aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc (renamed from Documentation/ABI/testing/sysfs-class-usb_host)4
-rw-r--r--Documentation/ABI/testing/sysfs-devices-cache_disable18
-rw-r--r--Documentation/ABI/testing/sysfs-devices-system-cpu156
-rw-r--r--Documentation/DocBook/tracepoint.tmpl5
-rw-r--r--Documentation/RCU/trace.txt254
-rw-r--r--Documentation/RCU/whatisRCU.txt2
-rw-r--r--Documentation/cputopology.txt47
-rw-r--r--Documentation/debugging-via-ohci1394.txt8
-rw-r--r--Documentation/dontdiff3
-rw-r--r--Documentation/fb/framebuffer.txt6
-rw-r--r--Documentation/feature-removal-schedule.txt53
-rw-r--r--Documentation/filesystems/caching/fscache.txt110
-rw-r--r--Documentation/filesystems/caching/netfs-api.txt21
-rw-r--r--Documentation/filesystems/ext4.txt8
-rw-r--r--Documentation/filesystems/ocfs2.txt6
-rw-r--r--Documentation/filesystems/proc.txt3
-rw-r--r--Documentation/flexible-arrays.txt43
-rw-r--r--Documentation/hwmon/sysfs-interface57
-rw-r--r--Documentation/i2c/busses/i2c-piix42
-rw-r--r--Documentation/kernel-parameters.txt39
-rw-r--r--Documentation/lguest/lguest.c1
-rw-r--r--Documentation/pcmcia/driver-changes.txt12
-rw-r--r--Documentation/slow-work.txt160
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt2
-rw-r--r--Documentation/thermal/sysfs-api.txt389
-rw-r--r--Documentation/trace/ftrace-design.txt13
-rw-r--r--Documentation/trace/ftrace.txt2
-rw-r--r--Documentation/trace/kprobetrace.txt149
-rw-r--r--Documentation/vm/hwpoison.txt136
-rw-r--r--Documentation/vm/page-types.c2
-rw-r--r--MAINTAINERS273
-rw-r--r--Makefile5
-rw-r--r--arch/Kconfig7
-rw-r--r--arch/alpha/boot/tools/objstrip.c2
-rw-r--r--arch/alpha/include/asm/fcntl.h2
-rw-r--r--arch/alpha/include/asm/thread_info.h31
-rw-r--r--arch/alpha/kernel/core_marvel.c2
-rw-r--r--arch/alpha/kernel/core_titan.c2
-rw-r--r--arch/alpha/kernel/irq.c2
-rw-r--r--arch/alpha/kernel/irq_alpha.c2
-rw-r--r--arch/alpha/kernel/irq_i8259.c2
-rw-r--r--arch/alpha/kernel/irq_pyxis.c2
-rw-r--r--arch/alpha/kernel/irq_srm.c2
-rw-r--r--arch/alpha/kernel/sys_alcor.c2
-rw-r--r--arch/alpha/kernel/sys_cabriolet.c2
-rw-r--r--arch/alpha/kernel/sys_dp264.c4
-rw-r--r--arch/alpha/kernel/sys_eb64p.c2
-rw-r--r--arch/alpha/kernel/sys_eiger.c2
-rw-r--r--arch/alpha/kernel/sys_jensen.c2
-rw-r--r--arch/alpha/kernel/sys_marvel.c6
-rw-r--r--arch/alpha/kernel/sys_mikasa.c2
-rw-r--r--arch/alpha/kernel/sys_noritake.c2
-rw-r--r--arch/alpha/kernel/sys_rawhide.c2
-rw-r--r--arch/alpha/kernel/sys_ruffian.c2
-rw-r--r--arch/alpha/kernel/sys_rx164.c2
-rw-r--r--arch/alpha/kernel/sys_sable.c2
-rw-r--r--arch/alpha/kernel/sys_takara.c2
-rw-r--r--arch/alpha/kernel/sys_titan.c2
-rw-r--r--arch/alpha/kernel/sys_wildfire.c2
-rw-r--r--arch/arm/configs/ams_delta_defconfig24
-rw-r--r--arch/arm/configs/kirkwood_defconfig260
-rw-r--r--arch/arm/configs/n8x0_defconfig2
-rw-r--r--arch/arm/configs/omap3_beagle_defconfig1
-rw-r--r--arch/arm/configs/omap3_pandora_defconfig49
-rw-r--r--arch/arm/configs/omap_3430sdp_defconfig9
-rw-r--r--arch/arm/configs/orion5x_defconfig278
-rw-r--r--arch/arm/configs/u300_defconfig94
-rw-r--r--arch/arm/include/asm/cacheflush.h5
-rw-r--r--arch/arm/include/asm/elf.h3
-rw-r--r--arch/arm/include/asm/kmap_types.h6
-rw-r--r--arch/arm/include/asm/tlbflush.h3
-rw-r--r--arch/arm/include/asm/unistd.h9
-rw-r--r--arch/arm/kernel/entry-armv.S35
-rw-r--r--arch/arm/kernel/entry-header.S15
-rw-r--r--arch/arm/kernel/head-common.S2
-rw-r--r--arch/arm/kernel/process.c9
-rw-r--r--arch/arm/kernel/signal.c45
-rw-r--r--arch/arm/kernel/signal.h4
-rw-r--r--arch/arm/kernel/smp_scu.c4
-rw-r--r--arch/arm/kernel/traps.c8
-rw-r--r--arch/arm/kernel/unwind.c9
-rw-r--r--arch/arm/mach-at91/Kconfig20
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c2
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c23
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h9
-rw-r--r--arch/arm/mach-ep93xx/core.c1
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c2
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h1
-rw-r--r--arch/arm/mach-ep93xx/micro9.c1
-rw-r--r--arch/arm/mach-integrator/include/mach/memory.h1
-rw-r--r--arch/arm/mach-kirkwood/addr-map.c2
-rw-r--r--arch/arm/mach-kirkwood/common.c10
-rw-r--r--arch/arm/mach-kirkwood/include/mach/bridge-regs.h3
-rw-r--r--arch/arm/mach-kirkwood/include/mach/io.h2
-rw-r--r--arch/arm/mach-kirkwood/include/mach/kirkwood.h1
-rw-r--r--arch/arm/mach-kirkwood/openrd_base-setup.c12
-rw-r--r--arch/arm/mach-kirkwood/pcie.c6
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-switch.h2
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa910.h2
-rw-r--r--arch/arm/mach-mv78xx0/common.c2
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/mv78xx0.h1
-rw-r--r--arch/arm/mach-mx2/clock_imx27.c8
-rw-r--r--arch/arm/mach-mx2/pcm038.c96
-rw-r--r--arch/arm/mach-mx2/pcm970-baseboard.c2
-rw-r--r--arch/arm/mach-mx25/devices.c19
-rw-r--r--arch/arm/mach-mx25/mx25pdk.c25
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c2
-rw-r--r--arch/arm/mach-mx3/clock.c2
-rw-r--r--arch/arm/mach-mx3/devices.c24
-rw-r--r--arch/arm/mach-mx3/devices.h6
-rw-r--r--arch/arm/mach-mx3/mm.c2
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c6
-rw-r--r--arch/arm/mach-omap1/board-generic.c8
-rw-r--r--arch/arm/mach-omap1/board-innovator.c20
-rw-r--r--arch/arm/mach-omap1/board-palmte.c8
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c8
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c8
-rw-r--r--arch/arm/mach-omap1/board-sx1.c8
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c8
-rw-r--r--arch/arm/mach-omap1/serial.c26
-rw-r--r--arch/arm/mach-omap2/Kconfig12
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c4
-rw-r--r--arch/arm/mach-omap2/board-ldp.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c80
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c4
-rw-r--r--arch/arm/mach-omap2/board-rx51.c1
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c93
-rw-r--r--arch/arm/mach-omap2/clock24xx.c1
-rw-r--r--arch/arm/mach-omap2/clock34xx.c2
-rw-r--r--arch/arm/mach-omap2/clock34xx.h4
-rw-r--r--arch/arm/mach-omap2/clockdomain.c74
-rw-r--r--arch/arm/mach-omap2/gpmc.c4
-rw-r--r--arch/arm/mach-omap2/io.c2
-rw-r--r--arch/arm/mach-omap2/mailbox.c2
-rw-r--r--arch/arm/mach-omap2/pm34xx.c7
-rw-r--r--arch/arm/mach-omap2/serial.c10
-rw-r--r--arch/arm/mach-pxa/cm-x300.c38
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c4
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa2xx.c1
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa3xx.c2
-rw-r--r--arch/arm/mach-pxa/hx4700.c2
-rw-r--r--arch/arm/mach-pxa/include/mach/entry-macro.S1
-rw-r--r--arch/arm/mach-pxa/irq.c11
-rw-r--r--arch/arm/mach-pxa/palmtc.c8
-rw-r--r--arch/arm/mach-pxa/spitz.c80
-rw-r--r--arch/arm/mach-realview/Kconfig5
-rw-r--r--arch/arm/mach-realview/core.c42
-rw-r--r--arch/arm/mach-realview/core.h6
-rw-r--r--arch/arm/mach-realview/include/mach/board-pb1176.h5
-rw-r--r--arch/arm/mach-realview/include/mach/board-pb11mp.h12
-rw-r--r--arch/arm/mach-realview/include/mach/memory.h49
-rw-r--r--arch/arm/mach-realview/include/mach/platform.h15
-rw-r--r--arch/arm/mach-realview/include/mach/system.h10
-rw-r--r--arch/arm/mach-realview/platsmp.c5
-rw-r--r--arch/arm/mach-realview/realview_eb.c1
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c24
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c17
-rw-r--r--arch/arm/mach-realview/realview_pba8.c1
-rw-r--r--arch/arm/mach-realview/realview_pbx.c21
-rw-r--r--arch/arm/mach-s3c2410/gpio.c1
-rw-r--r--arch/arm/mach-s3c2410/include/mach/dma.h7
-rw-r--r--arch/arm/mach-s3c2440/Kconfig1
-rw-r--r--arch/arm/mach-s3c2440/mach-mini2440.c4
-rw-r--r--arch/arm/mach-s3c6400/include/mach/dma.h7
-rw-r--r--arch/arm/mach-s3c6410/Kconfig1
-rw-r--r--arch/arm/mach-s3c6410/mach-smdk6410.c3
-rw-r--r--arch/arm/mach-u300/core.c2
-rw-r--r--arch/arm/mm/Kconfig5
-rw-r--r--arch/arm/mm/context.c5
-rw-r--r--arch/arm/mm/dma-mapping.c4
-rw-r--r--arch/arm/mm/flush.c31
-rw-r--r--arch/arm/mm/init.c20
-rw-r--r--arch/arm/mm/mmu.c7
-rw-r--r--arch/arm/mm/proc-v6.S7
-rw-r--r--arch/arm/mm/proc-v7.S14
-rw-r--r--arch/arm/oprofile/op_model_v6.c3
-rw-r--r--arch/arm/plat-omap/cpu-omap.c2
-rw-r--r--arch/arm/plat-omap/dma.c47
-rw-r--r--arch/arm/plat-omap/gpio.c2
-rw-r--r--arch/arm/plat-omap/include/mach/keypad.h5
-rw-r--r--arch/arm/plat-omap/iommu.c2
-rw-r--r--arch/arm/plat-omap/mcbsp.c2
-rw-r--r--arch/arm/plat-pxa/include/plat/mfp.h2
-rw-r--r--arch/arm/plat-pxa/mfp.c4
-rw-r--r--arch/arm/plat-s3c24xx/adc.c2
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c10
-rw-r--r--arch/arm/plat-s3c24xx/dma.c6
-rw-r--r--arch/arm/plat-s3c24xx/gpio.c1
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h9
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2410.h1
-rw-r--r--arch/arm/plat-s3c64xx/dma.c76
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/regs-clock.h4
-rw-r--r--arch/arm/plat-s3c64xx/s3c6400-clock.c3
-rw-r--r--arch/arm/tools/mach-types119
-rw-r--r--arch/avr32/include/asm/bug.h2
-rw-r--r--arch/avr32/mach-at32ap/include/mach/cpu.h3
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c9
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbinit.c2
-rw-r--r--arch/blackfin/kernel/process.c2
-rw-r--r--arch/blackfin/kernel/ptrace.c2
-rw-r--r--arch/blackfin/mach-bf518/include/mach/anomaly.h18
-rw-r--r--arch/blackfin/mach-bf527/include/mach/anomaly.h20
-rw-r--r--arch/blackfin/mach-bf533/include/mach/anomaly.h18
-rw-r--r--arch/blackfin/mach-bf537/include/mach/anomaly.h18
-rw-r--r--arch/blackfin/mach-bf538/include/mach/anomaly.h18
-rw-r--r--arch/blackfin/mach-bf548/include/mach/anomaly.h23
-rw-r--r--arch/blackfin/mach-bf561/atomic.S14
-rw-r--r--arch/blackfin/mach-bf561/include/mach/anomaly.h25
-rw-r--r--arch/blackfin/mach-common/arch_checks.c5
-rw-r--r--arch/blackfin/mach-common/smp.c6
-rw-r--r--arch/frv/kernel/signal.c2
-rw-r--r--arch/ia64/include/asm/spinlock.h62
-rw-r--r--arch/ia64/include/asm/spinlock_types.h2
-rw-r--r--arch/ia64/include/asm/swiotlb.h2
-rw-r--r--arch/ia64/kernel/mca.c104
-rw-r--r--arch/ia64/kernel/pci-swiotlb.c4
-rw-r--r--arch/ia64/kernel/unaligned.c6
-rw-r--r--arch/ia64/mm/tlb.c24
-rw-r--r--arch/ia64/pci/pci.c9
-rw-r--r--arch/ia64/sn/kernel/io_common.c8
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c7
-rw-r--r--arch/m32r/Kconfig3
-rw-r--r--arch/m32r/boot/compressed/Makefile18
-rw-r--r--arch/m32r/boot/compressed/misc.c143
-rw-r--r--arch/m32r/kernel/smp.c2
-rw-r--r--arch/m32r/kernel/time.c6
-rw-r--r--arch/m32r/kernel/vmlinux.lds.S2
-rw-r--r--arch/m68k/Kconfig6
-rw-r--r--arch/mips/Kconfig26
-rw-r--r--arch/mips/alchemy/common/irq.c34
-rw-r--r--arch/mips/alchemy/mtx-1/board_setup.c3
-rw-r--r--arch/mips/ar7/platform.c9
-rw-r--r--arch/mips/bcm47xx/prom.c2
-rw-r--r--arch/mips/bcm63xx/Makefile2
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c3
-rw-r--r--arch/mips/bcm63xx/cpu.c3
-rw-r--r--arch/mips/bcm63xx/dev-uart.c2
-rw-r--r--arch/mips/bcm63xx/dev-wdt.c37
-rw-r--r--arch/mips/bcm63xx/setup.c4
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c224
-rw-r--r--arch/mips/cavium-octeon/smp.c5
-rw-r--r--arch/mips/configs/rbtx49xx_defconfig252
-rw-r--r--arch/mips/include/asm/bug.h4
-rw-r--r--arch/mips/include/asm/dma-mapping.h11
-rw-r--r--arch/mips/include/asm/fixmap.h4
-rw-r--r--arch/mips/include/asm/gcmpregs.h18
-rw-r--r--arch/mips/include/asm/gic.h188
-rw-r--r--arch/mips/include/asm/mach-ar7/ar7.h3
-rw-r--r--arch/mips/include/asm/mach-au1x00/gpio-au1000.h2
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h6
-rw-r--r--arch/mips/include/asm/mach-ip27/topology.h4
-rw-r--r--arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h3
-rw-r--r--arch/mips/include/asm/mman.h1
-rw-r--r--arch/mips/include/asm/mmu_context.h13
-rw-r--r--arch/mips/include/asm/setup.h2
-rw-r--r--arch/mips/include/asm/smtc_ipi.h1
-rw-r--r--arch/mips/include/asm/spram.h10
-rw-r--r--arch/mips/include/asm/system.h15
-rw-r--r--arch/mips/include/asm/thread_info.h9
-rw-r--r--arch/mips/jazz/irq.c2
-rw-r--r--arch/mips/kernel/cevt-bcm1480.c2
-rw-r--r--arch/mips/kernel/cevt-ds1287.c2
-rw-r--r--arch/mips/kernel/cevt-gt641xx.c2
-rw-r--r--arch/mips/kernel/cevt-r4k.c2
-rw-r--r--arch/mips/kernel/cevt-sb1250.c2
-rw-r--r--arch/mips/kernel/cevt-smtc.c3
-rw-r--r--arch/mips/kernel/cevt-txx9.c2
-rw-r--r--arch/mips/kernel/cpu-probe.c8
-rw-r--r--arch/mips/kernel/head.S1
-rw-r--r--arch/mips/kernel/i8253.c2
-rw-r--r--arch/mips/kernel/irq-gic.c114
-rw-r--r--arch/mips/kernel/linux32.c6
-rw-r--r--arch/mips/kernel/scall64-o32.S4
-rw-r--r--arch/mips/kernel/smtc.c34
-rw-r--r--arch/mips/kernel/spram.c5
-rw-r--r--arch/mips/kernel/syscall.c4
-rw-r--r--arch/mips/kernel/vpe.c2
-rw-r--r--arch/mips/loongson/common/irq.c1
-rw-r--r--arch/mips/math-emu/cp1emu.c41
-rw-r--r--arch/mips/math-emu/dp_simple.c13
-rw-r--r--arch/mips/math-emu/sp_simple.c11
-rw-r--r--arch/mips/mm/dma-default.c7
-rw-r--r--arch/mips/mm/init.c6
-rw-r--r--arch/mips/mti-malta/malta-amon.c7
-rw-r--r--arch/mips/mti-malta/malta-int.c119
-rw-r--r--arch/mips/mti-malta/malta-memory.c3
-rw-r--r--arch/mips/mti-malta/malta-pci.c27
-rw-r--r--arch/mips/nxp/pnx8550/common/int.c2
-rw-r--r--arch/mips/nxp/pnx8550/common/time.c4
-rw-r--r--arch/mips/oprofile/op_model_loongson2.c2
-rw-r--r--arch/mips/rb532/devices.c3
-rw-r--r--arch/mips/rb532/prom.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c2
-rw-r--r--arch/mips/sni/time.c2
-rw-r--r--arch/mips/txx9/generic/setup.c9
-rw-r--r--arch/parisc/include/asm/fcntl.h2
-rw-r--r--arch/parisc/kernel/unwind.c2
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S6
-rw-r--r--arch/powerpc/Kconfig4
-rw-r--r--arch/powerpc/Kconfig.debug2
-rw-r--r--arch/powerpc/boot/addRamDisk.c6
-rw-r--r--arch/powerpc/boot/dts/cm5200.dts1
-rw-r--r--arch/powerpc/boot/dts/digsy_mtc.dts1
-rw-r--r--arch/powerpc/boot/dts/lite5200.dts2
-rw-r--r--arch/powerpc/boot/dts/lite5200b.dts2
-rw-r--r--arch/powerpc/boot/dts/media5200.dts2
-rw-r--r--arch/powerpc/boot/dts/motionpro.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc5121ads.dts3
-rw-r--r--arch/powerpc/boot/dts/mpc8377_wlan.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8569mds.dts4
-rw-r--r--arch/powerpc/boot/dts/mucmc52.dts332
-rw-r--r--arch/powerpc/boot/dts/pcm030.dts2
-rw-r--r--arch/powerpc/boot/dts/pcm032.dts2
-rw-r--r--arch/powerpc/boot/dts/sbc8548.dts17
-rw-r--r--arch/powerpc/boot/dts/tqm5200.dts1
-rw-r--r--arch/powerpc/boot/dts/uc101.dts284
-rw-r--r--arch/powerpc/configs/52xx/cm5200_defconfig136
-rw-r--r--arch/powerpc/configs/52xx/lite5200b_defconfig153
-rw-r--r--arch/powerpc/configs/52xx/motionpro_defconfig146
-rw-r--r--arch/powerpc/configs/52xx/pcm030_defconfig142
-rw-r--r--arch/powerpc/configs/52xx/tqm5200_defconfig148
-rw-r--r--arch/powerpc/configs/83xx/asp8347_defconfig60
-rw-r--r--arch/powerpc/configs/83xx/kmeter1_defconfig46
-rw-r--r--arch/powerpc/configs/83xx/mpc8313_rdb_defconfig73
-rw-r--r--arch/powerpc/configs/83xx/mpc8315_rdb_defconfig76
-rw-r--r--arch/powerpc/configs/83xx/mpc832x_mds_defconfig62
-rw-r--r--arch/powerpc/configs/83xx/mpc832x_rdb_defconfig66
-rw-r--r--arch/powerpc/configs/83xx/mpc834x_itx_defconfig60
-rw-r--r--arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig58
-rw-r--r--arch/powerpc/configs/83xx/mpc834x_mds_defconfig58
-rw-r--r--arch/powerpc/configs/83xx/mpc836x_mds_defconfig64
-rw-r--r--arch/powerpc/configs/83xx/mpc836x_rdk_defconfig60
-rw-r--r--arch/powerpc/configs/83xx/mpc837x_mds_defconfig64
-rw-r--r--arch/powerpc/configs/83xx/mpc837x_rdb_defconfig70
-rw-r--r--arch/powerpc/configs/83xx/sbc834x_defconfig61
-rw-r--r--arch/powerpc/configs/85xx/ksi8560_defconfig61
-rw-r--r--arch/powerpc/configs/85xx/mpc8540_ads_defconfig57
-rw-r--r--arch/powerpc/configs/85xx/mpc8560_ads_defconfig63
-rw-r--r--arch/powerpc/configs/85xx/mpc85xx_cds_defconfig58
-rw-r--r--arch/powerpc/configs/85xx/sbc8548_defconfig53
-rw-r--r--arch/powerpc/configs/85xx/sbc8560_defconfig57
-rw-r--r--arch/powerpc/configs/85xx/socrates_defconfig68
-rw-r--r--arch/powerpc/configs/85xx/stx_gp3_defconfig77
-rw-r--r--arch/powerpc/configs/85xx/tqm8540_defconfig59
-rw-r--r--arch/powerpc/configs/85xx/tqm8541_defconfig64
-rw-r--r--arch/powerpc/configs/85xx/tqm8548_defconfig64
-rw-r--r--arch/powerpc/configs/85xx/tqm8555_defconfig64
-rw-r--r--arch/powerpc/configs/85xx/tqm8560_defconfig64
-rw-r--r--arch/powerpc/configs/85xx/xes_mpc85xx_defconfig76
-rw-r--r--arch/powerpc/configs/86xx/gef_ppc9a_defconfig74
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc310_defconfig72
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc610_defconfig80
-rw-r--r--arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig64
-rw-r--r--arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig65
-rw-r--r--arch/powerpc/configs/86xx/sbc8641d_defconfig66
-rw-r--r--arch/powerpc/configs/adder875_defconfig48
-rw-r--r--arch/powerpc/configs/c2k_defconfig77
-rw-r--r--arch/powerpc/configs/ep8248e_defconfig49
-rw-r--r--arch/powerpc/configs/ep88xc_defconfig47
-rw-r--r--arch/powerpc/configs/linkstation_defconfig72
-rw-r--r--arch/powerpc/configs/mgcoge_defconfig51
-rw-r--r--arch/powerpc/configs/mgsuvd_defconfig45
-rw-r--r--arch/powerpc/configs/mpc5200_defconfig192
-rw-r--r--arch/powerpc/configs/mpc7448_hpc2_defconfig58
-rw-r--r--arch/powerpc/configs/mpc8272_ads_defconfig52
-rw-r--r--arch/powerpc/configs/mpc83xx_defconfig90
-rw-r--r--arch/powerpc/configs/mpc85xx_defconfig98
-rw-r--r--arch/powerpc/configs/mpc85xx_smp_defconfig99
-rw-r--r--arch/powerpc/configs/mpc866_ads_defconfig54
-rw-r--r--arch/powerpc/configs/mpc86xx_defconfig70
-rw-r--r--arch/powerpc/configs/mpc885_ads_defconfig47
-rw-r--r--arch/powerpc/configs/pasemi_defconfig628
-rw-r--r--arch/powerpc/configs/ppc64e_defconfig2199
-rw-r--r--arch/powerpc/configs/pq2fads_defconfig55
-rw-r--r--arch/powerpc/configs/prpmc2800_defconfig67
-rw-r--r--arch/powerpc/configs/pseries_defconfig2
-rw-r--r--arch/powerpc/configs/storcenter_defconfig54
-rw-r--r--arch/powerpc/include/asm/emulated_ops.h19
-rw-r--r--arch/powerpc/include/asm/firmware.h10
-rw-r--r--arch/powerpc/include/asm/hvcall.h2
-rw-r--r--arch/powerpc/include/asm/kmap_types.h11
-rw-r--r--arch/powerpc/include/asm/reg.h2
-rw-r--r--arch/powerpc/include/asm/trace.h133
-rw-r--r--arch/powerpc/kernel/align.c12
-rw-r--r--arch/powerpc/kernel/cputable.c2
-rw-r--r--arch/powerpc/kernel/entry_64.S48
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S3
-rw-r--r--arch/powerpc/kernel/irq.c6
-rw-r--r--arch/powerpc/kernel/kgdb.c6
-rw-r--r--arch/powerpc/kernel/pci-common.c2
-rw-r--r--arch/powerpc/kernel/pci_64.c2
-rw-r--r--arch/powerpc/kernel/perf_event.c19
-rw-r--r--arch/powerpc/kernel/power5+-pmu.c4
-rw-r--r--arch/powerpc/kernel/power5-pmu.c6
-rw-r--r--arch/powerpc/kernel/power6-pmu.c2
-rw-r--r--arch/powerpc/kernel/power7-pmu.c6
-rw-r--r--arch/powerpc/kernel/ppc970-pmu.c4
-rw-r--r--arch/powerpc/kernel/process.c12
-rw-r--r--arch/powerpc/kernel/setup-common.c1
-rw-r--r--arch/powerpc/kernel/setup_32.c2
-rw-r--r--arch/powerpc/kernel/setup_64.c3
-rw-r--r--arch/powerpc/kernel/time.c21
-rw-r--r--arch/powerpc/kernel/traps.c18
-rw-r--r--arch/powerpc/kernel/vdso.c11
-rw-r--r--arch/powerpc/kernel/vdso32/vdso32.lds.S4
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S1
-rw-r--r--arch/powerpc/kvm/timing.h4
-rw-r--r--arch/powerpc/lib/copypage_64.S4
-rw-r--r--arch/powerpc/mm/mmu_context_nohash.c4
-rw-r--r--arch/powerpc/mm/slb_low.S10
-rw-r--r--arch/powerpc/platforms/52xx/mpc5200_simple.c2
-rw-r--r--arch/powerpc/platforms/82xx/ep8248e.c15
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c2
-rw-r--r--arch/powerpc/platforms/iseries/Makefile11
-rw-r--r--arch/powerpc/platforms/iseries/dt.c56
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c7
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c3
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S132
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c38
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c33
-rw-r--r--arch/powerpc/platforms/pseries/msi.c2
-rw-r--r--arch/powerpc/platforms/pseries/xics.c9
-rw-r--r--arch/powerpc/xmon/xmon.c20
-rw-r--r--arch/s390/Kconfig28
-rw-r--r--arch/s390/hypfs/hypfs_diag.c2
-rw-r--r--arch/s390/include/asm/bug.h2
-rw-r--r--arch/s390/include/asm/cputime.h6
-rw-r--r--arch/s390/include/asm/spinlock.h29
-rw-r--r--arch/s390/kernel/early.c9
-rw-r--r--arch/s390/kernel/entry.S8
-rw-r--r--arch/s390/kernel/entry64.S8
-rw-r--r--arch/s390/kernel/ftrace.c67
-rw-r--r--arch/s390/kernel/ipl.c7
-rw-r--r--arch/s390/kernel/processor.c6
-rw-r--r--arch/s390/kernel/smp.c7
-rw-r--r--arch/s390/kernel/swsusp_asm64.S2
-rw-r--r--arch/sh/Kconfig6
-rw-r--r--arch/sh/Makefile3
-rw-r--r--arch/sh/boards/mach-landisk/gio.c10
-rw-r--r--arch/sh/boards/mach-rsk/devices-rsk7203.c4
-rw-r--r--arch/sh/boards/mach-rsk/setup.c23
-rw-r--r--arch/sh/boot/Makefile6
-rw-r--r--arch/sh/include/asm/rwsem.h2
-rw-r--r--arch/sh/kernel/cpu/irq/imask.c2
-rw-r--r--arch/sh/kernel/cpu/irq/intc-sh5.c2
-rw-r--r--arch/sh/kernel/dwarf.c24
-rw-r--r--arch/sh/kernel/entry-common.S2
-rw-r--r--arch/sh/kernel/ftrace.c37
-rw-r--r--arch/sh/kernel/irq.c3
-rw-r--r--arch/sh/kernel/setup.c2
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c14
-rw-r--r--arch/sh/kernel/signal_32.c9
-rw-r--r--arch/sh/kernel/smp.c2
-rw-r--r--arch/sh/kernel/traps_32.c7
-rw-r--r--arch/sh/mm/Kconfig2
-rw-r--r--arch/sh/mm/cache-sh4.c27
-rw-r--r--arch/sh/mm/cache.c12
-rw-r--r--arch/sparc/boot/btfixupprep.c8
-rw-r--r--arch/sparc/boot/piggyback_32.c10
-rw-r--r--arch/sparc/boot/piggyback_64.c2
-rw-r--r--arch/sparc/include/asm/system_64.h4
-rw-r--r--arch/sparc/kernel/ldc.c4
-rw-r--r--arch/sparc/kernel/perf_event.c2
-rw-r--r--arch/sparc/kernel/prom_common.c4
-rw-r--r--arch/sparc/kernel/visemul.c2
-rw-r--r--arch/sparc/mm/init_64.c2
-rw-r--r--arch/sparc/mm/init_64.h2
-rw-r--r--arch/x86/Kconfig16
-rw-r--r--arch/x86/Kconfig.cpu4
-rw-r--r--arch/x86/Kconfig.debug23
-rw-r--r--arch/x86/Makefile4
-rw-r--r--arch/x86/Makefile_32.cpu2
-rw-r--r--arch/x86/boot/setup.ld3
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c10
-rw-r--r--arch/x86/ia32/ia32entry.S5
-rw-r--r--arch/x86/include/asm/Kbuild1
-rw-r--r--arch/x86/include/asm/a.out-core.h10
-rw-r--r--arch/x86/include/asm/alternative-asm.h10
-rw-r--r--arch/x86/include/asm/alternative.h1
-rw-r--r--arch/x86/include/asm/amd_iommu.h15
-rw-r--r--arch/x86/include/asm/amd_iommu_proto.h38
-rw-r--r--arch/x86/include/asm/amd_iommu_types.h54
-rw-r--r--arch/x86/include/asm/apic.h21
-rw-r--r--arch/x86/include/asm/apicdef.h6
-rw-r--r--arch/x86/include/asm/apicnum.h12
-rw-r--r--arch/x86/include/asm/bug.h4
-rw-r--r--arch/x86/include/asm/calgary.h2
-rw-r--r--arch/x86/include/asm/cmpxchg_32.h218
-rw-r--r--arch/x86/include/asm/cmpxchg_64.h234
-rw-r--r--arch/x86/include/asm/debugreg.h33
-rw-r--r--arch/x86/include/asm/desc.h2
-rw-r--r--arch/x86/include/asm/device.h2
-rw-r--r--arch/x86/include/asm/dma-mapping.h15
-rw-r--r--arch/x86/include/asm/gart.h9
-rw-r--r--arch/x86/include/asm/hardirq.h6
-rw-r--r--arch/x86/include/asm/hw_breakpoint.h73
-rw-r--r--arch/x86/include/asm/hw_irq.h30
-rw-r--r--arch/x86/include/asm/inat.h220
-rw-r--r--arch/x86/include/asm/inat_types.h29
-rw-r--r--arch/x86/include/asm/insn.h184
-rw-r--r--arch/x86/include/asm/iommu.h2
-rw-r--r--arch/x86/include/asm/irq.h1
-rw-r--r--arch/x86/include/asm/mce.h14
-rw-r--r--arch/x86/include/asm/mpspec.h16
-rw-r--r--arch/x86/include/asm/msr.h8
-rw-r--r--arch/x86/include/asm/paravirt.h28
-rw-r--r--arch/x86/include/asm/paravirt_types.h10
-rw-r--r--arch/x86/include/asm/perf_event.h13
-rw-r--r--arch/x86/include/asm/processor.h16
-rw-r--r--arch/x86/include/asm/ptrace.h62
-rw-r--r--arch/x86/include/asm/string_32.h9
-rw-r--r--arch/x86/include/asm/swiotlb.h9
-rw-r--r--arch/x86/include/asm/system.h31
-rw-r--r--arch/x86/include/asm/topology.h1
-rw-r--r--arch/x86/include/asm/uaccess.h1
-rw-r--r--arch/x86/include/asm/uaccess_32.h27
-rw-r--r--arch/x86/include/asm/uaccess_64.h36
-rw-r--r--arch/x86/include/asm/uv/uv_hub.h23
-rw-r--r--arch/x86/include/asm/uv/uv_irq.h14
-rw-r--r--arch/x86/include/asm/x86_init.h10
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/acpi/processor.c3
-rw-r--r--arch/x86/kernel/acpi/realmode/wakeup.lds.S3
-rw-r--r--arch/x86/kernel/amd_iommu.c1245
-rw-r--r--arch/x86/kernel/amd_iommu_init.c118
-rw-r--r--arch/x86/kernel/aperture_64.c4
-rw-r--r--arch/x86/kernel/apic/Makefile2
-rw-r--r--arch/x86/kernel/apic/apic.c34
-rw-r--r--arch/x86/kernel/apic/apic_noop.c200
-rw-r--r--arch/x86/kernel/apic/bigsmp_32.c13
-rw-r--r--arch/x86/kernel/apic/es7000_32.c16
-rw-r--r--arch/x86/kernel/apic/io_apic.c364
-rw-r--r--arch/x86/kernel/apic/nmi.c11
-rw-r--r--arch/x86/kernel/apic/numaq_32.c13
-rw-r--r--arch/x86/kernel/apic/probe_32.c2
-rw-r--r--arch/x86/kernel/apic/summit_32.c10
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c16
-rw-r--r--arch/x86/kernel/apm_32.c14
-rw-r--r--arch/x86/kernel/cpu/Makefile1
-rw-r--r--arch/x86/kernel/cpu/amd.c2
-rw-r--r--arch/x86/kernel/cpu/centaur.c2
-rw-r--r--arch/x86/kernel/cpu/common.c34
-rw-r--r--arch/x86/kernel/cpu/cpu.h2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c23
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longhaul.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-ich.c19
-rw-r--r--arch/x86/kernel/cpu/cyrix.c2
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c16
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c106
-rw-r--r--arch/x86/kernel/cpu/mcheck/therm_throt.c29
-rw-r--r--arch/x86/kernel/cpu/mtrr/cleanup.c2
-rw-r--r--arch/x86/kernel/cpu/perf_event.c205
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c2
-rw-r--r--arch/x86/kernel/cpu/transmeta.c2
-rw-r--r--arch/x86/kernel/cpuid.c17
-rw-r--r--arch/x86/kernel/crash.c5
-rw-r--r--arch/x86/kernel/crash_dump_32.c19
-rw-r--r--arch/x86/kernel/dumpstack.c7
-rw-r--r--arch/x86/kernel/dumpstack_32.c9
-rw-r--r--arch/x86/kernel/dumpstack_64.c46
-rw-r--r--arch/x86/kernel/efi.c2
-rw-r--r--arch/x86/kernel/entry_32.S31
-rw-r--r--arch/x86/kernel/entry_64.S25
-rw-r--r--arch/x86/kernel/ftrace.c84
-rw-r--r--arch/x86/kernel/head_64.S4
-rw-r--r--arch/x86/kernel/hw_breakpoint.c555
-rw-r--r--arch/x86/kernel/irq.c108
-rw-r--r--arch/x86/kernel/irq_32.c45
-rw-r--r--arch/x86/kernel/irq_64.c58
-rw-r--r--arch/x86/kernel/kgdb.c9
-rw-r--r--arch/x86/kernel/kprobes.c257
-rw-r--r--arch/x86/kernel/machine_kexec_32.c2
-rw-r--r--arch/x86/kernel/machine_kexec_64.c2
-rw-r--r--arch/x86/kernel/microcode_amd.c6
-rw-r--r--arch/x86/kernel/microcode_core.c2
-rw-r--r--arch/x86/kernel/msr.c16
-rw-r--r--arch/x86/kernel/pci-calgary_64.c94
-rw-r--r--arch/x86/kernel/pci-dma.c45
-rw-r--r--arch/x86/kernel/pci-gart_64.c156
-rw-r--r--arch/x86/kernel/pci-nommu.c11
-rw-r--r--arch/x86/kernel/pci-swiotlb.c18
-rw-r--r--arch/x86/kernel/process.c21
-rw-r--r--arch/x86/kernel/process_32.c10
-rw-r--r--arch/x86/kernel/process_64.c15
-rw-r--r--arch/x86/kernel/ptrace.c415
-rw-r--r--arch/x86/kernel/reboot.c12
-rw-r--r--arch/x86/kernel/setup.c14
-rw-r--r--arch/x86/kernel/signal.c9
-rw-r--r--arch/x86/kernel/smp.c1
-rw-r--r--arch/x86/kernel/smpboot.c9
-rw-r--r--arch/x86/kernel/time.c3
-rw-r--r--arch/x86/kernel/tlb_uv.c9
-rw-r--r--arch/x86/kernel/trampoline.c12
-rw-r--r--arch/x86/kernel/trampoline_64.S4
-rw-r--r--arch/x86/kernel/traps.c73
-rw-r--r--arch/x86/kernel/tsc_sync.c13
-rw-r--r--arch/x86/kernel/uv_irq.c239
-rw-r--r--arch/x86/kernel/visws_quirks.c8
-rw-r--r--arch/x86/kernel/vmi_32.c2
-rw-r--r--arch/x86/kernel/vmlinux.lds.S3
-rw-r--r--arch/x86/kernel/x8664_ksyms_64.c5
-rw-r--r--arch/x86/kernel/x86_init.c8
-rw-r--r--arch/x86/kvm/i8254.c2
-rw-r--r--arch/x86/kvm/lapic.c2
-rw-r--r--arch/x86/kvm/mmu.c16
-rw-r--r--arch/x86/kvm/x86.c22
-rw-r--r--arch/x86/lib/.gitignore1
-rw-r--r--arch/x86/lib/Makefile13
-rw-r--r--arch/x86/lib/copy_user_64.S14
-rw-r--r--arch/x86/lib/inat.c90
-rw-r--r--arch/x86/lib/insn.c516
-rw-r--r--arch/x86/lib/msr.c46
-rw-r--r--arch/x86/lib/usercopy_32.c10
-rw-r--r--arch/x86/lib/x86-opcode-map.txt893
-rw-r--r--arch/x86/mm/extable.c31
-rw-r--r--arch/x86/mm/fault.c13
-rw-r--r--arch/x86/mm/ioremap.c24
-rw-r--r--arch/x86/mm/kmmio.c8
-rw-r--r--arch/x86/mm/srat_64.c4
-rw-r--r--arch/x86/mm/testmmiotrace.c29
-rw-r--r--arch/x86/power/cpu.c26
-rw-r--r--arch/x86/tools/Makefile31
-rw-r--r--arch/x86/tools/chkobjdump.awk23
-rw-r--r--arch/x86/tools/distill.awk47
-rw-r--r--arch/x86/tools/gen-insn-attr-x86.awk380
-rw-r--r--arch/x86/tools/test_get_len.c173
-rw-r--r--arch/x86/xen/enlighten.c14
-rw-r--r--block/blk-core.c2
-rw-r--r--block/cfq-iosched.c19
-rw-r--r--crypto/async_tx/Kconfig5
-rw-r--r--crypto/async_tx/async_pq.c74
-rw-r--r--crypto/async_tx/async_raid6_recov.c100
-rw-r--r--crypto/async_tx/async_xor.c33
-rw-r--r--crypto/gcm.c107
-rw-r--r--drivers/acpi/Kconfig4
-rw-r--r--drivers/acpi/ac.c1
-rw-r--r--drivers/acpi/acpica/acconfig.h4
-rw-r--r--drivers/acpi/acpica/acpredef.h5
-rw-r--r--drivers/acpi/acpica/exregion.c35
-rw-r--r--drivers/acpi/blacklist.c17
-rw-r--r--drivers/acpi/button.c3
-rw-r--r--drivers/acpi/pci_root.c11
-rw-r--r--drivers/acpi/power_meter.c6
-rw-r--r--drivers/acpi/proc.c2
-rw-r--r--drivers/acpi/processor_core.c2
-rw-r--r--drivers/acpi/processor_throttling.c6
-rw-r--r--drivers/acpi/sleep.c32
-rw-r--r--drivers/acpi/video.c15
-rw-r--r--drivers/acpi/video_detect.c2
-rw-r--r--drivers/ata/ahci.c43
-rw-r--r--drivers/ata/libata-core.c21
-rw-r--r--drivers/ata/libata-eh.c6
-rw-r--r--drivers/ata/pata_atiixp.c2
-rw-r--r--drivers/ata/pata_pcmcia.c17
-rw-r--r--drivers/ata/pata_sc1200.c3
-rw-r--r--drivers/ata/pata_via.c2
-rw-r--r--drivers/ata/sata_fsl.c84
-rw-r--r--drivers/ata/sata_mv.c29
-rw-r--r--drivers/ata/sata_nv.c18
-rw-r--r--drivers/ata/sata_via.c1
-rw-r--r--drivers/base/bus.c17
-rw-r--r--drivers/base/driver.c2
-rw-r--r--drivers/base/platform.c6
-rw-r--r--drivers/base/power/main.c1
-rw-r--r--drivers/base/power/runtime.c16
-rw-r--r--drivers/block/aoe/aoecmd.c23
-rw-r--r--drivers/block/cciss.c16
-rw-r--r--drivers/block/loop.c2
-rw-r--r--drivers/block/virtio_blk.c39
-rw-r--r--drivers/bluetooth/bluecard_cs.c16
-rw-r--r--drivers/bluetooth/bt3c_cs.c13
-rw-r--r--drivers/bluetooth/btuart_cs.c13
-rw-r--r--drivers/bluetooth/btusb.c5
-rw-r--r--drivers/bluetooth/dtl1_cs.c12
-rw-r--r--drivers/char/Kconfig6
-rw-r--r--drivers/char/agp/Kconfig3
-rw-r--r--drivers/char/agp/intel-agp.c19
-rw-r--r--drivers/char/hvc_xen.c25
-rw-r--r--drivers/char/hw_random/virtio-rng.c3
-rw-r--r--drivers/char/keyboard.c2
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c73
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c52
-rw-r--r--drivers/char/pcmcia/ipwireless/hardware.c8
-rw-r--r--drivers/char/pcmcia/ipwireless/main.c296
-rw-r--r--drivers/char/pcmcia/synclink_cs.c80
-rw-r--r--drivers/char/tpm/tpm.c2
-rw-r--r--drivers/char/tpm/tpm_tis.c11
-rw-r--r--drivers/char/tty_buffer.c31
-rw-r--r--drivers/char/tty_port.c10
-rw-r--r--drivers/char/virtio_console.c1
-rw-r--r--drivers/char/vt_ioctl.c8
-rw-r--r--drivers/cpufreq/cpufreq.c48
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c4
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c4
-rw-r--r--drivers/cpuidle/cpuidle.c5
-rw-r--r--drivers/crypto/padlock-aes.c4
-rw-r--r--drivers/crypto/padlock-sha.c14
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/dmaengine.c10
-rw-r--r--drivers/dma/ioat/dca.c6
-rw-r--r--drivers/dma/ioat/dma.h4
-rw-r--r--drivers/dma/ioat/dma_v2.c2
-rw-r--r--drivers/dma/ioat/dma_v3.c44
-rw-r--r--drivers/dma/ioat/hw.h2
-rw-r--r--drivers/dma/ioat/registers.h4
-rw-r--r--drivers/dma/shdma.c12
-rw-r--r--drivers/edac/amd64_edac.c14
-rw-r--r--drivers/edac/edac_mce_amd.c21
-rw-r--r--drivers/edac/i5000_edac.c7
-rw-r--r--drivers/edac/i5400_edac.c89
-rw-r--r--drivers/edac/mpc85xx_edac.c2
-rw-r--r--drivers/firewire/ohci.c41
-rw-r--r--drivers/firewire/sbp2.c39
-rw-r--r--drivers/gpio/gpiolib.c8
-rw-r--r--drivers/gpio/langwell_gpio.c11
-rw-r--r--drivers/gpio/twl4030-gpio.c5
-rw-r--r--drivers/gpu/drm/Kconfig1
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c1
-rw-r--r--drivers/gpu/drm/drm_edid.c21
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c50
-rw-r--r--drivers/gpu/drm/drm_gem.c2
-rw-r--r--drivers/gpu/drm/drm_mm.c9
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c4
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c5
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h53
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c10
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h30
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c341
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c14
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c4
-rw-r--r--drivers/gpu/drm/i915/intel_display.c193
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c2
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c26
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c35
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/atom.c1
-rw-r--r--drivers/gpu/drm/radeon/atombios.h2
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c357
-rw-r--r--drivers/gpu/drm/radeon/mkregtable.c12
-rw-r--r--drivers/gpu/drm/radeon/r100.c42
-rw-r--r--drivers/gpu/drm/radeon/r300.c2
-rw-r--r--drivers/gpu/drm/radeon/r420.c2
-rw-r--r--drivers/gpu/drm/radeon/r500_reg.h9
-rw-r--r--drivers/gpu/drm/radeon/r520.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c108
-rw-r--r--drivers/gpu/drm/radeon/r600_blit.c58
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c5
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c18
-rw-r--r--drivers/gpu/drm/radeon/r600d.h14
-rw-r--r--drivers/gpu/drm/radeon/radeon.h12
-rw-r--r--drivers/gpu/drm/radeon/radeon_agp.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h23
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c282
-rw-r--r--drivers/gpu/drm/radeon/radeon_benchmark.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_clocks.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c287
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c211
-rw-r--r--drivers/gpu/drm/radeon/radeon_cursor.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c38
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c28
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c125
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c20
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c40
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c27
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h34
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c65
-rw-r--r--drivers/gpu/drm/radeon/radeon_reg.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_test.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c6
-rw-r--r--drivers/gpu/drm/radeon/rs400.c2
-rw-r--r--drivers/gpu/drm/radeon/rs600.c20
-rw-r--r--drivers/gpu/drm/radeon/rs690.c2
-rw-r--r--drivers/gpu/drm/radeon/rv515.c9
-rw-r--r--drivers/gpu/drm/radeon/rv770.c59
-rw-r--r--drivers/gpu/drm/radeon/rv770d.h5
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c1
-rw-r--r--drivers/hid/hid-core.c8
-rw-r--r--drivers/hid/hid-ids.h3
-rw-r--r--drivers/hid/hid-lg.c13
-rw-r--r--drivers/hid/usbhid/hid-core.c12
-rw-r--r--drivers/hid/usbhid/hid-quirks.c3
-rw-r--r--drivers/hid/usbhid/hiddev.c5
-rw-r--r--drivers/hwmon/adt7475.c17
-rw-r--r--drivers/hwmon/dme1737.c29
-rw-r--r--drivers/hwmon/fschmd.c2
-rw-r--r--drivers/hwmon/hp_accel.c5
-rw-r--r--drivers/hwmon/it87.c5
-rw-r--r--drivers/hwmon/s3c-hwmon.c11
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-imx.c86
-rw-r--r--drivers/i2c/busses/i2c-mpc.c10
-rw-r--r--drivers/i2c/busses/i2c-piix4.c8
-rw-r--r--drivers/i2c/busses/i2c-pnx.c9
-rw-r--r--drivers/i2c/chips/tsl2550.c3
-rw-r--r--drivers/i2c/i2c-core.c11
-rw-r--r--drivers/ide/atiixp.c2
-rw-r--r--drivers/ide/cmd64x.c6
-rw-r--r--drivers/ide/ide-cs.c33
-rw-r--r--drivers/ide/ide-ioctls.c2
-rw-r--r--drivers/ide/ide-probe.c9
-rw-r--r--drivers/ieee802154/fakehard.c5
-rw-r--r--drivers/input/ff-core.c20
-rw-r--r--drivers/input/ff-memless.c26
-rw-r--r--drivers/input/input.c94
-rw-r--r--drivers/input/keyboard/atkbd.c145
-rw-r--r--drivers/input/keyboard/gpio_keys.c1
-rw-r--r--drivers/input/misc/Kconfig1
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c2
-rw-r--r--drivers/input/mouse/lifebook.c3
-rw-r--r--drivers/input/mouse/logips2pp.c2
-rw-r--r--drivers/input/mouse/psmouse-base.c4
-rw-r--r--drivers/input/mouse/synaptics.c10
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h34
-rw-r--r--drivers/input/serio/i8042.c35
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c4
-rw-r--r--drivers/isdn/hardware/eicon/maintidi.c5
-rw-r--r--drivers/isdn/hardware/eicon/message.c18
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c2
-rw-r--r--drivers/isdn/hisax/amd7930_fn.c1
-rw-r--r--drivers/isdn/hisax/avma1_cs.c28
-rw-r--r--drivers/isdn/hisax/diva.c2
-rw-r--r--drivers/isdn/hisax/elsa_cs.c46
-rw-r--r--drivers/isdn/hisax/elsa_ser.c22
-rw-r--r--drivers/isdn/hisax/hfc_usb.c4
-rw-r--r--drivers/isdn/hisax/hscx_irq.c2
-rw-r--r--drivers/isdn/hisax/icc.c1
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c64
-rw-r--r--drivers/isdn/hisax/teles_cs.c38
-rw-r--r--drivers/isdn/i4l/isdn_net.h6
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c352
-rw-r--r--drivers/isdn/mISDN/stack.c2
-rw-r--r--drivers/leds/leds-gpio.c2
-rw-r--r--drivers/macintosh/via-pmu.c40
-rw-r--r--drivers/md/Makefile22
-rw-r--r--drivers/md/bitmap.c9
-rw-r--r--drivers/md/dm-exception-store.c38
-rw-r--r--drivers/md/dm-exception-store.h8
-rw-r--r--drivers/md/dm-log-userspace-base.c2
-rw-r--r--drivers/md/dm-snap-persistent.c16
-rw-r--r--drivers/md/dm-snap.c25
-rw-r--r--drivers/md/dm.c11
-rw-r--r--drivers/md/md.c48
-rw-r--r--drivers/md/raid1.c13
-rw-r--r--drivers/md/raid10.c5
-rw-r--r--drivers/md/raid5.c269
-rw-r--r--drivers/md/raid5.h14
-rw-r--r--drivers/md/raid6altivec.uc2
-rw-r--r--drivers/md/raid6int.uc2
-rw-r--r--drivers/md/raid6test/Makefile42
-rw-r--r--drivers/md/unroll.awk20
-rw-r--r--drivers/md/unroll.pl24
-rw-r--r--drivers/media/common/ir-functions.c2
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c8
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c1
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig2
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.c2
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c10
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c15
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c38
-rw-r--r--drivers/media/dvb/firewire/firedtv-fe.c8
-rw-r--r--drivers/media/dvb/frontends/dib0070.h7
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c5
-rw-r--r--drivers/media/dvb/pt1/pt1.c1
-rw-r--r--drivers/media/dvb/siano/Kconfig2
-rw-r--r--drivers/media/dvb/siano/smsusb.c6
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c33
-rw-r--r--drivers/media/video/davinci/vpif_display.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c5
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c20
-rw-r--r--drivers/media/video/gspca/mr97310a.c2
-rw-r--r--drivers/media/video/gspca/ov519.c2
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c3
-rw-r--r--drivers/media/video/mx1_camera.c1
-rw-r--r--drivers/media/video/mx3_camera.c1
-rw-r--r--drivers/media/video/pxa_camera.c5
-rw-r--r--drivers/media/video/s2255drv.c5
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c6
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/saa7164/saa7164-cmd.c2
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c11
-rw-r--r--drivers/media/video/soc_camera.c33
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c2
-rw-r--r--drivers/media/video/uvc/uvc_video.c3
-rw-r--r--drivers/media/video/videobuf-dma-contig.c1
-rw-r--r--drivers/mfd/twl4030-core.c2
-rw-r--r--drivers/mfd/wm831x-core.c2
-rw-r--r--drivers/mfd/wm831x-irq.c3
-rw-r--r--drivers/misc/eeprom/at24.c76
-rw-r--r--drivers/misc/sgi-gru/gruprocfs.c13
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c5
-rw-r--r--drivers/mmc/host/at91_mci.c1
-rw-r--r--drivers/mmc/host/omap.c1
-rw-r--r--drivers/mmc/host/omap_hsmmc.c2
-rw-r--r--drivers/mmc/host/pxamci.c4
-rw-r--r--drivers/mtd/maps/Kconfig1
-rw-r--r--drivers/mtd/maps/Makefile2
-rw-r--r--drivers/mtd/maps/gpio-addr-flash.c5
-rw-r--r--drivers/mtd/maps/pcmciamtd.c197
-rw-r--r--drivers/mtd/maps/sa1100-flash.c4
-rw-r--r--drivers/mtd/nand/nand_base.c6
-rw-r--r--drivers/mtd/ubi/build.c3
-rw-r--r--drivers/mtd/ubi/scan.c7
-rw-r--r--drivers/mtd/ubi/scan.h2
-rw-r--r--drivers/net/Kconfig13
-rw-r--r--drivers/net/Makefile10
-rw-r--r--drivers/net/acenic.c3
-rw-r--r--drivers/net/arm/ep93xx_eth.c12
-rw-r--r--drivers/net/au1000_eth.c16
-rw-r--r--drivers/net/b44.c3
-rw-r--r--drivers/net/benet/be.h2
-rw-r--r--drivers/net/benet/be_cmds.c33
-rw-r--r--drivers/net/benet/be_cmds.h7
-rw-r--r--drivers/net/benet/be_ethtool.c8
-rw-r--r--drivers/net/benet/be_main.c55
-rw-r--r--drivers/net/bnx2.h9
-rw-r--r--drivers/net/bonding/bond_main.c10
-rw-r--r--drivers/net/can/Kconfig60
-rw-r--r--drivers/net/can/dev.c23
-rw-r--r--drivers/net/can/sja1000/Kconfig47
-rw-r--r--drivers/net/can/sja1000/sja1000_of_platform.c1
-rw-r--r--drivers/net/can/usb/Kconfig10
-rw-r--r--drivers/net/can/usb/Makefile2
-rw-r--r--drivers/net/can/usb/ems_usb.c5
-rw-r--r--drivers/net/cassini.c5
-rw-r--r--drivers/net/cnic.c6
-rw-r--r--drivers/net/cxgb3/sge.c4
-rw-r--r--drivers/net/davinci_emac.c67
-rw-r--r--drivers/net/dm9000.h2
-rw-r--r--drivers/net/e100.c43
-rw-r--r--drivers/net/e1000e/defines.h2
-rw-r--r--drivers/net/e1000e/e1000.h28
-rw-r--r--drivers/net/e1000e/ethtool.c12
-rw-r--r--drivers/net/e1000e/hw.h3
-rw-r--r--drivers/net/e1000e/ich8lan.c630
-rw-r--r--drivers/net/e1000e/netdev.c50
-rw-r--r--drivers/net/e1000e/phy.c540
-rw-r--r--drivers/net/ethoc.c24
-rw-r--r--drivers/net/fec.c2
-rw-r--r--drivers/net/fec_mpc52xx.c6
-rw-r--r--drivers/net/fec_mpc52xx_phy.c1
-rw-r--r--drivers/net/forcedeth.c5
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c1
-rw-r--r--drivers/net/fs_enet/mii-bitbang.c1
-rw-r--r--drivers/net/fs_enet/mii-fec.c1
-rw-r--r--drivers/net/fsl_pq_mdio.c2
-rw-r--r--drivers/net/gianfar.c4
-rw-r--r--drivers/net/ibm_newemac/core.c9
-rw-r--r--drivers/net/ibm_newemac/emac.h5
-rw-r--r--drivers/net/ifb.c3
-rw-r--r--drivers/net/igb/igb_ethtool.c35
-rw-r--r--drivers/net/igbvf/ethtool.c30
-rw-r--r--drivers/net/irda/sa1100_ir.c7
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c22
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c85
-rw-r--r--drivers/net/ixp2000/enp2611.c18
-rw-r--r--drivers/net/ixp2000/ixpdev.c11
-rw-r--r--drivers/net/ks8851.c42
-rw-r--r--drivers/net/ks8851.h1
-rw-r--r--drivers/net/ks8851_mll.c142
-rw-r--r--drivers/net/macsonic.c117
-rw-r--r--drivers/net/macvlan.c2
-rw-r--r--drivers/net/mlx4/main.c1
-rw-r--r--drivers/net/myri10ge/myri10ge.c17
-rw-r--r--drivers/net/netxen/netxen_nic.h2
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h3
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c69
-rw-r--r--drivers/net/netxen/netxen_nic_init.c10
-rw-r--r--drivers/net/netxen/netxen_nic_main.c8
-rw-r--r--drivers/net/niu.c2
-rw-r--r--drivers/net/pcmcia/3c574_cs.c103
-rw-r--r--drivers/net/pcmcia/3c589_cs.c102
-rw-r--r--drivers/net/pcmcia/axnet_cs.c56
-rw-r--r--drivers/net/pcmcia/com20020_cs.c63
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c189
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c71
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c173
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c82
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c340
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c259
-rw-r--r--drivers/net/phy/mdio-gpio.c3
-rw-r--r--drivers/net/ppp_generic.c11
-rw-r--r--drivers/net/pppoe.c129
-rw-r--r--drivers/net/qlge/qlge.h11
-rw-r--r--drivers/net/qlge/qlge_main.c177
-rw-r--r--drivers/net/qlge/qlge_mpi.c118
-rw-r--r--drivers/net/r6040.c2
-rw-r--r--drivers/net/r8169.c1013
-rw-r--r--drivers/net/s2io.c1
-rw-r--r--drivers/net/sfc/rx.c9
-rw-r--r--drivers/net/sfc/sfe4001.c4
-rw-r--r--drivers/net/sh_eth.c1
-rw-r--r--drivers/net/sky2.c2
-rw-r--r--drivers/net/smc91x.c2
-rw-r--r--drivers/net/smsc911x.c2
-rw-r--r--drivers/net/smsc9420.c14
-rw-r--r--drivers/net/stmmac/Kconfig53
-rw-r--r--drivers/net/stmmac/Makefile4
-rw-r--r--drivers/net/stmmac/common.h330
-rw-r--r--drivers/net/stmmac/descs.h163
-rw-r--r--drivers/net/stmmac/gmac.c693
-rw-r--r--drivers/net/stmmac/gmac.h204
-rw-r--r--drivers/net/stmmac/mac100.c517
-rw-r--r--drivers/net/stmmac/mac100.h116
-rw-r--r--drivers/net/stmmac/stmmac.h98
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c395
-rw-r--r--drivers/net/stmmac/stmmac_main.c2210
-rw-r--r--drivers/net/stmmac/stmmac_mdio.c217
-rw-r--r--drivers/net/stmmac/stmmac_timer.c140
-rw-r--r--drivers/net/stmmac/stmmac_timer.h42
-rw-r--r--drivers/net/sungem.c10
-rw-r--r--drivers/net/tokenring/ibmtr.c11
-rw-r--r--drivers/net/usb/Kconfig2
-rw-r--r--drivers/net/usb/cdc_ether.c42
-rw-r--r--drivers/net/usb/dm9601.c4
-rw-r--r--drivers/net/usb/hso.c8
-rw-r--r--drivers/net/usb/pegasus.c13
-rw-r--r--drivers/net/usb/pegasus.h6
-rw-r--r--drivers/net/usb/rndis_host.c6
-rw-r--r--drivers/net/veth.c35
-rw-r--r--drivers/net/virtio_net.c23
-rw-r--r--drivers/net/vmxnet3/Makefile35
-rw-r--r--drivers/net/vmxnet3/upt1_defs.h96
-rw-r--r--drivers/net/vmxnet3/vmxnet3_defs.h535
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c2574
-rw-r--r--drivers/net/vmxnet3/vmxnet3_ethtool.c566
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h389
-rw-r--r--drivers/net/wan/cosa.c1
-rw-r--r--drivers/net/wan/hdlc_cisco.c18
-rw-r--r--drivers/net/wireless/adm8211.h2
-rw-r--r--drivers/net/wireless/airo.c5
-rw-r--r--drivers/net/wireless/airo_cs.c55
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c2
-rw-r--r--drivers/net/wireless/atmel_cs.c51
-rw-r--r--drivers/net/wireless/b43/b43.h168
-rw-r--r--drivers/net/wireless/b43/dma.c15
-rw-r--r--drivers/net/wireless/b43/leds.c4
-rw-r--r--drivers/net/wireless/b43/leds.h5
-rw-r--r--drivers/net/wireless/b43/main.c9
-rw-r--r--drivers/net/wireless/b43/pcmcia.c26
-rw-r--r--drivers/net/wireless/b43/pio.c78
-rw-r--r--drivers/net/wireless/b43/rfkill.c3
-rw-r--r--drivers/net/wireless/b43/xmit.c5
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c51
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c6
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c141
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h8
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c2
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c1
-rw-r--r--drivers/net/wireless/libertas/ethtool.c17
-rw-r--r--drivers/net/wireless/libertas/if_cs.c72
-rw-r--r--drivers/net/wireless/libertas/if_spi.c10
-rw-r--r--drivers/net/wireless/libertas/if_usb.c2
-rw-r--r--drivers/net/wireless/netwave_cs.c95
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c33
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c60
-rw-r--r--drivers/net/wireless/p54/p54usb.c10
-rw-r--r--drivers/net/wireless/ray_cs.c359
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c5
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.c4
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rfkill.c1
-rw-r--r--drivers/net/wireless/wavelan_cs.c35
-rw-r--r--drivers/net/wireless/wl3501_cs.c74
-rw-r--r--drivers/net/znet.c8
-rw-r--r--drivers/of/of_mdio.c13
-rw-r--r--drivers/oprofile/event_buffer.c35
-rw-r--r--drivers/parport/parport_cs.c38
-rw-r--r--drivers/pci/dmar.c59
-rw-r--r--drivers/pci/intel-iommu.c45
-rw-r--r--drivers/pci/pcie/aspm.c6
-rw-r--r--drivers/pci/quirks.c6
-rw-r--r--drivers/pci/setup-bus.c13
-rw-r--r--drivers/pcmcia/Kconfig42
-rw-r--r--drivers/pcmcia/Makefile10
-rw-r--r--drivers/pcmcia/cardbus.c4
-rw-r--r--drivers/pcmcia/cirrus.h10
-rw-r--r--drivers/pcmcia/cistpl.c91
-rw-r--r--drivers/pcmcia/cs.c136
-rw-r--r--drivers/pcmcia/cs_internal.h45
-rw-r--r--drivers/pcmcia/ds.c196
-rw-r--r--drivers/pcmcia/i82365.c41
-rw-r--r--drivers/pcmcia/m32r_cfc.c115
-rw-r--r--drivers/pcmcia/m32r_pcc.c61
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c55
-rw-r--r--drivers/pcmcia/o2micro.h22
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c94
-rw-r--r--drivers/pcmcia/pcmcia_resource.c482
-rw-r--r--drivers/pcmcia/pd6729.c72
-rw-r--r--drivers/pcmcia/pd6729.h7
-rw-r--r--drivers/pcmcia/pxa2xx_base.c94
-rw-r--r--drivers/pcmcia/pxa2xx_base.h3
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x255.c2
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x270.c2
-rw-r--r--drivers/pcmcia/pxa2xx_e740.c2
-rw-r--r--drivers/pcmcia/pxa2xx_lubbock.c14
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c2
-rw-r--r--drivers/pcmcia/pxa2xx_palmld.c2
-rw-r--r--drivers/pcmcia/pxa2xx_palmtx.c2
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c2
-rw-r--r--drivers/pcmcia/pxa2xx_trizeps4.c4
-rw-r--r--drivers/pcmcia/pxa2xx_viper.c2
-rw-r--r--drivers/pcmcia/rsrc_mgr.c1
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c3
-rw-r--r--drivers/pcmcia/sa1100_assabet.c2
-rw-r--r--drivers/pcmcia/sa1100_badge4.c11
-rw-r--r--drivers/pcmcia/sa1100_cerf.c2
-rw-r--r--drivers/pcmcia/sa1100_generic.c11
-rw-r--r--drivers/pcmcia/sa1100_h3600.c4
-rw-r--r--drivers/pcmcia/sa1100_jornada720.c42
-rw-r--r--drivers/pcmcia/sa1100_neponset.c13
-rw-r--r--drivers/pcmcia/sa1100_shannon.c2
-rw-r--r--drivers/pcmcia/sa1100_simpad.c2
-rw-r--r--drivers/pcmcia/sa1111_generic.c65
-rw-r--r--drivers/pcmcia/sa1111_generic.h17
-rw-r--r--drivers/pcmcia/sa11xx_base.c99
-rw-r--r--drivers/pcmcia/sa11xx_base.h2
-rw-r--r--drivers/pcmcia/soc_common.c230
-rw-r--r--drivers/pcmcia/soc_common.h10
-rw-r--r--drivers/pcmcia/socket_sysfs.c2
-rw-r--r--drivers/pcmcia/tcic.c33
-rw-r--r--drivers/pcmcia/topic.h15
-rw-r--r--drivers/pcmcia/yenta_socket.c12
-rw-r--r--drivers/platform/x86/acerhdf.c12
-rw-r--r--drivers/platform/x86/eeepc-laptop.c7
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c2
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c26
-rw-r--r--drivers/pps/kapi.c20
-rw-r--r--drivers/pps/pps.c11
-rw-r--r--drivers/regulator/core.c3
-rw-r--r--drivers/regulator/fixed.c5
-rw-r--r--drivers/regulator/wm831x-isink.c2
-rw-r--r--drivers/regulator/wm831x-ldo.c6
-rw-r--r--drivers/rtc/rtc-coh901331.c11
-rw-r--r--drivers/rtc/rtc-pcf50633.c10
-rw-r--r--drivers/rtc/rtc-v3020.c2
-rw-r--r--drivers/rtc/rtc-vr41xx.c9
-rw-r--r--drivers/rtc/rtc-x1205.c6
-rw-r--r--drivers/s390/block/dasd.c13
-rw-r--r--drivers/s390/block/dasd_eckd.c8
-rw-r--r--drivers/s390/char/monreader.c1
-rw-r--r--drivers/s390/char/sclp_async.c51
-rw-r--r--drivers/s390/char/sclp_quiesce.c48
-rw-r--r--drivers/s390/char/sclp_vt220.c30
-rw-r--r--drivers/s390/char/tape_block.c3
-rw-r--r--drivers/s390/cio/device.c9
-rw-r--r--drivers/s390/net/smsgiucv.c7
-rw-r--r--drivers/s390/scsi/zfcp_aux.c11
-rw-r--r--drivers/s390/scsi/zfcp_erp.c22
-rw-r--r--drivers/s390/scsi/zfcp_ext.h1
-rw-r--r--drivers/s390/scsi/zfcp_fc.c11
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c13
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c1
-rw-r--r--drivers/scsi/bfa/bfad_fwimg.c2
-rw-r--r--drivers/scsi/bfa/bfad_im.c2
-rw-r--r--drivers/scsi/dpt_i2o.c4
-rw-r--r--drivers/scsi/gdth.c2
-rw-r--r--drivers/scsi/hosts.c2
-rw-r--r--drivers/scsi/ipr.c42
-rw-r--r--drivers/scsi/ipr.h1
-rw-r--r--drivers/scsi/libsas/sas_expander.c1
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c42
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c44
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c8
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c45
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c42
-rw-r--r--drivers/scsi/pmcraid.c10
-rw-r--r--drivers/scsi/scsi_scan.c18
-rw-r--r--drivers/scsi/scsi_sysfs.c68
-rw-r--r--drivers/scsi/scsi_transport_fc.c3
-rw-r--r--drivers/scsi/sd_dif.c2
-rw-r--r--drivers/serial/8250.c2
-rw-r--r--drivers/serial/8250_pci.c86
-rw-r--r--drivers/serial/atmel_serial.c2
-rw-r--r--drivers/serial/bcm63xx_uart.c4
-rw-r--r--drivers/serial/mpc52xx_uart.c2
-rw-r--r--drivers/serial/of_serial.c1
-rw-r--r--drivers/serial/serial_cs.c151
-rw-r--r--drivers/serial/sh-sci.c2
-rw-r--r--drivers/serial/suncore.c37
-rw-r--r--drivers/serial/suncore.h5
-rw-r--r--drivers/serial/sunhv.c2
-rw-r--r--drivers/serial/sunsab.c9
-rw-r--r--drivers/serial/sunsu.c36
-rw-r--r--drivers/serial/sunzilog.c8
-rw-r--r--drivers/spi/spi_stmp.c2
-rw-r--r--drivers/spi/spi_txx9.c13
-rw-r--r--drivers/ssb/pcmcia.c232
-rw-r--r--drivers/ssb/scan.c6
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/android/Kconfig1
-rw-r--r--drivers/staging/b3dfg/b3dfg.c1
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c221
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c203
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c237
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c236
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c225
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c127
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c1
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c219
-rw-r--r--drivers/staging/et131x/et1310_address_map.h2
-rw-r--r--drivers/staging/et131x/et1310_rx.c20
-rw-r--r--drivers/staging/go7007/s2250-board.c4
-rw-r--r--drivers/staging/go7007/s2250-loader.h24
-rw-r--r--drivers/staging/hv/BlkVsc.c1
-rw-r--r--drivers/staging/hv/Channel.c16
-rw-r--r--drivers/staging/hv/ChannelMgmt.c2
-rw-r--r--drivers/staging/hv/ChannelMgmt.h3
-rw-r--r--drivers/staging/hv/NetVsc.c11
-rw-r--r--drivers/staging/hv/NetVsc.h1
-rw-r--r--drivers/staging/hv/StorVsc.c10
-rw-r--r--drivers/staging/hv/TODO6
-rw-r--r--drivers/staging/hv/blkvsc_drv.c1
-rw-r--r--drivers/staging/hv/netvsc_drv.c1
-rw-r--r--drivers/staging/hv/osd.c1
-rw-r--r--drivers/staging/hv/osd.h1
-rw-r--r--drivers/staging/hv/vmbus_drv.c28
-rw-r--r--drivers/staging/iio/industrialio-core.c2
-rw-r--r--drivers/staging/octeon/ethernet-mdio.c2
-rw-r--r--drivers/staging/octeon/ethernet-spi.c2
-rw-r--r--drivers/staging/octeon/ethernet.c53
-rw-r--r--drivers/staging/otus/Kconfig2
-rw-r--r--drivers/staging/panel/panel.c13
-rw-r--r--drivers/staging/poch/poch.c1
-rw-r--r--drivers/staging/rt2860/Kconfig2
-rw-r--r--drivers/staging/rt2860/common/cmm_data_2860.c2
-rw-r--r--drivers/staging/rt2860/common/cmm_info.c1
-rw-r--r--drivers/staging/rt2860/rt_linux.c1
-rw-r--r--drivers/staging/rt2870/Kconfig2
-rw-r--r--drivers/staging/rt3090/Kconfig2
-rw-r--r--drivers/staging/rt3090/common/cmm_info.c1
-rw-r--r--drivers/staging/rt3090/rt_linux.c1
-rw-r--r--drivers/staging/rtl8187se/Kconfig2
-rw-r--r--drivers/staging/rtl8187se/TODO3
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c4
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_module.c4
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c12
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c17
-rw-r--r--drivers/staging/rtl8192e/Kconfig2
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c8
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_module.c8
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c19
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c21
-rw-r--r--drivers/staging/rtl8192su/Kconfig2
-rw-r--r--drivers/staging/rtl8192su/TODO3
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c4
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_module.c4
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c15
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c17
-rw-r--r--drivers/staging/sep/sep_driver.c1
-rw-r--r--drivers/staging/stlc45xx/Kconfig8
-rw-r--r--drivers/staging/stlc45xx/Makefile1
-rw-r--r--drivers/staging/stlc45xx/stlc45xx.c2594
-rw-r--r--drivers/staging/stlc45xx/stlc45xx.h283
-rw-r--r--drivers/staging/stlc45xx/stlc45xx_lmac.h434
-rw-r--r--drivers/staging/vme/bridges/vme_ca91cx42.c1
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.c1
-rw-r--r--drivers/staging/vt6655/TODO5
-rw-r--r--drivers/staging/vt6656/TODO5
-rw-r--r--drivers/staging/vt6656/main_usb.c1
-rw-r--r--drivers/staging/winbond/Kconfig2
-rw-r--r--drivers/staging/wlan-ng/Kconfig2
-rw-r--r--drivers/telephony/ixj_pcmcia.c36
-rw-r--r--drivers/thermal/thermal_sys.c10
-rw-r--r--drivers/uio/uio_pdrv_genirq.c1
-rw-r--r--drivers/usb/class/cdc-acm.c18
-rw-r--r--drivers/usb/core/hub.c2
-rw-r--r--drivers/usb/gadget/Kconfig1
-rw-r--r--drivers/usb/gadget/amd5536udc.c49
-rw-r--r--drivers/usb/gadget/ether.c9
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c2
-rw-r--r--drivers/usb/host/ehci-hcd.c2
-rw-r--r--drivers/usb/host/ehci-pci.c4
-rw-r--r--drivers/usb/host/ehci-q.c16
-rw-r--r--drivers/usb/host/ehci-sched.c24
-rw-r--r--drivers/usb/host/ehci.h2
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/ohci-pci.c20
-rw-r--r--drivers/usb/host/ohci-q.c18
-rw-r--r--drivers/usb/host/ohci.h9
-rw-r--r--drivers/usb/host/r8a66597-hcd.c23
-rw-r--r--drivers/usb/host/sl811_cs.c49
-rw-r--r--drivers/usb/host/whci/asl.c23
-rw-r--r--drivers/usb/host/whci/pzl.c24
-rw-r--r--drivers/usb/host/xhci-mem.c10
-rw-r--r--drivers/usb/host/xhci-ring.c7
-rw-r--r--drivers/usb/mon/mon_bin.c11
-rw-r--r--drivers/usb/musb/cppi_dma.c10
-rw-r--r--drivers/usb/musb/musb_core.c4
-rw-r--r--drivers/usb/musb/musb_gadget.c79
-rw-r--r--drivers/usb/musb/musb_gadget_ep0.c3
-rw-r--r--drivers/usb/musb/musb_host.c5
-rw-r--r--drivers/usb/serial/cp210x.c21
-rw-r--r--drivers/usb/serial/ftdi_sio.c3
-rw-r--r--drivers/usb/serial/option.c15
-rw-r--r--drivers/usb/serial/sierra.c38
-rw-r--r--drivers/usb/storage/transport.c17
-rw-r--r--drivers/usb/wusbcore/security.c41
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/atafb.c6
-rw-r--r--drivers/video/atmel_lcdfb.c11
-rw-r--r--drivers/video/backlight/corgi_lcd.c5
-rw-r--r--drivers/video/backlight/lcd.c2
-rw-r--r--drivers/video/console/fbcon.c5
-rw-r--r--drivers/video/da8xx-fb.c13
-rw-r--r--drivers/video/gbefb.c2
-rw-r--r--drivers/video/msm/mddi.c1
-rw-r--r--drivers/video/msm/mddi_client_nt35399.c1
-rw-r--r--drivers/video/msm/mddi_client_toshiba.c1
-rw-r--r--drivers/video/msm/mdp.c18
-rw-r--r--drivers/video/msm/mdp_ppp.c20
-rw-r--r--drivers/video/savage/savagefb_driver.c20
-rw-r--r--drivers/video/uvesafb.c28
-rw-r--r--drivers/virtio/virtio_balloon.c3
-rw-r--r--drivers/virtio/virtio_pci.c27
-rw-r--r--drivers/virtio/virtio_ring.c3
-rw-r--r--drivers/watchdog/pnx4008_wdt.c4
-rw-r--r--drivers/watchdog/rc32434_wdt.c4
-rw-r--r--drivers/watchdog/riowd.c2
-rw-r--r--drivers/watchdog/sbc_fitpc2_wdt.c2
-rw-r--r--firmware/Makefile6
-rw-r--r--firmware/WHENCE4
-rw-r--r--firmware/cis/PE-200.cis.ihex9
-rw-r--r--firmware/cis/SW_555_SER.cis.ihex12
-rw-r--r--firmware/cis/SW_7xx_SER.cis.ihex13
-rw-r--r--firmware/cis/SW_8xx_SER.cis.ihex13
-rw-r--r--fs/9p/cache.c14
-rw-r--r--fs/9p/vfs_dir.c93
-rw-r--r--fs/9p/vfs_inode.c5
-rw-r--r--fs/Kconfig4
-rw-r--r--fs/afs/file.c15
-rw-r--r--fs/bio.c28
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/btrfs/acl.c6
-rw-r--r--fs/btrfs/btrfs_inode.h6
-rw-r--r--fs/btrfs/ctree.h4
-rw-r--r--fs/btrfs/disk-io.c2
-rw-r--r--fs/btrfs/extent-tree.c130
-rw-r--r--fs/btrfs/extent_map.c2
-rw-r--r--fs/btrfs/file.c41
-rw-r--r--fs/btrfs/free-space-cache.c2
-rw-r--r--fs/btrfs/inode.c128
-rw-r--r--fs/btrfs/root-tree.c2
-rw-r--r--fs/btrfs/super.c9
-rw-r--r--fs/btrfs/transaction.c64
-rw-r--r--fs/btrfs/transaction.h5
-rw-r--r--fs/btrfs/tree-log.c48
-rw-r--r--fs/btrfs/tree-log.h3
-rw-r--r--fs/btrfs/xattr.c2
-rw-r--r--fs/cachefiles/interface.c32
-rw-r--r--fs/cachefiles/namei.c187
-rw-r--r--fs/cachefiles/rdwr.c130
-rw-r--r--fs/cifs/CHANGES9
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsproto.h1
-rw-r--r--fs/cifs/connect.c11
-rw-r--r--fs/cifs/dir.c8
-rw-r--r--fs/cifs/inode.c7
-rw-r--r--fs/cifs/misc.c14
-rw-r--r--fs/cifs/readdir.c7
-rw-r--r--fs/compat.c2
-rw-r--r--fs/compat_ioctl.c4
-rw-r--r--fs/dlm/lowcomms.c36
-rw-r--r--fs/exec.c12
-rw-r--r--fs/ext3/fsync.c36
-rw-r--r--fs/ext3/inode.c36
-rw-r--r--fs/ext3/super.c2
-rw-r--r--fs/ext4/ext4.h2
-rw-r--r--fs/ext4/extents.c36
-rw-r--r--fs/ext4/inode.c24
-rw-r--r--fs/ext4/namei.c16
-rw-r--r--fs/ext4/super.c20
-rw-r--r--fs/fcntl.c4
-rw-r--r--fs/file_table.c2
-rw-r--r--fs/fscache/Kconfig7
-rw-r--r--fs/fscache/Makefile1
-rw-r--r--fs/fscache/cache.c5
-rw-r--r--fs/fscache/cookie.c26
-rw-r--r--fs/fscache/internal.h56
-rw-r--r--fs/fscache/main.c6
-rw-r--r--fs/fscache/object-list.c432
-rw-r--r--fs/fscache/object.c104
-rw-r--r--fs/fscache/operation.c120
-rw-r--r--fs/fscache/page.c273
-rw-r--r--fs/fscache/proc.c13
-rw-r--r--fs/fscache/stats.c94
-rw-r--r--fs/fuse/dir.c7
-rw-r--r--fs/fuse/file.c5
-rw-r--r--fs/gfs2/Kconfig2
-rw-r--r--fs/gfs2/acl.c357
-rw-r--r--fs/gfs2/acl.h24
-rw-r--r--fs/gfs2/aops.c20
-rw-r--r--fs/gfs2/dir.c34
-rw-r--r--fs/gfs2/glock.c31
-rw-r--r--fs/gfs2/glock.h9
-rw-r--r--fs/gfs2/glops.c5
-rw-r--r--fs/gfs2/incore.h5
-rw-r--r--fs/gfs2/inode.c4
-rw-r--r--fs/gfs2/log.c2
-rw-r--r--fs/gfs2/lops.c4
-rw-r--r--fs/gfs2/main.c4
-rw-r--r--fs/gfs2/ops_fstype.c154
-rw-r--r--fs/gfs2/quota.c393
-rw-r--r--fs/gfs2/quota.h5
-rw-r--r--fs/gfs2/recovery.c4
-rw-r--r--fs/gfs2/rgrp.c14
-rw-r--r--fs/gfs2/super.c110
-rw-r--r--fs/gfs2/super.h4
-rw-r--r--fs/gfs2/sys.c14
-rw-r--r--fs/gfs2/xattr.c74
-rw-r--r--fs/gfs2/xattr.h8
-rw-r--r--fs/hfs/btree.c5
-rw-r--r--fs/hfsplus/wrapper.c4
-rw-r--r--fs/inode.c10
-rw-r--r--fs/ioctl.c2
-rw-r--r--fs/jbd/journal.c3
-rw-r--r--fs/jbd2/journal.c2
-rw-r--r--fs/jffs2/read.c9
-rw-r--r--fs/namespace.c20
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nfs/direct.c1
-rw-r--r--fs/nfs/fscache.c10
-rw-r--r--fs/nfs/nfs4proc.c17
-rw-r--r--fs/nfs/nfs4xdr.c1
-rw-r--r--fs/nfs/super.c1
-rw-r--r--fs/nfsd/nfs3xdr.c2
-rw-r--r--fs/nilfs2/btnode.c4
-rw-r--r--fs/nilfs2/cpfile.c2
-rw-r--r--fs/nilfs2/inode.c1
-rw-r--r--fs/nilfs2/ioctl.c39
-rw-r--r--fs/nilfs2/segment.c17
-rw-r--r--fs/notify/dnotify/dnotify.c3
-rw-r--r--fs/notify/inode_mark.c6
-rw-r--r--fs/notify/notification.c2
-rw-r--r--fs/ocfs2/file.c3
-rw-r--r--fs/ocfs2/ocfs2.h7
-rw-r--r--fs/ocfs2/refcounttree.c69
-rw-r--r--fs/ocfs2/super.c20
-rw-r--r--fs/ocfs2/uptodate.c5
-rw-r--r--fs/open.c27
-rw-r--r--fs/pipe.c41
-rw-r--r--fs/proc/array.c25
-rw-r--r--fs/proc/base.c3
-rw-r--r--fs/proc/meminfo.c2
-rw-r--r--fs/proc/stat.c19
-rw-r--r--fs/quota/Kconfig2
-rw-r--r--fs/quota/dquot.c93
-rw-r--r--fs/quota/quota.c93
-rw-r--r--fs/sysfs/dir.c7
-rw-r--r--fs/sysfs/file.c14
-rw-r--r--fs/xattr_acl.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_quotaops.c2
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c1
-rw-r--r--fs/xfs/xfs_ialloc.c1
-rw-r--r--fs/xfs/xfs_log_recover.c4
-rw-r--r--fs/xfs/xfs_trans_ail.c23
-rw-r--r--include/asm-generic/fcntl.h21
-rw-r--r--include/linux/Kbuild2
-rw-r--r--include/linux/bootmem.h1
-rw-r--r--include/linux/capability.h2
-rw-r--r--include/linux/compiler-gcc.h1
-rw-r--r--include/linux/compiler-gcc4.h22
-rw-r--r--include/linux/compiler.h20
-rw-r--r--include/linux/cpufreq.h7
-rw-r--r--include/linux/device.h4
-rw-r--r--include/linux/dmar.h15
-rw-r--r--include/linux/ext3_fs_i.h8
-rw-r--r--include/linux/fb.h6
-rw-r--r--include/linux/fscache-cache.h40
-rw-r--r--include/linux/fscache.h27
-rw-r--r--include/linux/ftrace_event.h38
-rw-r--r--include/linux/gfs2_ondisk.h6
-rw-r--r--include/linux/hardirq.h24
-rw-r--r--include/linux/hid.h1
-rw-r--r--include/linux/hw_breakpoint.h131
-rw-r--r--include/linux/i2c-pnx.h2
-rw-r--r--include/linux/i2c.h18
-rw-r--r--include/linux/init_task.h4
-rw-r--r--include/linux/input.h4
-rw-r--r--include/linux/interrupt.h6
-rw-r--r--include/linux/irqflags.h2
-rw-r--r--include/linux/isdn_ppp.h2
-rw-r--r--include/linux/jiffies.h1
-rw-r--r--include/linux/kernel.h5
-rw-r--r--include/linux/kernel_stat.h1
-rw-r--r--include/linux/kprobes.h2
-rw-r--r--include/linux/lsm_audit.h18
-rw-r--r--include/linux/mfd/wm831x/regulator.h4
-rw-r--r--include/linux/moduleparam.h1
-rw-r--r--include/linux/net.h1
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--include/linux/nilfs2_fs.h9
-rw-r--r--include/linux/pci_ids.h19
-rw-r--r--include/linux/perf_counter.h3
-rw-r--r--include/linux/perf_event.h63
-rw-r--r--include/linux/posix_acl.h14
-rw-r--r--include/linux/prctl.h12
-rw-r--r--include/linux/preempt.h5
-rw-r--r--include/linux/quota.h11
-rw-r--r--include/linux/ratelimit.h33
-rw-r--r--include/linux/rcupdate.h10
-rw-r--r--include/linux/rcutiny.h104
-rw-r--r--include/linux/rcutree.h13
-rw-r--r--include/linux/sched.h45
-rw-r--r--include/linux/securebits.h24
-rw-r--r--include/linux/security.h48
-rw-r--r--include/linux/skbuff.h6
-rw-r--r--include/linux/slow-work.h72
-rw-r--r--include/linux/smp.h11
-rw-r--r--include/linux/smp_lock.h21
-rw-r--r--include/linux/spinlock.h6
-rw-r--r--include/linux/spinlock_api_smp.h75
-rw-r--r--include/linux/srcu.h1
-rw-r--r--include/linux/string.h2
-rw-r--r--include/linux/suspend.h21
-rw-r--r--include/linux/swiotlb.h12
-rw-r--r--include/linux/syscalls.h77
-rw-r--r--include/linux/topology.h4
-rw-r--r--include/linux/tpm.h9
-rw-r--r--include/linux/trace_seq.h2
-rw-r--r--include/linux/tracepoint.h6
-rw-r--r--include/linux/virtio_9p.h1
-rw-r--r--include/linux/virtio_balloon.h1
-rw-r--r--include/linux/virtio_blk.h5
-rw-r--r--include/linux/virtio_console.h1
-rw-r--r--include/linux/virtio_net.h1
-rw-r--r--include/linux/virtio_rng.h1
-rw-r--r--include/linux/vt.h4
-rw-r--r--include/linux/workqueue.h1
-rw-r--r--include/net/9p/client.h7
-rw-r--r--include/net/inet_timewait_sock.h8
-rw-r--r--include/net/ip_fib.h3
-rw-r--r--include/net/mac80211.h8
-rw-r--r--include/net/netfilter/nf_conntrack.h8
-rw-r--r--include/net/netfilter/nf_nat_helper.h4
-rw-r--r--include/net/sctp/structs.h3
-rw-r--r--include/net/sock.h10
-rw-r--r--include/pcmcia/cs.h14
-rw-r--r--include/pcmcia/cs_types.h3
-rw-r--r--include/pcmcia/ds.h88
-rw-r--r--include/pcmcia/ss.h17
-rw-r--r--include/scsi/scsi_device.h1
-rw-r--r--include/scsi/scsi_host.h29
-rw-r--r--include/trace/define_trace.h11
-rw-r--r--include/trace/events/bkl.h61
-rw-r--r--include/trace/events/block.h202
-rw-r--r--include/trace/events/ext4.h129
-rw-r--r--include/trace/events/irq.h52
-rw-r--r--include/trace/events/jbd2.h63
-rw-r--r--include/trace/events/kmem.h130
-rw-r--r--include/trace/events/lock.h (renamed from include/trace/events/lockdep.h)8
-rw-r--r--include/trace/events/mce.h69
-rw-r--r--include/trace/events/module.h22
-rw-r--r--include/trace/events/power.h38
-rw-r--r--include/trace/events/sched.h217
-rw-r--r--include/trace/events/signal.h173
-rw-r--r--include/trace/events/syscalls.h3
-rw-r--r--include/trace/events/timer.h79
-rw-r--r--include/trace/events/workqueue.h22
-rw-r--r--include/trace/ftrace.h340
-rw-r--r--include/trace/power.h32
-rw-r--r--include/trace/syscall.h33
-rw-r--r--init/Kconfig28
-rw-r--r--init/main.c11
-rw-r--r--kernel/Kconfig.locks202
-rw-r--r--kernel/Makefile4
-rw-r--r--kernel/capability.c15
-rw-r--r--kernel/cgroup.c8
-rw-r--r--kernel/cpuset.c27
-rw-r--r--kernel/exit.c31
-rw-r--r--kernel/fork.c7
-rw-r--r--kernel/futex.c20
-rw-r--r--kernel/hung_task.c2
-rw-r--r--kernel/hw_breakpoint.c423
-rw-r--r--kernel/irq/chip.c6
-rw-r--r--kernel/irq/proc.c40
-rw-r--r--kernel/irq/spurious.c16
-rw-r--r--kernel/kallsyms.c1
-rw-r--r--kernel/kgdb.c2
-rw-r--r--kernel/kmod.c8
-rw-r--r--kernel/kprobes.c72
-rw-r--r--kernel/kthread.c23
-rw-r--r--kernel/lockdep.c22
-rw-r--r--kernel/module.c5
-rw-r--r--kernel/mutex.c4
-rw-r--r--kernel/notifier.c2
-rw-r--r--kernel/params.c17
-rw-r--r--kernel/perf_event.c695
-rw-r--r--kernel/power/hibernate.c11
-rw-r--r--kernel/power/suspend_test.c5
-rw-r--r--kernel/power/swap.c43
-rw-r--r--kernel/printk.c7
-rw-r--r--kernel/rcupdate.c122
-rw-r--r--kernel/rcutiny.c282
-rw-r--r--kernel/rcutorture.c65
-rw-r--r--kernel/rcutree.c493
-rw-r--r--kernel/rcutree.h84
-rw-r--r--kernel/rcutree_plugin.h343
-rw-r--r--kernel/rcutree_trace.c12
-rw-r--r--kernel/sched.c340
-rw-r--r--kernel/sched_debug.c4
-rw-r--r--kernel/sched_fair.c139
-rw-r--r--kernel/sched_rt.c61
-rw-r--r--kernel/signal.c73
-rw-r--r--kernel/slow-work-debugfs.c227
-rw-r--r--kernel/slow-work.c512
-rw-r--r--kernel/slow-work.h72
-rw-r--r--kernel/smp.c56
-rw-r--r--kernel/softirq.c2
-rw-r--r--kernel/spinlock.c310
-rw-r--r--kernel/srcu.c74
-rw-r--r--kernel/sys.c46
-rw-r--r--kernel/sysctl.c3
-rw-r--r--kernel/sysctl_check.c2
-rw-r--r--kernel/time.c30
-rw-r--r--kernel/trace/Kconfig38
-rw-r--r--kernel/trace/Makefile2
-rw-r--r--kernel/trace/ftrace.c383
-rw-r--r--kernel/trace/ring_buffer.c38
-rw-r--r--kernel/trace/ring_buffer_benchmark.c85
-rw-r--r--kernel/trace/trace.c55
-rw-r--r--kernel/trace/trace.h80
-rw-r--r--kernel/trace/trace_clock.c8
-rw-r--r--kernel/trace/trace_entries.h16
-rw-r--r--kernel/trace/trace_event_profile.c43
-rw-r--r--kernel/trace/trace_events.c191
-rw-r--r--kernel/trace/trace_events_filter.c426
-rw-r--r--kernel/trace/trace_export.c43
-rw-r--r--kernel/trace/trace_kprobe.c1523
-rw-r--r--kernel/trace/trace_ksym.c550
-rw-r--r--kernel/trace/trace_output.c5
-rw-r--r--kernel/trace/trace_selftest.c55
-rw-r--r--kernel/trace/trace_syscalls.c229
-rw-r--r--kernel/user.c2
-rw-r--r--kernel/workqueue.c35
-rw-r--r--lib/Kconfig.debug4
-rw-r--r--lib/dma-debug.c6
-rw-r--r--lib/kernel_lock.c20
-rw-r--r--lib/radix-tree.c5
-rw-r--r--lib/ratelimit.c45
-rw-r--r--lib/string.c20
-rw-r--r--lib/swiotlb.c46
-rw-r--r--mm/Kconfig9
-rw-r--r--mm/backing-dev.c25
-rw-r--r--mm/bootmem.c24
-rw-r--r--mm/highmem.c17
-rw-r--r--mm/ksm.c1
-rw-r--r--mm/memory-failure.c59
-rw-r--r--mm/memory.c14
-rw-r--r--mm/memory_hotplug.c24
-rw-r--r--mm/mempolicy.c13
-rw-r--r--mm/migrate.c2
-rw-r--r--mm/mmap.c4
-rw-r--r--mm/nommu.c6
-rw-r--r--mm/page_alloc.c7
-rw-r--r--mm/percpu.c139
-rw-r--r--mm/swapfile.c3
-rw-r--r--mm/vmscan.c14
-rw-r--r--net/8021q/vlan.c7
-rw-r--r--net/9p/client.c5
-rw-r--r--net/9p/trans_virtio.c1
-rw-r--r--net/bluetooth/hci_conn.c1
-rw-r--r--net/bluetooth/hci_sysfs.c4
-rw-r--r--net/bluetooth/l2cap.c22
-rw-r--r--net/bridge/br_if.c6
-rw-r--r--net/can/bcm.c19
-rw-r--r--net/core/datagram.c10
-rw-r--r--net/core/dev.c11
-rw-r--r--net/core/pktgen.c47
-rw-r--r--net/core/skbuff.c3
-rw-r--r--net/core/sysctl_net_core.c2
-rw-r--r--net/core/utils.c2
-rw-r--r--net/decnet/sysctl_net_decnet.c7
-rw-r--r--net/ipv4/fib_frontend.c5
-rw-r--r--net/ipv4/inet_connection_sock.c34
-rw-r--r--net/ipv4/ip_fragment.c2
-rw-r--r--net/ipv4/ip_gre.c28
-rw-r--r--net/ipv4/ip_sockglue.c7
-rw-r--r--net/ipv4/ipip.c32
-rw-r--r--net/ipv4/ipmr.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c3
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c34
-rw-r--r--net/ipv4/raw.c24
-rw-r--r--net/ipv4/route.c8
-rw-r--r--net/ipv4/tcp.c74
-rw-r--r--net/ipv4/tcp_minisocks.c4
-rw-r--r--net/ipv4/udp.c77
-rw-r--r--net/ipv6/ipv6_sockglue.c6
-rw-r--r--net/ipv6/udp.c4
-rw-r--r--net/mac80211/agg-rx.c4
-rw-r--r--net/mac80211/agg-tx.c38
-rw-r--r--net/mac80211/cfg.c6
-rw-r--r--net/mac80211/ht.c10
-rw-r--r--net/mac80211/ibss.c14
-rw-r--r--net/mac80211/ieee80211_i.h10
-rw-r--r--net/mac80211/mesh_hwmp.c2
-rw-r--r--net/mac80211/mlme.c3
-rw-r--r--net/mac80211/rx.c12
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/util.c23
-rw-r--r--net/netfilter/nf_conntrack_core.c8
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c64
-rw-r--r--net/netfilter/nf_log.c18
-rw-r--r--net/netfilter/xt_connlimit.c10
-rw-r--r--net/netfilter/xt_limit.c2
-rw-r--r--net/netfilter/xt_osf.c2
-rw-r--r--net/packet/af_packet.c5
-rw-r--r--net/rfkill/core.c1
-rw-r--r--net/rose/rose_route.c16
-rw-r--r--net/sched/act_pedit.c2
-rw-r--r--net/sched/cls_api.c2
-rw-r--r--net/sctp/associola.c4
-rw-r--r--net/sctp/outqueue.c10
-rw-r--r--net/sctp/sm_sideeffect.c1
-rw-r--r--net/sctp/sm_statefuns.c15
-rw-r--r--net/sctp/socket.c40
-rw-r--r--net/sctp/transport.c8
-rw-r--r--net/sunrpc/addr.c18
-rw-r--r--net/sunrpc/svcsock.c10
-rw-r--r--net/unix/af_unix.c2
-rw-r--r--net/wireless/core.h1
-rw-r--r--net/wireless/mlme.c9
-rw-r--r--net/wireless/nl80211.c3
-rw-r--r--net/wireless/sme.c24
-rw-r--r--samples/Kconfig6
-rw-r--r--samples/Makefile3
-rw-r--r--samples/hw_breakpoint/Makefile1
-rw-r--r--samples/hw_breakpoint/data_breakpoint.c87
-rwxr-xr-xscripts/checkpatch.pl84
-rw-r--r--scripts/dtc/data.c2
-rw-r--r--scripts/dtc/dtc-lexer.l2
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped69
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c2
-rw-r--r--scripts/dtc/treesource.c2
-rw-r--r--scripts/genksyms/keywords.c_shipped95
-rw-r--r--scripts/genksyms/keywords.gperf2
-rwxr-xr-xscripts/get_maintainer.pl41
-rw-r--r--scripts/kconfig/Makefile4
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped25
-rw-r--r--scripts/kconfig/streamline_config.pl12
-rw-r--r--scripts/kconfig/zconf.gperf2
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped2
-rw-r--r--scripts/kconfig/zconf.l6
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped379
-rw-r--r--scripts/kconfig/zconf.y13
-rwxr-xr-xscripts/kernel-doc15
-rwxr-xr-xscripts/recordmcount.pl219
-rw-r--r--scripts/selinux/Makefile4
-rw-r--r--scripts/selinux/genheaders/.gitignore1
-rw-r--r--scripts/selinux/genheaders/Makefile5
-rw-r--r--scripts/selinux/genheaders/genheaders.c118
-rw-r--r--scripts/selinux/mdp/mdp.c151
-rw-r--r--security/Kconfig54
-rw-r--r--security/Makefile1
-rw-r--r--security/capability.c21
-rw-r--r--security/commoncap.c74
-rw-r--r--security/integrity/ima/Kconfig1
-rw-r--r--security/integrity/ima/ima_iint.c4
-rw-r--r--security/keys/keyctl.c2
-rw-r--r--security/lsm_audit.c4
-rw-r--r--security/min_addr.c3
-rw-r--r--security/root_plug.c90
-rw-r--r--security/security.c61
-rw-r--r--security/selinux/.gitignore2
-rw-r--r--security/selinux/Makefile10
-rw-r--r--security/selinux/avc.c78
-rw-r--r--security/selinux/hooks.c25
-rw-r--r--security/selinux/include/av_inherit.h34
-rw-r--r--security/selinux/include/av_perm_to_string.h183
-rw-r--r--security/selinux/include/av_permissions.h870
-rw-r--r--security/selinux/include/avc_ss.h21
-rw-r--r--security/selinux/include/class_to_string.h80
-rw-r--r--security/selinux/include/classmap.h150
-rw-r--r--security/selinux/include/common_perm_to_string.h58
-rw-r--r--security/selinux/include/flask.h91
-rw-r--r--security/selinux/include/security.h13
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--security/selinux/ss/Makefile2
-rw-r--r--security/selinux/ss/mls.c2
-rw-r--r--security/selinux/ss/policydb.c47
-rw-r--r--security/selinux/ss/policydb.h7
-rw-r--r--security/selinux/ss/services.c562
-rw-r--r--security/tomoyo/common.c200
-rw-r--r--security/tomoyo/common.h4
-rw-r--r--security/tomoyo/realpath.c13
-rw-r--r--sound/arm/aaci.c6
-rw-r--r--sound/core/pcm.c5
-rw-r--r--sound/core/rawmidi.c42
-rw-r--r--sound/drivers/dummy.c4
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c65
-rw-r--r--sound/drivers/pcsp/pcsp_mixer.c2
-rw-r--r--sound/oss/dmasound/dmasound_core.c4
-rw-r--r--sound/oss/hex2hex.c2
-rw-r--r--sound/oss/sb_common.c4
-rw-r--r--sound/oss/sb_ess.c2
-rw-r--r--sound/parisc/harmony.c6
-rw-r--r--sound/pci/Kconfig1
-rw-r--r--sound/pci/ali5451/ali5451.c2
-rw-r--r--sound/pci/hda/hda_intel.c13
-rw-r--r--sound/pci/hda/patch_conexant.c16
-rw-r--r--sound/pci/hda/patch_nvhdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c24
-rw-r--r--sound/pci/hda/patch_sigmatel.c70
-rw-r--r--sound/pci/ice1712/ice1712.h4
-rw-r--r--sound/pci/ice1712/prodigy_hifi.c2
-rw-r--r--sound/pci/intel8x0.c6
-rw-r--r--sound/pci/via82xx.c59
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c27
-rw-r--r--sound/pcmcia/vx/vxpocket.c27
-rw-r--r--sound/ppc/Kconfig2
-rw-r--r--sound/sh/aica.c1
-rw-r--r--sound/soc/codecs/tlv320aic23.c5
-rw-r--r--sound/soc/omap/Kconfig13
-rw-r--r--sound/soc/omap/omap-pcm.c8
-rw-r--r--sound/soc/omap/omap3evm.c2
-rw-r--r--sound/soc/omap/omap3pandora.c3
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c17
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c2
-rw-r--r--sound/soc/soc-core.c11
-rw-r--r--sound/soc/soc-dapm.c22
-rw-r--r--sound/usb/caiaq/audio.c16
-rw-r--r--sound/usb/caiaq/device.c2
-rw-r--r--sound/usb/usbaudio.h2
-rw-r--r--sound/usb/usbmixer.c9
-rw-r--r--tools/perf/.gitignore1
-rw-r--r--tools/perf/Documentation/perf-bench.txt120
-rw-r--r--tools/perf/Documentation/perf-buildid-list.txt34
-rw-r--r--tools/perf/Documentation/perf-kmem.txt44
-rw-r--r--tools/perf/Documentation/perf-probe.txt49
-rw-r--r--tools/perf/Documentation/perf-record.txt16
-rw-r--r--tools/perf/Documentation/perf-report.txt8
-rw-r--r--tools/perf/Documentation/perf-timechart.txt5
-rw-r--r--tools/perf/Documentation/perf-trace-perl.txt219
-rw-r--r--tools/perf/Documentation/perf-trace.txt11
-rw-r--r--tools/perf/Makefile151
-rw-r--r--tools/perf/bench/bench.h17
-rw-r--r--tools/perf/bench/mem-memcpy.c193
-rw-r--r--tools/perf/bench/sched-messaging.c336
-rw-r--r--tools/perf/bench/sched-pipe.c124
-rw-r--r--tools/perf/builtin-annotate.c885
-rw-r--r--tools/perf/builtin-bench.c196
-rw-r--r--tools/perf/builtin-buildid-list.c116
-rw-r--r--tools/perf/builtin-help.c16
-rw-r--r--tools/perf/builtin-kmem.c807
-rw-r--r--tools/perf/builtin-probe.c242
-rw-r--r--tools/perf/builtin-record.c347
-rw-r--r--tools/perf/builtin-report.c1147
-rw-r--r--tools/perf/builtin-sched.c355
-rw-r--r--tools/perf/builtin-stat.c34
-rw-r--r--tools/perf/builtin-timechart.c295
-rw-r--r--tools/perf/builtin-top.c507
-rw-r--r--tools/perf/builtin-trace.c418
-rw-r--r--tools/perf/builtin.h4
-rw-r--r--tools/perf/command-list.txt4
-rw-r--r--tools/perf/design.txt2
-rw-r--r--tools/perf/perf.c86
-rw-r--r--tools/perf/perf.h12
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/Context.c134
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/Context.xs41
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL17
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/README59
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm55
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm192
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm88
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/typemap1
-rw-r--r--tools/perf/scripts/perl/bin/check-perf-trace-record7
-rw-r--r--tools/perf/scripts/perl/bin/check-perf-trace-report5
-rw-r--r--tools/perf/scripts/perl/bin/rw-by-file-record2
-rw-r--r--tools/perf/scripts/perl/bin/rw-by-file-report5
-rw-r--r--tools/perf/scripts/perl/bin/rw-by-pid-record2
-rw-r--r--tools/perf/scripts/perl/bin/rw-by-pid-report5
-rw-r--r--tools/perf/scripts/perl/bin/wakeup-latency-record6
-rw-r--r--tools/perf/scripts/perl/bin/wakeup-latency-report5
-rw-r--r--tools/perf/scripts/perl/bin/workqueue-stats-record2
-rw-r--r--tools/perf/scripts/perl/bin/workqueue-stats-report6
-rw-r--r--tools/perf/scripts/perl/check-perf-trace.pl106
-rw-r--r--tools/perf/scripts/perl/rw-by-file.pl105
-rw-r--r--tools/perf/scripts/perl/rw-by-pid.pl170
-rw-r--r--tools/perf/scripts/perl/wakeup-latency.pl103
-rw-r--r--tools/perf/scripts/perl/workqueue-stats.pl129
-rwxr-xr-xtools/perf/util/PERF-VERSION-GEN2
-rw-r--r--tools/perf/util/cache.h11
-rw-r--r--tools/perf/util/callchain.c2
-rw-r--r--tools/perf/util/callchain.h2
-rw-r--r--tools/perf/util/color.h6
-rw-r--r--tools/perf/util/ctype.c8
-rw-r--r--tools/perf/util/data_map.c291
-rw-r--r--tools/perf/util/data_map.h32
-rw-r--r--tools/perf/util/debug.c4
-rw-r--r--tools/perf/util/debug.h9
-rw-r--r--tools/perf/util/debugfs.c241
-rw-r--r--tools/perf/util/debugfs.h25
-rw-r--r--tools/perf/util/event.c312
-rw-r--r--tools/perf/util/event.h75
-rw-r--r--tools/perf/util/exec_cmd.h6
-rw-r--r--tools/perf/util/header.c403
-rw-r--r--tools/perf/util/header.h76
-rw-r--r--tools/perf/util/help.h6
-rw-r--r--tools/perf/util/hist.c202
-rw-r--r--tools/perf/util/hist.h50
-rw-r--r--tools/perf/util/include/asm/asm-offsets.h1
-rw-r--r--tools/perf/util/include/asm/bitops.h18
-rw-r--r--tools/perf/util/include/asm/bug.h22
-rw-r--r--tools/perf/util/include/asm/byteorder.h2
-rw-r--r--tools/perf/util/include/asm/swab.h1
-rw-r--r--tools/perf/util/include/asm/uaccess.h14
-rw-r--r--tools/perf/util/include/linux/bitmap.h3
-rw-r--r--tools/perf/util/include/linux/bitops.h29
-rw-r--r--tools/perf/util/include/linux/compiler.h10
-rw-r--r--tools/perf/util/include/linux/ctype.h1
-rw-r--r--tools/perf/util/include/linux/kernel.h76
-rw-r--r--tools/perf/util/include/linux/string.h1
-rw-r--r--tools/perf/util/include/linux/types.h9
-rw-r--r--tools/perf/util/levenshtein.h6
-rw-r--r--tools/perf/util/map.c99
-rw-r--r--tools/perf/util/module.c545
-rw-r--r--tools/perf/util/module.h53
-rw-r--r--tools/perf/util/parse-events.c160
-rw-r--r--tools/perf/util/parse-events.h8
-rw-r--r--tools/perf/util/parse-options.h6
-rw-r--r--tools/perf/util/probe-event.c484
-rw-r--r--tools/perf/util/probe-event.h18
-rw-r--r--tools/perf/util/probe-finder.c732
-rw-r--r--tools/perf/util/probe-finder.h57
-rw-r--r--tools/perf/util/quote.h6
-rw-r--r--tools/perf/util/run-command.h6
-rw-r--r--tools/perf/util/sigchain.h6
-rw-r--r--tools/perf/util/sort.c290
-rw-r--r--tools/perf/util/sort.h99
-rw-r--r--tools/perf/util/strbuf.h6
-rw-r--r--tools/perf/util/string.c194
-rw-r--r--tools/perf/util/string.h10
-rw-r--r--tools/perf/util/strlist.h6
-rw-r--r--tools/perf/util/svghelper.c2
-rw-r--r--tools/perf/util/svghelper.h6
-rw-r--r--tools/perf/util/symbol.c1199
-rw-r--r--tools/perf/util/symbol.h102
-rw-r--r--tools/perf/util/thread.c250
-rw-r--r--tools/perf/util/thread.h50
-rw-r--r--tools/perf/util/trace-event-info.c26
-rw-r--r--tools/perf/util/trace-event-parse.c581
-rw-r--r--tools/perf/util/trace-event-perl.c598
-rw-r--r--tools/perf/util/trace-event-perl.h51
-rw-r--r--tools/perf/util/trace-event-read.c11
-rw-r--r--tools/perf/util/trace-event.h64
-rw-r--r--tools/perf/util/types.h6
-rw-r--r--tools/perf/util/util.h31
-rw-r--r--tools/perf/util/values.h6
-rw-r--r--tools/perf/util/wrapper.c61
-rw-r--r--virt/kvm/kvm_main.c7
1984 files changed, 65690 insertions, 30270 deletions
diff --git a/.gitignore b/.gitignore
index b93fb7eff942..946c7ec5c922 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@
*.elf
*.bin
*.gz
+*.bz2
*.lzma
*.patch
*.gcno
diff --git a/Documentation/ABI/testing/sysfs-class-usb_host b/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
index 46b66ad1f1b4..4e8106f7cfd9 100644
--- a/Documentation/ABI/testing/sysfs-class-usb_host
+++ b/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
@@ -1,4 +1,4 @@
-What: /sys/class/usb_host/usb_hostN/wusb_chid
+What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_chid
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
@@ -9,7 +9,7 @@ Description:
Set an all zero CHID to stop the host controller.
-What: /sys/class/usb_host/usb_hostN/wusb_trust_timeout
+What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_trust_timeout
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
diff --git a/Documentation/ABI/testing/sysfs-devices-cache_disable b/Documentation/ABI/testing/sysfs-devices-cache_disable
deleted file mode 100644
index 175bb4f70512..000000000000
--- a/Documentation/ABI/testing/sysfs-devices-cache_disable
+++ /dev/null
@@ -1,18 +0,0 @@
-What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
-Date: August 2008
-KernelVersion: 2.6.27
-Contact: mark.langsdorf@amd.com
-Description: These files exist in every cpu's cache index directories.
- There are currently 2 cache_disable_# files in each
- directory. Reading from these files on a supported
- processor will return that cache disable index value
- for that processor and node. Writing to one of these
- files will cause the specificed cache index to be disabled.
-
- Currently, only AMD Family 10h Processors support cache index
- disable, and only for their L3 caches. See the BIOS and
- Kernel Developer's Guide at
- http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf
- for formatting information and other details on the
- cache index disable.
-Users: joachim.deguara@amd.com
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
new file mode 100644
index 000000000000..a703b9e9aeb9
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -0,0 +1,156 @@
+What: /sys/devices/system/cpu/
+Date: pre-git history
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description:
+ A collection of both global and individual CPU attributes
+
+ Individual CPU attributes are contained in subdirectories
+ named by the kernel's logical CPU number, e.g.:
+
+ /sys/devices/system/cpu/cpu#/
+
+What: /sys/devices/system/cpu/sched_mc_power_savings
+ /sys/devices/system/cpu/sched_smt_power_savings
+Date: June 2006
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description: Discover and adjust the kernel's multi-core scheduler support.
+
+ Possible values are:
+
+ 0 - No power saving load balance (default value)
+ 1 - Fill one thread/core/package first for long running threads
+ 2 - Also bias task wakeups to semi-idle cpu package for power
+ savings
+
+ sched_mc_power_savings is dependent upon SCHED_MC, which is
+ itself architecture dependent.
+
+ sched_smt_power_savings is dependent upon SCHED_SMT, which
+ is itself architecture dependent.
+
+ The two files are independent of each other. It is possible
+ that one file may be present without the other.
+
+ Introduced by git commit 5c45bf27.
+
+
+What: /sys/devices/system/cpu/kernel_max
+ /sys/devices/system/cpu/offline
+ /sys/devices/system/cpu/online
+ /sys/devices/system/cpu/possible
+ /sys/devices/system/cpu/present
+Date: December 2008
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description: CPU topology files that describe kernel limits related to
+ hotplug. Briefly:
+
+ kernel_max: the maximum cpu index allowed by the kernel
+ configuration.
+
+ offline: cpus that are not online because they have been
+ HOTPLUGGED off or exceed the limit of cpus allowed by the
+ kernel configuration (kernel_max above).
+
+ online: cpus that are online and being scheduled.
+
+ possible: cpus that have been allocated resources and can be
+ brought online if they are present.
+
+ present: cpus that have been identified as being present in
+ the system.
+
+ See Documentation/cputopology.txt for more information.
+
+
+
+What: /sys/devices/system/cpu/cpu#/node
+Date: October 2009
+Contact: Linux memory management mailing list <linux-mm@kvack.org>
+Description: Discover NUMA node a CPU belongs to
+
+ When CONFIG_NUMA is enabled, a symbolic link that points
+ to the corresponding NUMA node directory.
+
+ For example, the following symlink is created for cpu42
+ in NUMA node 2:
+
+ /sys/devices/system/cpu/cpu42/node2 -> ../../node/node2
+
+
+What: /sys/devices/system/cpu/cpu#/topology/core_id
+ /sys/devices/system/cpu/cpu#/topology/core_siblings
+ /sys/devices/system/cpu/cpu#/topology/core_siblings_list
+ /sys/devices/system/cpu/cpu#/topology/physical_package_id
+ /sys/devices/system/cpu/cpu#/topology/thread_siblings
+ /sys/devices/system/cpu/cpu#/topology/thread_siblings_list
+Date: December 2008
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description: CPU topology files that describe a logical CPU's relationship
+ to other cores and threads in the same physical package.
+
+ One cpu# directory is created per logical CPU in the system,
+ e.g. /sys/devices/system/cpu/cpu42/.
+
+ Briefly, the files above are:
+
+ core_id: the CPU core ID of cpu#. Typically it is the
+ hardware platform's identifier (rather than the kernel's).
+ The actual value is architecture and platform dependent.
+
+ core_siblings: internal kernel map of cpu#'s hardware threads
+ within the same physical_package_id.
+
+ core_siblings_list: human-readable list of the logical CPU
+ numbers within the same physical_package_id as cpu#.
+
+ physical_package_id: physical package id of cpu#. Typically
+ corresponds to a physical socket number, but the actual value
+ is architecture and platform dependent.
+
+ thread_siblings: internel kernel map of cpu#'s hardware
+ threads within the same core as cpu#
+
+ thread_siblings_list: human-readable list of cpu#'s hardware
+ threads within the same core as cpu#
+
+ See Documentation/cputopology.txt for more information.
+
+
+What: /sys/devices/system/cpu/cpuidle/current_driver
+ /sys/devices/system/cpu/cpuidle/current_governer_ro
+Date: September 2007
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description: Discover cpuidle policy and mechanism
+
+ Various CPUs today support multiple idle levels that are
+ differentiated by varying exit latencies and power
+ consumption during idle.
+
+ Idle policy (governor) is differentiated from idle mechanism
+ (driver)
+
+ current_driver: displays current idle mechanism
+
+ current_governor_ro: displays current idle policy
+
+ See files in Documentation/cpuidle/ for more information.
+
+
+What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
+Date: August 2008
+KernelVersion: 2.6.27
+Contact: mark.langsdorf@amd.com
+Description: These files exist in every cpu's cache index directories.
+ There are currently 2 cache_disable_# files in each
+ directory. Reading from these files on a supported
+ processor will return that cache disable index value
+ for that processor and node. Writing to one of these
+ files will cause the specificed cache index to be disabled.
+
+ Currently, only AMD Family 10h Processors support cache index
+ disable, and only for their L3 caches. See the BIOS and
+ Kernel Developer's Guide at
+ http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf
+ for formatting information and other details on the
+ cache index disable.
+Users: joachim.deguara@amd.com
diff --git a/Documentation/DocBook/tracepoint.tmpl b/Documentation/DocBook/tracepoint.tmpl
index b0756d0fd579..8bca1d5cec09 100644
--- a/Documentation/DocBook/tracepoint.tmpl
+++ b/Documentation/DocBook/tracepoint.tmpl
@@ -86,4 +86,9 @@
!Iinclude/trace/events/irq.h
</chapter>
+ <chapter id="signal">
+ <title>SIGNAL</title>
+!Iinclude/trace/events/signal.h
+ </chapter>
+
</book>
diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt
index 187bbf10c923..8608fd85e921 100644
--- a/Documentation/RCU/trace.txt
+++ b/Documentation/RCU/trace.txt
@@ -1,185 +1,10 @@
CONFIG_RCU_TRACE debugfs Files and Formats
-The rcupreempt and rcutree implementations of RCU provide debugfs trace
-output that summarizes counters and state. This information is useful for
-debugging RCU itself, and can sometimes also help to debug abuses of RCU.
-Note that the rcuclassic implementation of RCU does not provide debugfs
-trace output.
-
-The following sections describe the debugfs files and formats for
-preemptable RCU (rcupreempt) and hierarchical RCU (rcutree).
-
-
-Preemptable RCU debugfs Files and Formats
-
-This implementation of RCU provides three debugfs files under the
-top-level directory RCU: rcu/rcuctrs (which displays the per-CPU
-counters used by preemptable RCU) rcu/rcugp (which displays grace-period
-counters), and rcu/rcustats (which internal counters for debugging RCU).
-
-The output of "cat rcu/rcuctrs" looks as follows:
-
-CPU last cur F M
- 0 5 -5 0 0
- 1 -1 0 0 0
- 2 0 1 0 0
- 3 0 1 0 0
- 4 0 1 0 0
- 5 0 1 0 0
- 6 0 2 0 0
- 7 0 -1 0 0
- 8 0 1 0 0
-ggp = 26226, state = waitzero
-
-The per-CPU fields are as follows:
-
-o "CPU" gives the CPU number. Offline CPUs are not displayed.
-
-o "last" gives the value of the counter that is being decremented
- for the current grace period phase. In the example above,
- the counters sum to 4, indicating that there are still four
- RCU read-side critical sections still running that started
- before the last counter flip.
-
-o "cur" gives the value of the counter that is currently being
- both incremented (by rcu_read_lock()) and decremented (by
- rcu_read_unlock()). In the example above, the counters sum to
- 1, indicating that there is only one RCU read-side critical section
- still running that started after the last counter flip.
-
-o "F" indicates whether RCU is waiting for this CPU to acknowledge
- a counter flip. In the above example, RCU is not waiting on any,
- which is consistent with the state being "waitzero" rather than
- "waitack".
-
-o "M" indicates whether RCU is waiting for this CPU to execute a
- memory barrier. In the above example, RCU is not waiting on any,
- which is consistent with the state being "waitzero" rather than
- "waitmb".
-
-o "ggp" is the global grace-period counter.
-
-o "state" is the RCU state, which can be one of the following:
-
- o "idle": there is no grace period in progress.
-
- o "waitack": RCU just incremented the global grace-period
- counter, which has the effect of reversing the roles of
- the "last" and "cur" counters above, and is waiting for
- all the CPUs to acknowledge the flip. Once the flip has
- been acknowledged, CPUs will no longer be incrementing
- what are now the "last" counters, so that their sum will
- decrease monotonically down to zero.
-
- o "waitzero": RCU is waiting for the sum of the "last" counters
- to decrease to zero.
-
- o "waitmb": RCU is waiting for each CPU to execute a memory
- barrier, which ensures that instructions from a given CPU's
- last RCU read-side critical section cannot be reordered
- with instructions following the memory-barrier instruction.
-
-The output of "cat rcu/rcugp" looks as follows:
-
-oldggp=48870 newggp=48873
-
-Note that reading from this file provokes a synchronize_rcu(). The
-"oldggp" value is that of "ggp" from rcu/rcuctrs above, taken before
-executing the synchronize_rcu(), and the "newggp" value is also the
-"ggp" value, but taken after the synchronize_rcu() command returns.
-
-
-The output of "cat rcu/rcugp" looks as follows:
-
-na=1337955 nl=40 wa=1337915 wl=44 da=1337871 dl=0 dr=1337871 di=1337871
-1=50989 e1=6138 i1=49722 ie1=82 g1=49640 a1=315203 ae1=265563 a2=49640
-z1=1401244 ze1=1351605 z2=49639 m1=5661253 me1=5611614 m2=49639
-
-These are counters tracking internal preemptable-RCU events, however,
-some of them may be useful for debugging algorithms using RCU. In
-particular, the "nl", "wl", and "dl" values track the number of RCU
-callbacks in various states. The fields are as follows:
-
-o "na" is the total number of RCU callbacks that have been enqueued
- since boot.
-
-o "nl" is the number of RCU callbacks waiting for the previous
- grace period to end so that they can start waiting on the next
- grace period.
-
-o "wa" is the total number of RCU callbacks that have started waiting
- for a grace period since boot. "na" should be roughly equal to
- "nl" plus "wa".
-
-o "wl" is the number of RCU callbacks currently waiting for their
- grace period to end.
-
-o "da" is the total number of RCU callbacks whose grace periods
- have completed since boot. "wa" should be roughly equal to
- "wl" plus "da".
-
-o "dr" is the total number of RCU callbacks that have been removed
- from the list of callbacks ready to invoke. "dr" should be roughly
- equal to "da".
-
-o "di" is the total number of RCU callbacks that have been invoked
- since boot. "di" should be roughly equal to "da", though some
- early versions of preemptable RCU had a bug so that only the
- last CPU's count of invocations was displayed, rather than the
- sum of all CPU's counts.
-
-o "1" is the number of calls to rcu_try_flip(). This should be
- roughly equal to the sum of "e1", "i1", "a1", "z1", and "m1"
- described below. In other words, the number of times that
- the state machine is visited should be equal to the sum of the
- number of times that each state is visited plus the number of
- times that the state-machine lock acquisition failed.
-
-o "e1" is the number of times that rcu_try_flip() was unable to
- acquire the fliplock.
-
-o "i1" is the number of calls to rcu_try_flip_idle().
-
-o "ie1" is the number of times rcu_try_flip_idle() exited early
- due to the calling CPU having no work for RCU.
-
-o "g1" is the number of times that rcu_try_flip_idle() decided
- to start a new grace period. "i1" should be roughly equal to
- "ie1" plus "g1".
-
-o "a1" is the number of calls to rcu_try_flip_waitack().
-
-o "ae1" is the number of times that rcu_try_flip_waitack() found
- that at least one CPU had not yet acknowledge the new grace period
- (AKA "counter flip").
-
-o "a2" is the number of time rcu_try_flip_waitack() found that
- all CPUs had acknowledged. "a1" should be roughly equal to
- "ae1" plus "a2". (This particular output was collected on
- a 128-CPU machine, hence the smaller-than-usual fraction of
- calls to rcu_try_flip_waitack() finding all CPUs having already
- acknowledged.)
-
-o "z1" is the number of calls to rcu_try_flip_waitzero().
-
-o "ze1" is the number of times that rcu_try_flip_waitzero() found
- that not all of the old RCU read-side critical sections had
- completed.
-
-o "z2" is the number of times that rcu_try_flip_waitzero() finds
- the sum of the counters equal to zero, in other words, that
- all of the old RCU read-side critical sections had completed.
- The value of "z1" should be roughly equal to "ze1" plus
- "z2".
-
-o "m1" is the number of calls to rcu_try_flip_waitmb().
-
-o "me1" is the number of times that rcu_try_flip_waitmb() finds
- that at least one CPU has not yet executed a memory barrier.
-
-o "m2" is the number of times that rcu_try_flip_waitmb() finds that
- all CPUs have executed a memory barrier.
+The rcutree implementation of RCU provides debugfs trace output that
+summarizes counters and state. This information is useful for debugging
+RCU itself, and can sometimes also help to debug abuses of RCU.
+The following sections describe the debugfs files and formats.
Hierarchical RCU debugfs Files and Formats
@@ -210,9 +35,10 @@ rcu_bh:
6 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=859/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
7 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3761/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
-The first section lists the rcu_data structures for rcu, the second for
-rcu_bh. Each section has one line per CPU, or eight for this 8-CPU system.
-The fields are as follows:
+The first section lists the rcu_data structures for rcu_sched, the second
+for rcu_bh. Note that CONFIG_TREE_PREEMPT_RCU kernels will have an
+additional section for rcu_preempt. Each section has one line per CPU,
+or eight for this 8-CPU system. The fields are as follows:
o The number at the beginning of each line is the CPU number.
CPUs numbers followed by an exclamation mark are offline,
@@ -223,9 +49,9 @@ o The number at the beginning of each line is the CPU number.
o "c" is the count of grace periods that this CPU believes have
completed. CPUs in dynticks idle mode may lag quite a ways
- behind, for example, CPU 4 under "rcu" above, which has slept
- through the past 25 RCU grace periods. It is not unusual to
- see CPUs lagging by thousands of grace periods.
+ behind, for example, CPU 4 under "rcu_sched" above, which has
+ slept through the past 25 RCU grace periods. It is not unusual
+ to see CPUs lagging by thousands of grace periods.
o "g" is the count of grace periods that this CPU believes have
started. Again, CPUs in dynticks idle mode may lag behind.
@@ -308,8 +134,10 @@ The output of "cat rcu/rcugp" looks as follows:
rcu_sched: completed=33062 gpnum=33063
rcu_bh: completed=464 gpnum=464
-Again, this output is for both "rcu" and "rcu_bh". The fields are
-taken from the rcu_state structure, and are as follows:
+Again, this output is for both "rcu_sched" and "rcu_bh". Note that
+kernels built with CONFIG_TREE_PREEMPT_RCU will have an additional
+"rcu_preempt" line. The fields are taken from the rcu_state structure,
+and are as follows:
o "completed" is the number of grace periods that have completed.
It is comparable to the "c" field from rcu/rcudata in that a
@@ -324,23 +152,24 @@ o "gpnum" is the number of grace periods that have started. It is
If these two fields are equal (as they are for "rcu_bh" above),
then there is no grace period in progress, in other words, RCU
is idle. On the other hand, if the two fields differ (as they
- do for "rcu" above), then an RCU grace period is in progress.
+ do for "rcu_sched" above), then an RCU grace period is in progress.
The output of "cat rcu/rcuhier" looks as follows, with very long lines:
-c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6
-1/1 0:127 ^0
-3/3 0:35 ^0 0/0 36:71 ^1 0/0 72:107 ^2 0/0 108:127 ^3
-3/3f 0:5 ^0 2/3 6:11 ^1 0/0 12:17 ^2 0/0 18:23 ^3 0/0 24:29 ^4 0/0 30:35 ^5 0/0 36:41 ^0 0/0 42:47 ^1 0/0 48:53 ^2 0/0 54:59 ^3 0/0 60:65 ^4 0/0 66:71 ^5 0/0 72:77 ^0 0/0 78:83 ^1 0/0 84:89 ^2 0/0 90:95 ^3 0/0 96:101 ^4 0/0 102:107 ^5 0/0 108:113 ^0 0/0 114:119 ^1 0/0 120:125 ^2 0/0 126:127 ^3
+c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6 oqlen=0
+1/1 .>. 0:127 ^0
+3/3 .>. 0:35 ^0 0/0 .>. 36:71 ^1 0/0 .>. 72:107 ^2 0/0 .>. 108:127 ^3
+3/3f .>. 0:5 ^0 2/3 .>. 6:11 ^1 0/0 .>. 12:17 ^2 0/0 .>. 18:23 ^3 0/0 .>. 24:29 ^4 0/0 .>. 30:35 ^5 0/0 .>. 36:41 ^0 0/0 .>. 42:47 ^1 0/0 .>. 48:53 ^2 0/0 .>. 54:59 ^3 0/0 .>. 60:65 ^4 0/0 .>. 66:71 ^5 0/0 .>. 72:77 ^0 0/0 .>. 78:83 ^1 0/0 .>. 84:89 ^2 0/0 .>. 90:95 ^3 0/0 .>. 96:101 ^4 0/0 .>. 102:107 ^5 0/0 .>. 108:113 ^0 0/0 .>. 114:119 ^1 0/0 .>. 120:125 ^2 0/0 .>. 126:127 ^3
rcu_bh:
-c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0
-0/1 0:127 ^0
-0/3 0:35 ^0 0/0 36:71 ^1 0/0 72:107 ^2 0/0 108:127 ^3
-0/3f 0:5 ^0 0/3 6:11 ^1 0/0 12:17 ^2 0/0 18:23 ^3 0/0 24:29 ^4 0/0 30:35 ^5 0/0 36:41 ^0 0/0 42:47 ^1 0/0 48:53 ^2 0/0 54:59 ^3 0/0 60:65 ^4 0/0 66:71 ^5 0/0 72:77 ^0 0/0 78:83 ^1 0/0 84:89 ^2 0/0 90:95 ^3 0/0 96:101 ^4 0/0 102:107 ^5 0/0 108:113 ^0 0/0 114:119 ^1 0/0 120:125 ^2 0/0 126:127 ^3
+c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0 oqlen=0
+0/1 .>. 0:127 ^0
+0/3 .>. 0:35 ^0 0/0 .>. 36:71 ^1 0/0 .>. 72:107 ^2 0/0 .>. 108:127 ^3
+0/3f .>. 0:5 ^0 0/3 .>. 6:11 ^1 0/0 .>. 12:17 ^2 0/0 .>. 18:23 ^3 0/0 .>. 24:29 ^4 0/0 .>. 30:35 ^5 0/0 .>. 36:41 ^0 0/0 .>. 42:47 ^1 0/0 .>. 48:53 ^2 0/0 .>. 54:59 ^3 0/0 .>. 60:65 ^4 0/0 .>. 66:71 ^5 0/0 .>. 72:77 ^0 0/0 .>. 78:83 ^1 0/0 .>. 84:89 ^2 0/0 .>. 90:95 ^3 0/0 .>. 96:101 ^4 0/0 .>. 102:107 ^5 0/0 .>. 108:113 ^0 0/0 .>. 114:119 ^1 0/0 .>. 120:125 ^2 0/0 .>. 126:127 ^3
-This is once again split into "rcu" and "rcu_bh" portions. The fields are
-as follows:
+This is once again split into "rcu_sched" and "rcu_bh" portions,
+and CONFIG_TREE_PREEMPT_RCU kernels will again have an additional
+"rcu_preempt" section. The fields are as follows:
o "c" is exactly the same as "completed" under rcu/rcugp.
@@ -372,6 +201,11 @@ o "fqlh" is the number of calls to force_quiescent_state() that
exited immediately (without even being counted in nfqs above)
due to contention on ->fqslock.
+o "oqlen" is the number of callbacks on the "orphan" callback
+ list. RCU callbacks are placed on this list by CPUs going
+ offline, and are "adopted" either by the CPU helping the outgoing
+ CPU or by the next rcu_barrier*() call, whichever comes first.
+
o Each element of the form "1/1 0:127 ^0" represents one struct
rcu_node. Each line represents one level of the hierarchy, from
root to leaves. It is best to think of the rcu_data structures
@@ -379,7 +213,7 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
might be either one, two, or three levels of rcu_node structures,
depending on the relationship between CONFIG_RCU_FANOUT and
CONFIG_NR_CPUS.
-
+
o The numbers separated by the "/" are the qsmask followed
by the qsmaskinit. The qsmask will have one bit
set for each entity in the next lower level that
@@ -389,10 +223,19 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
The value of qsmaskinit is assigned to that of qsmask
at the beginning of each grace period.
- For example, for "rcu", the qsmask of the first entry
- of the lowest level is 0x14, meaning that we are still
- waiting for CPUs 2 and 4 to check in for the current
- grace period.
+ For example, for "rcu_sched", the qsmask of the first
+ entry of the lowest level is 0x14, meaning that we
+ are still waiting for CPUs 2 and 4 to check in for the
+ current grace period.
+
+ o The characters separated by the ">" indicate the state
+ of the blocked-tasks lists. A "T" preceding the ">"
+ indicates that at least one task blocked in an RCU
+ read-side critical section blocks the current grace
+ period, while a "." preceding the ">" indicates otherwise.
+ The character following the ">" indicates similarly for
+ the next grace period. A "T" should appear in this
+ field only for rcu-preempt.
o The numbers separated by the ":" are the range of CPUs
served by this struct rcu_node. This can be helpful
@@ -431,8 +274,9 @@ rcu_bh:
6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
-As always, this is once again split into "rcu" and "rcu_bh" portions.
-The fields are as follows:
+As always, this is once again split into "rcu_sched" and "rcu_bh"
+portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
+"rcu_preempt" section. The fields are as follows:
o "np" is the number of times that __rcu_pending() has been invoked
for the corresponding flavor of RCU.
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index e41a7fecf0d3..d542ca243b80 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -830,7 +830,7 @@ sched: Critical sections Grace period Barrier
SRCU: Critical sections Grace period Barrier
srcu_read_lock synchronize_srcu N/A
- srcu_read_unlock
+ srcu_read_unlock synchronize_srcu_expedited
SRCU: Initialization/cleanup
init_srcu_struct
diff --git a/Documentation/cputopology.txt b/Documentation/cputopology.txt
index b41f3e58aefa..f1c5c4bccd3e 100644
--- a/Documentation/cputopology.txt
+++ b/Documentation/cputopology.txt
@@ -1,15 +1,28 @@
-Export cpu topology info via sysfs. Items (attributes) are similar
+Export CPU topology info via sysfs. Items (attributes) are similar
to /proc/cpuinfo.
1) /sys/devices/system/cpu/cpuX/topology/physical_package_id:
-represent the physical package id of cpu X;
+
+ physical package id of cpuX. Typically corresponds to a physical
+ socket number, but the actual value is architecture and platform
+ dependent.
+
2) /sys/devices/system/cpu/cpuX/topology/core_id:
-represent the cpu core id to cpu X;
+
+ the CPU core ID of cpuX. Typically it is the hardware platform's
+ identifier (rather than the kernel's). The actual value is
+ architecture and platform dependent.
+
3) /sys/devices/system/cpu/cpuX/topology/thread_siblings:
-represent the thread siblings to cpu X in the same core;
+
+ internel kernel map of cpuX's hardware threads within the same
+ core as cpuX
+
4) /sys/devices/system/cpu/cpuX/topology/core_siblings:
-represent the thread siblings to cpu X in the same physical package;
+
+ internal kernel map of cpuX's hardware threads within the same
+ physical_package_id.
To implement it in an architecture-neutral way, a new source file,
drivers/base/topology.c, is to export the 4 attributes.
@@ -32,32 +45,32 @@ not defined by include/asm-XXX/topology.h:
3) thread_siblings: just the given CPU
4) core_siblings: just the given CPU
-Additionally, cpu topology information is provided under
+Additionally, CPU topology information is provided under
/sys/devices/system/cpu and includes these files. The internal
source for the output is in brackets ("[]").
- kernel_max: the maximum cpu index allowed by the kernel configuration.
+ kernel_max: the maximum CPU index allowed by the kernel configuration.
[NR_CPUS-1]
- offline: cpus that are not online because they have been
+ offline: CPUs that are not online because they have been
HOTPLUGGED off (see cpu-hotplug.txt) or exceed the limit
- of cpus allowed by the kernel configuration (kernel_max
+ of CPUs allowed by the kernel configuration (kernel_max
above). [~cpu_online_mask + cpus >= NR_CPUS]
- online: cpus that are online and being scheduled [cpu_online_mask]
+ online: CPUs that are online and being scheduled [cpu_online_mask]
- possible: cpus that have been allocated resources and can be
+ possible: CPUs that have been allocated resources and can be
brought online if they are present. [cpu_possible_mask]
- present: cpus that have been identified as being present in the
+ present: CPUs that have been identified as being present in the
system. [cpu_present_mask]
The format for the above output is compatible with cpulist_parse()
[see <linux/cpumask.h>]. Some examples follow.
-In this example, there are 64 cpus in the system but cpus 32-63 exceed
+In this example, there are 64 CPUs in the system but cpus 32-63 exceed
the kernel max which is limited to 0..31 by the NR_CPUS config option
-being 32. Note also that cpus 2 and 4-31 are not online but could be
+being 32. Note also that CPUs 2 and 4-31 are not online but could be
brought online as they are both present and possible.
kernel_max: 31
@@ -67,8 +80,8 @@ brought online as they are both present and possible.
present: 0-31
In this example, the NR_CPUS config option is 128, but the kernel was
-started with possible_cpus=144. There are 4 cpus in the system and cpu2
-was manually taken offline (and is the only cpu that can be brought
+started with possible_cpus=144. There are 4 CPUs in the system and cpu2
+was manually taken offline (and is the only CPU that can be brought
online.)
kernel_max: 127
@@ -78,4 +91,4 @@ online.)
present: 0-3
See cpu-hotplug.txt for the possible_cpus=NUM kernel start parameter
-as well as more information on the various cpumask's.
+as well as more information on the various cpumasks.
diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt
index 59a91e5c6909..611f5a5499b1 100644
--- a/Documentation/debugging-via-ohci1394.txt
+++ b/Documentation/debugging-via-ohci1394.txt
@@ -64,14 +64,14 @@ be used to view the printk buffer of a remote machine, even with live update.
Bernhard Kaindl enhanced firescope to support accessing 64-bit machines
from 32-bit firescope and vice versa:
-- ftp://ftp.suse.de/private/bk/firewire/tools/firescope-0.2.2.tar.bz2
+- http://halobates.de/firewire/firescope-0.2.2.tar.bz2
and he implemented fast system dump (alpha version - read README.txt):
-- ftp://ftp.suse.de/private/bk/firewire/tools/firedump-0.1.tar.bz2
+- http://halobates.de/firewire/firedump-0.1.tar.bz2
There is also a gdb proxy for firewire which allows to use gdb to access
data which can be referenced from symbols found by gdb in vmlinux:
-- ftp://ftp.suse.de/private/bk/firewire/tools/fireproxy-0.33.tar.bz2
+- http://halobates.de/firewire/fireproxy-0.33.tar.bz2
The latest version of this gdb proxy (fireproxy-0.34) can communicate (not
yet stable) with kgdb over an memory-based communication module (kgdbom).
@@ -178,7 +178,7 @@ Step-by-step instructions for using firescope with early OHCI initialization:
Notes
-----
-Documentation and specifications: ftp://ftp.suse.de/private/bk/firewire/docs
+Documentation and specifications: http://halobates.de/firewire/
FireWire is a trademark of Apple Inc. - for more information please refer to:
http://en.wikipedia.org/wiki/FireWire
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index e1efc400bed6..e151b2a36267 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -65,6 +65,7 @@ aicdb.h*
asm-offsets.h
asm_offsets.h
autoconf.h*
+av_permissions.h
bbootsect
bin2c
binkernel.spec
@@ -95,12 +96,14 @@ docproc
elf2ecoff
elfconfig.h*
fixdep
+flask.h
fore200e_mkfirm
fore200e_pca_fw.c*
gconf
gen-devlist
gen_crc32table
gen_init_cpio
+genheaders
genksyms
*_gray256.c
ihex2fw
diff --git a/Documentation/fb/framebuffer.txt b/Documentation/fb/framebuffer.txt
index b3e3a0356839..fe79e3c8847d 100644
--- a/Documentation/fb/framebuffer.txt
+++ b/Documentation/fb/framebuffer.txt
@@ -312,10 +312,8 @@ and to the following documentation:
8. Mailing list
---------------
-There are several frame buffer device related mailing lists at SourceForge:
- - linux-fbdev-announce@lists.sourceforge.net, for announcements,
- - linux-fbdev-user@lists.sourceforge.net, for generic user support,
- - linux-fbdev-devel@lists.sourceforge.net, for project developers.
+There is a frame buffer device related mailing list at kernel.org:
+linux-fbdev@vger.kernel.org.
Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for
subscription information and archive browsing.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 89a47b5aff07..f613df8ec7bf 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,6 +6,21 @@ be removed from this file.
---------------------------
+What: USER_SCHED
+When: 2.6.34
+
+Why: USER_SCHED was implemented as a proof of concept for group scheduling.
+ The effect of USER_SCHED can already be achieved from userspace with
+ the help of libcgroup. The removal of USER_SCHED will also simplify
+ the scheduler code with the removal of one major ifdef. There are also
+ issues USER_SCHED has with USER_NS. A decision was taken not to fix
+ those and instead remove USER_SCHED. Also new group scheduling
+ features will not be implemented for USER_SCHED.
+
+Who: Dhaval Giani <dhaval@linux.vnet.ibm.com>
+
+---------------------------
+
What: PRISM54
When: 2.6.34
@@ -418,6 +433,14 @@ When: 2.6.33
Why: Should be implemented in userspace, policy daemon.
Who: Johannes Berg <johannes@sipsolutions.net>
+---------------------------
+
+What: CONFIG_INOTIFY
+When: 2.6.33
+Why: last user (audit) will be converted to the newer more generic
+ and more easily maintained fsnotify subsystem
+Who: Eric Paris <eparis@redhat.com>
+
----------------------------
What: lock_policy_rwsem_* and unlock_policy_rwsem_* will not be
@@ -451,3 +474,33 @@ Why: OSS sound_core grabs all legacy minors (0-255) of SOUND_MAJOR
will also allow making ALSA OSS emulation independent of
sound_core. The dependency will be broken then too.
Who: Tejun Heo <tj@kernel.org>
+
+----------------------------
+
+What: Support for VMware's guest paravirtuliazation technique [VMI] will be
+ dropped.
+When: 2.6.37 or earlier.
+Why: With the recent innovations in CPU hardware acceleration technologies
+ from Intel and AMD, VMware ran a few experiments to compare these
+ techniques to guest paravirtualization technique on VMware's platform.
+ These hardware assisted virtualization techniques have outperformed the
+ performance benefits provided by VMI in most of the workloads. VMware
+ expects that these hardware features will be ubiquitous in a couple of
+ years, as a result, VMware has started a phased retirement of this
+ feature from the hypervisor. We will be removing this feature from the
+ Kernel too. Right now we are targeting 2.6.37 but can retire earlier if
+ technical reasons (read opportunity to remove major chunk of pvops)
+ arise.
+
+ Please note that VMI has always been an optimization and non-VMI kernels
+ still work fine on VMware's platform.
+ Latest versions of VMware's product which support VMI are,
+ Workstation 7.0 and VSphere 4.0 on ESX side, future maintainence
+ releases for these products will continue supporting VMI.
+
+ For more details about VMI retirement take a look at this,
+ http://blogs.vmware.com/guestosguide/2009/09/vmi-retirement.html
+
+Who: Alok N Kataria <akataria@vmware.com>
+
+----------------------------
diff --git a/Documentation/filesystems/caching/fscache.txt b/Documentation/filesystems/caching/fscache.txt
index 9e94b9491d89..a91e2e2095b0 100644
--- a/Documentation/filesystems/caching/fscache.txt
+++ b/Documentation/filesystems/caching/fscache.txt
@@ -235,6 +235,7 @@ proc files.
neg=N Number of negative lookups made
pos=N Number of positive lookups made
crt=N Number of objects created by lookup
+ tmo=N Number of lookups timed out and requeued
Updates n=N Number of update cookie requests seen
nul=N Number of upd reqs given a NULL parent
run=N Number of upd reqs granted CPU time
@@ -250,8 +251,10 @@ proc files.
ok=N Number of successful alloc reqs
wt=N Number of alloc reqs that waited on lookup completion
nbf=N Number of alloc reqs rejected -ENOBUFS
+ int=N Number of alloc reqs aborted -ERESTARTSYS
ops=N Number of alloc reqs submitted
owt=N Number of alloc reqs waited for CPU time
+ abt=N Number of alloc reqs aborted due to object death
Retrvls n=N Number of retrieval (read) requests seen
ok=N Number of successful retr reqs
wt=N Number of retr reqs that waited on lookup completion
@@ -261,6 +264,7 @@ proc files.
oom=N Number of retr reqs failed -ENOMEM
ops=N Number of retr reqs submitted
owt=N Number of retr reqs waited for CPU time
+ abt=N Number of retr reqs aborted due to object death
Stores n=N Number of storage (write) requests seen
ok=N Number of successful store reqs
agn=N Number of store reqs on a page already pending storage
@@ -268,12 +272,37 @@ proc files.
oom=N Number of store reqs failed -ENOMEM
ops=N Number of store reqs submitted
run=N Number of store reqs granted CPU time
+ pgs=N Number of pages given store req processing time
+ rxd=N Number of store reqs deleted from tracking tree
+ olm=N Number of store reqs over store limit
+ VmScan nos=N Number of release reqs against pages with no pending store
+ gon=N Number of release reqs against pages stored by time lock granted
+ bsy=N Number of release reqs ignored due to in-progress store
+ can=N Number of page stores cancelled due to release req
Ops pend=N Number of times async ops added to pending queues
run=N Number of times async ops given CPU time
enq=N Number of times async ops queued for processing
+ can=N Number of async ops cancelled
+ rej=N Number of async ops rejected due to object lookup/create failure
dfr=N Number of async ops queued for deferred release
rel=N Number of async ops released
gc=N Number of deferred-release async ops garbage collected
+ CacheOp alo=N Number of in-progress alloc_object() cache ops
+ luo=N Number of in-progress lookup_object() cache ops
+ luc=N Number of in-progress lookup_complete() cache ops
+ gro=N Number of in-progress grab_object() cache ops
+ upo=N Number of in-progress update_object() cache ops
+ dro=N Number of in-progress drop_object() cache ops
+ pto=N Number of in-progress put_object() cache ops
+ syn=N Number of in-progress sync_cache() cache ops
+ atc=N Number of in-progress attr_changed() cache ops
+ rap=N Number of in-progress read_or_alloc_page() cache ops
+ ras=N Number of in-progress read_or_alloc_pages() cache ops
+ alp=N Number of in-progress allocate_page() cache ops
+ als=N Number of in-progress allocate_pages() cache ops
+ wrp=N Number of in-progress write_page() cache ops
+ ucp=N Number of in-progress uncache_page() cache ops
+ dsp=N Number of in-progress dissociate_pages() cache ops
(*) /proc/fs/fscache/histogram
@@ -299,6 +328,87 @@ proc files.
jiffy range covered, and the SECS field the equivalent number of seconds.
+===========
+OBJECT LIST
+===========
+
+If CONFIG_FSCACHE_OBJECT_LIST is enabled, the FS-Cache facility will maintain a
+list of all the objects currently allocated and allow them to be viewed
+through:
+
+ /proc/fs/fscache/objects
+
+This will look something like:
+
+ [root@andromeda ~]# head /proc/fs/fscache/objects
+ OBJECT PARENT STAT CHLDN OPS OOP IPR EX READS EM EV F S | NETFS_COOKIE_DEF TY FL NETFS_DATA OBJECT_KEY, AUX_DATA
+ ======== ======== ==== ===== === === === == ===== == == = = | ================ == == ================ ================
+ 17e4b 2 ACTV 0 0 0 0 0 0 7b 4 0 8 | NFS.fh DT 0 ffff88001dd82820 010006017edcf8bbc93b43298fdfbe71e50b57b13a172c0117f38472, e567634700000000000000000000000063f2404a000000000000000000000000c9030000000000000000000063f2404a
+ 1693a 2 ACTV 0 0 0 0 0 0 7b 4 0 8 | NFS.fh DT 0 ffff88002db23380 010006017edcf8bbc93b43298fdfbe71e50b57b1e0162c01a2df0ea6, 420ebc4a000000000000000000000000420ebc4a0000000000000000000000000e1801000000000000000000420ebc4a
+
+where the first set of columns before the '|' describe the object:
+
+ COLUMN DESCRIPTION
+ ======= ===============================================================
+ OBJECT Object debugging ID (appears as OBJ%x in some debug messages)
+ PARENT Debugging ID of parent object
+ STAT Object state
+ CHLDN Number of child objects of this object
+ OPS Number of outstanding operations on this object
+ OOP Number of outstanding child object management operations
+ IPR
+ EX Number of outstanding exclusive operations
+ READS Number of outstanding read operations
+ EM Object's event mask
+ EV Events raised on this object
+ F Object flags
+ S Object slow-work work item flags
+
+and the second set of columns describe the object's cookie, if present:
+
+ COLUMN DESCRIPTION
+ =============== =======================================================
+ NETFS_COOKIE_DEF Name of netfs cookie definition
+ TY Cookie type (IX - index, DT - data, hex - special)
+ FL Cookie flags
+ NETFS_DATA Netfs private data stored in the cookie
+ OBJECT_KEY Object key } 1 column, with separating comma
+ AUX_DATA Object aux data } presence may be configured
+
+The data shown may be filtered by attaching the a key to an appropriate keyring
+before viewing the file. Something like:
+
+ keyctl add user fscache:objlist <restrictions> @s
+
+where <restrictions> are a selection of the following letters:
+
+ K Show hexdump of object key (don't show if not given)
+ A Show hexdump of object aux data (don't show if not given)
+
+and the following paired letters:
+
+ C Show objects that have a cookie
+ c Show objects that don't have a cookie
+ B Show objects that are busy
+ b Show objects that aren't busy
+ W Show objects that have pending writes
+ w Show objects that don't have pending writes
+ R Show objects that have outstanding reads
+ r Show objects that don't have outstanding reads
+ S Show objects that have slow work queued
+ s Show objects that don't have slow work queued
+
+If neither side of a letter pair is given, then both are implied. For example:
+
+ keyctl add user fscache:objlist KB @s
+
+shows objects that are busy, and lists their object keys, but does not dump
+their auxiliary data. It also implies "CcWwRrSs", but as 'B' is given, 'b' is
+not implied.
+
+By default all objects and all fields will be shown.
+
+
=========
DEBUGGING
=========
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
index 2666b1ed5e9e..1902c57b72ef 100644
--- a/Documentation/filesystems/caching/netfs-api.txt
+++ b/Documentation/filesystems/caching/netfs-api.txt
@@ -641,7 +641,7 @@ data file must be retired (see the relinquish cookie function below).
Furthermore, note that this does not cancel the asynchronous read or write
operation started by the read/alloc and write functions, so the page
-invalidation and release functions must use:
+invalidation functions must use:
bool fscache_check_page_write(struct fscache_cookie *cookie,
struct page *page);
@@ -654,6 +654,25 @@ to see if a page is being written to the cache, and:
to wait for it to finish if it is.
+When releasepage() is being implemented, a special FS-Cache function exists to
+manage the heuristics of coping with vmscan trying to eject pages, which may
+conflict with the cache trying to write pages to the cache (which may itself
+need to allocate memory):
+
+ bool fscache_maybe_release_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp);
+
+This takes the netfs cookie, and the page and gfp arguments as supplied to
+releasepage(). It will return false if the page cannot be released yet for
+some reason and if it returns true, the page has been uncached and can now be
+released.
+
+To make a page available for release, this function may wait for an outstanding
+storage request to complete, or it may attempt to cancel the storage request -
+in which case the page will not be stored in the cache this time.
+
+
==========================
INDEX AND DATA FILE UPDATE
==========================
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index bf4f4b7e11b3..6d94e0696f8c 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -134,9 +134,15 @@ ro Mount filesystem read only. Note that ext4 will
mount options "ro,noload" can be used to prevent
writes to the filesystem.
+journal_checksum Enable checksumming of the journal transactions.
+ This will allow the recovery code in e2fsck and the
+ kernel to detect corruption in the kernel. It is a
+ compatible change and will be ignored by older kernels.
+
journal_async_commit Commit block can be written to disk without waiting
for descriptor blocks. If enabled older kernels cannot
- mount the device.
+ mount the device. This will enable 'journal_checksum'
+ internally.
journal=update Update the ext4 file system's journal to the current
format.
diff --git a/Documentation/filesystems/ocfs2.txt b/Documentation/filesystems/ocfs2.txt
index c2a0871280a0..c58b9f5ba002 100644
--- a/Documentation/filesystems/ocfs2.txt
+++ b/Documentation/filesystems/ocfs2.txt
@@ -20,15 +20,16 @@ Lots of code taken from ext3 and other projects.
Authors in alphabetical order:
Joel Becker <joel.becker@oracle.com>
Zach Brown <zach.brown@oracle.com>
-Mark Fasheh <mark.fasheh@oracle.com>
+Mark Fasheh <mfasheh@suse.com>
Kurt Hackel <kurt.hackel@oracle.com>
+Tao Ma <tao.ma@oracle.com>
Sunil Mushran <sunil.mushran@oracle.com>
Manish Singh <manish.singh@oracle.com>
+Tiger Yang <tiger.yang@oracle.com>
Caveats
=======
Features which OCFS2 does not support yet:
- - quotas
- Directory change notification (F_NOTIFY)
- Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
@@ -70,7 +71,6 @@ commit=nrsec (*) Ocfs2 can be told to sync all its data and metadata
performance.
localalloc=8(*) Allows custom localalloc size in MB. If the value is too
large, the fs will silently revert it to the default.
- Localalloc is not enabled for local mounts.
localflocks This disables cluster aware flock.
inode64 Indicates that Ocfs2 is allowed to create inodes at
any location in the filesystem, including those which
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 2c48f945546b..4af0018533f2 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1072,7 +1072,8 @@ second). The meanings of the columns are as follows, from left to right:
- irq: servicing interrupts
- softirq: servicing softirqs
- steal: involuntary wait
-- guest: running a guest
+- guest: running a normal guest
+- guest_nice: running a niced guest
The "intr" line gives counts of interrupts serviced since boot time, for each
of the possible system interrupts. The first column is the total of all
diff --git a/Documentation/flexible-arrays.txt b/Documentation/flexible-arrays.txt
index 84eb26808dee..cb8a3a00cc92 100644
--- a/Documentation/flexible-arrays.txt
+++ b/Documentation/flexible-arrays.txt
@@ -1,5 +1,5 @@
Using flexible arrays in the kernel
-Last updated for 2.6.31
+Last updated for 2.6.32
Jonathan Corbet <corbet@lwn.net>
Large contiguous memory allocations can be unreliable in the Linux kernel.
@@ -40,6 +40,13 @@ argument is passed directly to the internal memory allocation calls. With
the current code, using flags to ask for high memory is likely to lead to
notably unpleasant side effects.
+It is also possible to define flexible arrays at compile time with:
+
+ DEFINE_FLEX_ARRAY(name, element_size, total);
+
+This macro will result in a definition of an array with the given name; the
+element size and total will be checked for validity at compile time.
+
Storing data into a flexible array is accomplished with a call to:
int flex_array_put(struct flex_array *array, unsigned int element_nr,
@@ -76,16 +83,30 @@ particular element has never been allocated.
Note that it is possible to get back a valid pointer for an element which
has never been stored in the array. Memory for array elements is allocated
one page at a time; a single allocation could provide memory for several
-adjacent elements. The flexible array code does not know if a specific
-element has been written; it only knows if the associated memory is
-present. So a flex_array_get() call on an element which was never stored
-in the array has the potential to return a pointer to random data. If the
-caller does not have a separate way to know which elements were actually
-stored, it might be wise, at least, to add GFP_ZERO to the flags argument
-to ensure that all elements are zeroed.
-
-There is no way to remove a single element from the array. It is possible,
-though, to remove all elements with a call to:
+adjacent elements. Flexible array elements are normally initialized to the
+value FLEX_ARRAY_FREE (defined as 0x6c in <linux/poison.h>), so errors
+involving that number probably result from use of unstored array entries.
+Note that, if array elements are allocated with __GFP_ZERO, they will be
+initialized to zero and this poisoning will not happen.
+
+Individual elements in the array can be cleared with:
+
+ int flex_array_clear(struct flex_array *array, unsigned int element_nr);
+
+This function will set the given element to FLEX_ARRAY_FREE and return
+zero. If storage for the indicated element is not allocated for the array,
+flex_array_clear() will return -EINVAL instead. Note that clearing an
+element does not release the storage associated with it; to reduce the
+allocated size of an array, call:
+
+ int flex_array_shrink(struct flex_array *array);
+
+The return value will be the number of pages of memory actually freed.
+This function works by scanning the array for pages containing nothing but
+FLEX_ARRAY_FREE bytes, so (1) it can be expensive, and (2) it will not work
+if the array's pages are allocated with __GFP_ZERO.
+
+It is possible to remove all elements of an array with a call to:
void flex_array_free_parts(struct flex_array *array);
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index dcbd502c8792..82def883361b 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -353,10 +353,20 @@ power[1-*]_average Average power use
Unit: microWatt
RO
-power[1-*]_average_interval Power use averaging interval
+power[1-*]_average_interval Power use averaging interval. A poll
+ notification is sent to this file if the
+ hardware changes the averaging interval.
Unit: milliseconds
RW
+power[1-*]_average_interval_max Maximum power use averaging interval
+ Unit: milliseconds
+ RO
+
+power[1-*]_average_interval_min Minimum power use averaging interval
+ Unit: milliseconds
+ RO
+
power[1-*]_average_highest Historical average maximum power use
Unit: microWatt
RO
@@ -365,6 +375,18 @@ power[1-*]_average_lowest Historical average minimum power use
Unit: microWatt
RO
+power[1-*]_average_max A poll notification is sent to
+ power[1-*]_average when power use
+ rises above this value.
+ Unit: microWatt
+ RW
+
+power[1-*]_average_min A poll notification is sent to
+ power[1-*]_average when power use
+ sinks below this value.
+ Unit: microWatt
+ RW
+
power[1-*]_input Instantaneous power use
Unit: microWatt
RO
@@ -381,6 +403,39 @@ power[1-*]_reset_history Reset input_highest, input_lowest,
average_highest and average_lowest.
WO
+power[1-*]_accuracy Accuracy of the power meter.
+ Unit: Percent
+ RO
+
+power[1-*]_alarm 1 if the system is drawing more power than the
+ cap allows; 0 otherwise. A poll notification is
+ sent to this file when the power use exceeds the
+ cap. This file only appears if the cap is known
+ to be enforced by hardware.
+ RO
+
+power[1-*]_cap If power use rises above this limit, the
+ system should take action to reduce power use.
+ A poll notification is sent to this file if the
+ cap is changed by the hardware. The *_cap
+ files only appear if the cap is known to be
+ enforced by hardware.
+ Unit: microWatt
+ RW
+
+power[1-*]_cap_hyst Margin of hysteresis built around capping and
+ notification.
+ Unit: microWatt
+ RW
+
+power[1-*]_cap_max Maximum cap that can be set.
+ Unit: microWatt
+ RO
+
+power[1-*]_cap_min Minimum cap that can be set.
+ Unit: microWatt
+ RO
+
**********
* Energy *
**********
diff --git a/Documentation/i2c/busses/i2c-piix4 b/Documentation/i2c/busses/i2c-piix4
index c5b37c570554..ac540c71c7eb 100644
--- a/Documentation/i2c/busses/i2c-piix4
+++ b/Documentation/i2c/busses/i2c-piix4
@@ -8,7 +8,7 @@ Supported adapters:
Datasheet: Only available via NDA from ServerWorks
* ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
Datasheet: Not publicly available
- * AMD SB900
+ * AMD Hudson-2
Datasheet: Not publicly available
* Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
Datasheet: Publicly available at the SMSC website http://www.smsc.com
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9107b387e91f..fce5b5e516cc 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -85,7 +85,6 @@ parameter is applicable:
PPT Parallel port support is enabled.
PS2 Appropriate PS/2 support is enabled.
RAM RAM disk support is enabled.
- ROOTPLUG The example Root Plug LSM is enabled.
S390 S390 architecture is enabled.
SCSI Appropriate SCSI support is enabled.
A lot of drivers has their options described inside of
@@ -345,6 +344,15 @@ and is between 256 and 4096 characters. It is defined in the file
Change the amount of debugging information output
when initialising the APIC and IO-APIC components.
+ show_lapic= [APIC,X86] Advanced Programmable Interrupt Controller
+ Limit apic dumping. The parameter defines the maximal
+ number of local apics being dumped. Also it is possible
+ to set it to "all" by meaning -- no limit here.
+ Format: { 1 (default) | 2 | ... | all }.
+ The parameter valid if only apic=debug or
+ apic=verbose is specified.
+ Example: apic=debug show_lapic=all
+
apm= [APM] Advanced Power Management
See header of arch/x86/kernel/apm_32.c.
@@ -779,6 +787,13 @@ and is between 256 and 4096 characters. It is defined in the file
by the set_ftrace_notrace file in the debugfs
tracing directory.
+ ftrace_graph_filter=[function-list]
+ [FTRACE] Limit the top level callers functions traced
+ by the function graph tracer at boot up.
+ function-list is a comma separated list of functions
+ that can be changed at run time by the
+ set_graph_function file in the debugfs tracing directory.
+
gamecon.map[2|3]=
[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
support via parallel port (up to 5 devices per port)
@@ -2032,8 +2047,15 @@ and is between 256 and 4096 characters. It is defined in the file
print-fatal-signals=
[KNL] debug: print fatal signals
- print-fatal-signals=1: print segfault info to
- the kernel console.
+
+ If enabled, warn about various signal handling
+ related application anomalies: too many signals,
+ too many POSIX.1 timers, fatal signals causing a
+ coredump - etc.
+
+ If you hit the warning due to signal overflow,
+ you might want to try "ulimit -i unlimited".
+
default: off.
printk.time= Show timing data prefixed to each printk message line
@@ -2164,15 +2186,6 @@ and is between 256 and 4096 characters. It is defined in the file
Useful for devices that are detected asynchronously
(e.g. USB and MMC devices).
- root_plug.vendor_id=
- [ROOTPLUG] Override the default vendor ID
-
- root_plug.product_id=
- [ROOTPLUG] Override the default product ID
-
- root_plug.debug=
- [ROOTPLUG] Enable debugging output
-
rw [KNL] Mount root device read-write on boot
S [KNL] Run init in single mode
@@ -2182,6 +2195,8 @@ and is between 256 and 4096 characters. It is defined in the file
sbni= [NET] Granch SBNI12 leased line adapter
+ sched_debug [KNL] Enables verbose scheduler debug messages.
+
sc1200wdt= [HW,WDT] SC1200 WDT (watchdog) driver
Format: <io>[,<timeout>[,<isapnp>]]
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index ba9373f82ab5..098de5bce00a 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -42,7 +42,6 @@
#include <signal.h>
#include "linux/lguest_launcher.h"
#include "linux/virtio_config.h"
-#include <linux/virtio_ids.h>
#include "linux/virtio_net.h"
#include "linux/virtio_blk.h"
#include "linux/virtio_console.h"
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 059934363caf..446f43b309df 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,17 @@
This file details changes in 2.6 which affect PCMCIA card driver authors:
+* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
+ Instead of the cs_error() callback or the CS_CHECK() macro, please use
+ Linux-style checking of return values, and -- if necessary -- debug
+ messages using "dev_dbg()" or "pr_debug()".
+
+* New CIS tuple access (as of 2.6.33)
+ Instead of pcmcia_get_{first,next}_tuple(), pcmcia_get_tuple_data() and
+ pcmcia_parse_tuple(), a driver shall use "pcmcia_get_tuple()" if it is
+ only interested in one (raw) tuple, or "pcmcia_loop_tuple()" if it is
+ interested in all tuples of one type. To decode the MAC from CISTPL_FUNCE,
+ a new helper "pcmcia_get_mac_from_cis()" was added.
+
* New configuration loop helper (as of 2.6.28)
By calling pcmcia_loop_config(), a driver can iterate over all available
configuration options. During a driver's probe() phase, one doesn't need
diff --git a/Documentation/slow-work.txt b/Documentation/slow-work.txt
index ebc50f808ea4..9dbf4470c7e1 100644
--- a/Documentation/slow-work.txt
+++ b/Documentation/slow-work.txt
@@ -41,6 +41,13 @@ expand files, provided the time taken to do so isn't too long.
Operations of both types may sleep during execution, thus tying up the thread
loaned to it.
+A further class of work item is available, based on the slow work item class:
+
+ (*) Delayed slow work items.
+
+These are slow work items that have a timer to defer queueing of the item for
+a while.
+
THREAD-TO-CLASS ALLOCATION
--------------------------
@@ -64,9 +71,11 @@ USING SLOW WORK ITEMS
Firstly, a module or subsystem wanting to make use of slow work items must
register its interest:
- int ret = slow_work_register_user();
+ int ret = slow_work_register_user(struct module *module);
-This will return 0 if successful, or a -ve error upon failure.
+This will return 0 if successful, or a -ve error upon failure. The module
+pointer should be the module interested in using this facility (almost
+certainly THIS_MODULE).
Slow work items may then be set up by:
@@ -93,6 +102,10 @@ Slow work items may then be set up by:
or:
+ delayed_slow_work_init(&myitem, &myitem_ops);
+
+ or:
+
vslow_work_init(&myitem, &myitem_ops);
depending on its class.
@@ -102,15 +115,92 @@ A suitably set up work item can then be enqueued for processing:
int ret = slow_work_enqueue(&myitem);
This will return a -ve error if the thread pool is unable to gain a reference
-on the item, 0 otherwise.
+on the item, 0 otherwise, or (for delayed work):
+
+ int ret = delayed_slow_work_enqueue(&myitem, my_jiffy_delay);
The items are reference counted, so there ought to be no need for a flush
-operation. When all a module's slow work items have been processed, and the
+operation. But as the reference counting is optional, means to cancel
+existing work items are also included:
+
+ cancel_slow_work(&myitem);
+ cancel_delayed_slow_work(&myitem);
+
+can be used to cancel pending work. The above cancel function waits for
+existing work to have been executed (or prevent execution of them, depending
+on timing).
+
+
+When all a module's slow work items have been processed, and the
module has no further interest in the facility, it should unregister its
interest:
- slow_work_unregister_user();
+ slow_work_unregister_user(struct module *module);
+
+The module pointer is used to wait for all outstanding work items for that
+module before completing the unregistration. This prevents the put_ref() code
+from being taken away before it completes. module should almost certainly be
+THIS_MODULE.
+
+
+================
+HELPER FUNCTIONS
+================
+
+The slow-work facility provides a function by which it can be determined
+whether or not an item is queued for later execution:
+
+ bool queued = slow_work_is_queued(struct slow_work *work);
+
+If it returns false, then the item is not on the queue (it may be executing
+with a requeue pending). This can be used to work out whether an item on which
+another depends is on the queue, thus allowing a dependent item to be queued
+after it.
+
+If the above shows an item on which another depends not to be queued, then the
+owner of the dependent item might need to wait. However, to avoid locking up
+the threads unnecessarily be sleeping in them, it can make sense under some
+circumstances to return the work item to the queue, thus deferring it until
+some other items have had a chance to make use of the yielded thread.
+
+To yield a thread and defer an item, the work function should simply enqueue
+the work item again and return. However, this doesn't work if there's nothing
+actually on the queue, as the thread just vacated will jump straight back into
+the item's work function, thus busy waiting on a CPU.
+
+Instead, the item should use the thread to wait for the dependency to go away,
+but rather than using schedule() or schedule_timeout() to sleep, it should use
+the following function:
+
+ bool requeue = slow_work_sleep_till_thread_needed(
+ struct slow_work *work,
+ signed long *_timeout);
+
+This will add a second wait and then sleep, such that it will be woken up if
+either something appears on the queue that could usefully make use of the
+thread - and behind which this item can be queued, or if the event the caller
+set up to wait for happens. True will be returned if something else appeared
+on the queue and this work function should perhaps return, of false if
+something else woke it up. The timeout is as for schedule_timeout().
+
+For example:
+
+ wq = bit_waitqueue(&my_flags, MY_BIT);
+ init_wait(&wait);
+ requeue = false;
+ do {
+ prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
+ if (!test_bit(MY_BIT, &my_flags))
+ break;
+ requeue = slow_work_sleep_till_thread_needed(&my_work,
+ &timeout);
+ } while (timeout > 0 && !requeue);
+ finish_wait(wq, &wait);
+ if (!test_bit(MY_BIT, &my_flags)
+ goto do_my_thing;
+ if (requeue)
+ return; // to slow_work
===============
@@ -118,7 +208,8 @@ ITEM OPERATIONS
===============
Each work item requires a table of operations of type struct slow_work_ops.
-All members are required:
+Only ->execute() is required; the getting and putting of a reference and the
+describing of an item are all optional.
(*) Get a reference on an item:
@@ -148,6 +239,16 @@ All members are required:
This should perform the work required of the item. It may sleep, it may
perform disk I/O and it may wait for locks.
+ (*) View an item through /proc:
+
+ void (*desc)(struct slow_work *work, struct seq_file *m);
+
+ If supplied, this should print to 'm' a small string describing the work
+ the item is to do. This should be no more than about 40 characters, and
+ shouldn't include a newline character.
+
+ See the 'Viewing executing and queued items' section below.
+
==================
POOL CONFIGURATION
@@ -172,3 +273,50 @@ The slow-work thread pool has a number of configurables:
is bounded to between 1 and one fewer than the number of active threads.
This ensures there is always at least one thread that can process very
slow work items, and always at least one thread that won't.
+
+
+==================================
+VIEWING EXECUTING AND QUEUED ITEMS
+==================================
+
+If CONFIG_SLOW_WORK_DEBUG is enabled, a debugfs file is made available:
+
+ /sys/kernel/debug/slow_work/runqueue
+
+through which the list of work items being executed and the queues of items to
+be executed may be viewed. The owner of a work item is given the chance to
+add some information of its own.
+
+The contents look something like the following:
+
+ THR PID ITEM ADDR FL MARK DESC
+ === ===== ================ == ===== ==========
+ 0 3005 ffff880023f52348 a 952ms FSC: OBJ17d3: LOOK
+ 1 3006 ffff880024e33668 2 160ms FSC: OBJ17e5 OP60d3b: Write1/Store fl=2
+ 2 3165 ffff8800296dd180 a 424ms FSC: OBJ17e4: LOOK
+ 3 4089 ffff8800262c8d78 a 212ms FSC: OBJ17ea: CRTN
+ 4 4090 ffff88002792bed8 2 388ms FSC: OBJ17e8 OP60d36: Write1/Store fl=2
+ 5 4092 ffff88002a0ef308 2 388ms FSC: OBJ17e7 OP60d2e: Write1/Store fl=2
+ 6 4094 ffff88002abaf4b8 2 132ms FSC: OBJ17e2 OP60d4e: Write1/Store fl=2
+ 7 4095 ffff88002bb188e0 a 388ms FSC: OBJ17e9: CRTN
+ vsq - ffff880023d99668 1 308ms FSC: OBJ17e0 OP60f91: Write1/EnQ fl=2
+ vsq - ffff8800295d1740 1 212ms FSC: OBJ16be OP4d4b6: Write1/EnQ fl=2
+ vsq - ffff880025ba3308 1 160ms FSC: OBJ179a OP58dec: Write1/EnQ fl=2
+ vsq - ffff880024ec83e0 1 160ms FSC: OBJ17ae OP599f2: Write1/EnQ fl=2
+ vsq - ffff880026618e00 1 160ms FSC: OBJ17e6 OP60d33: Write1/EnQ fl=2
+ vsq - ffff880025a2a4b8 1 132ms FSC: OBJ16a2 OP4d583: Write1/EnQ fl=2
+ vsq - ffff880023cbe6d8 9 212ms FSC: OBJ17eb: LOOK
+ vsq - ffff880024d37590 9 212ms FSC: OBJ17ec: LOOK
+ vsq - ffff880027746cb0 9 212ms FSC: OBJ17ed: LOOK
+ vsq - ffff880024d37ae8 9 212ms FSC: OBJ17ee: LOOK
+ vsq - ffff880024d37cb0 9 212ms FSC: OBJ17ef: LOOK
+ vsq - ffff880025036550 9 212ms FSC: OBJ17f0: LOOK
+ vsq - ffff8800250368e0 9 212ms FSC: OBJ17f1: LOOK
+ vsq - ffff880025036aa8 9 212ms FSC: OBJ17f2: LOOK
+
+In the 'THR' column, executing items show the thread they're occupying and
+queued threads indicate which queue they're on. 'PID' shows the process ID of
+a slow-work thread that's executing something. 'FL' shows the work item flags.
+'MARK' indicates how long since an item was queued or began executing. Lastly,
+the 'DESC' column permits the owner of an item to give some information.
+
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 1c8eb4518ce0..fd9a2f67edf2 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -522,7 +522,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
pcm_devs - Number of PCM devices assigned to each card
(default = 1, up to 4)
pcm_substreams - Number of PCM substreams assigned to each PCM
- (default = 8, up to 16)
+ (default = 8, up to 128)
hrtimer - Use hrtimer (=1, default) or system timer (=0)
fake_buffer - Fake buffer allocations (default = 1)
diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index 70d68ce8640a..a87dc277a5ca 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -1,5 +1,5 @@
Generic Thermal Sysfs driver How To
-=========================
+===================================
Written by Sujith Thomas <sujith.thomas@intel.com>, Zhang Rui <rui.zhang@intel.com>
@@ -10,20 +10,20 @@ Copyright (c) 2008 Intel Corporation
0. Introduction
-The generic thermal sysfs provides a set of interfaces for thermal zone devices (sensors)
-and thermal cooling devices (fan, processor...) to register with the thermal management
-solution and to be a part of it.
+The generic thermal sysfs provides a set of interfaces for thermal zone
+devices (sensors) and thermal cooling devices (fan, processor...) to register
+with the thermal management solution and to be a part of it.
-This how-to focuses on enabling new thermal zone and cooling devices to participate
-in thermal management.
-This solution is platform independent and any type of thermal zone devices and
-cooling devices should be able to make use of the infrastructure.
+This how-to focuses on enabling new thermal zone and cooling devices to
+participate in thermal management.
+This solution is platform independent and any type of thermal zone devices
+and cooling devices should be able to make use of the infrastructure.
-The main task of the thermal sysfs driver is to expose thermal zone attributes as well
-as cooling device attributes to the user space.
-An intelligent thermal management application can make decisions based on inputs
-from thermal zone attributes (the current temperature and trip point temperature)
-and throttle appropriate devices.
+The main task of the thermal sysfs driver is to expose thermal zone attributes
+as well as cooling device attributes to the user space.
+An intelligent thermal management application can make decisions based on
+inputs from thermal zone attributes (the current temperature and trip point
+temperature) and throttle appropriate devices.
[0-*] denotes any positive number starting from 0
[1-*] denotes any positive number starting from 1
@@ -31,77 +31,77 @@ and throttle appropriate devices.
1. thermal sysfs driver interface functions
1.1 thermal zone device interface
-1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *name, int trips,
- void *devdata, struct thermal_zone_device_ops *ops)
-
- This interface function adds a new thermal zone device (sensor) to
- /sys/class/thermal folder as thermal_zone[0-*].
- It tries to bind all the thermal cooling devices registered at the same time.
-
- name: the thermal zone name.
- trips: the total number of trip points this thermal zone supports.
- devdata: device private data
- ops: thermal zone device call-backs.
- .bind: bind the thermal zone device with a thermal cooling device.
- .unbind: unbind the thermal zone device with a thermal cooling device.
- .get_temp: get the current temperature of the thermal zone.
- .get_mode: get the current mode (user/kernel) of the thermal zone.
- "kernel" means thermal management is done in kernel.
- "user" will prevent kernel thermal driver actions upon trip points
- so that user applications can take charge of thermal management.
- .set_mode: set the mode (user/kernel) of the thermal zone.
- .get_trip_type: get the type of certain trip point.
- .get_trip_temp: get the temperature above which the certain trip point
- will be fired.
+1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *name,
+ int trips, void *devdata, struct thermal_zone_device_ops *ops)
+
+ This interface function adds a new thermal zone device (sensor) to
+ /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the
+ thermal cooling devices registered at the same time.
+
+ name: the thermal zone name.
+ trips: the total number of trip points this thermal zone supports.
+ devdata: device private data
+ ops: thermal zone device call-backs.
+ .bind: bind the thermal zone device with a thermal cooling device.
+ .unbind: unbind the thermal zone device with a thermal cooling device.
+ .get_temp: get the current temperature of the thermal zone.
+ .get_mode: get the current mode (user/kernel) of the thermal zone.
+ - "kernel" means thermal management is done in kernel.
+ - "user" will prevent kernel thermal driver actions upon trip points
+ so that user applications can take charge of thermal management.
+ .set_mode: set the mode (user/kernel) of the thermal zone.
+ .get_trip_type: get the type of certain trip point.
+ .get_trip_temp: get the temperature above which the certain trip point
+ will be fired.
1.1.2 void thermal_zone_device_unregister(struct thermal_zone_device *tz)
- This interface function removes the thermal zone device.
- It deletes the corresponding entry form /sys/class/thermal folder and unbind all
- the thermal cooling devices it uses.
+ This interface function removes the thermal zone device.
+ It deletes the corresponding entry form /sys/class/thermal folder and
+ unbind all the thermal cooling devices it uses.
1.2 thermal cooling device interface
1.2.1 struct thermal_cooling_device *thermal_cooling_device_register(char *name,
- void *devdata, struct thermal_cooling_device_ops *)
-
- This interface function adds a new thermal cooling device (fan/processor/...) to
- /sys/class/thermal/ folder as cooling_device[0-*].
- It tries to bind itself to all the thermal zone devices register at the same time.
- name: the cooling device name.
- devdata: device private data.
- ops: thermal cooling devices call-backs.
- .get_max_state: get the Maximum throttle state of the cooling device.
- .get_cur_state: get the Current throttle state of the cooling device.
- .set_cur_state: set the Current throttle state of the cooling device.
+ void *devdata, struct thermal_cooling_device_ops *)
+
+ This interface function adds a new thermal cooling device (fan/processor/...)
+ to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
+ to all the thermal zone devices register at the same time.
+ name: the cooling device name.
+ devdata: device private data.
+ ops: thermal cooling devices call-backs.
+ .get_max_state: get the Maximum throttle state of the cooling device.
+ .get_cur_state: get the Current throttle state of the cooling device.
+ .set_cur_state: set the Current throttle state of the cooling device.
1.2.2 void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
- This interface function remove the thermal cooling device.
- It deletes the corresponding entry form /sys/class/thermal folder and unbind
- itself from all the thermal zone devices using it.
+ This interface function remove the thermal cooling device.
+ It deletes the corresponding entry form /sys/class/thermal folder and
+ unbind itself from all the thermal zone devices using it.
1.3 interface for binding a thermal zone device with a thermal cooling device
1.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
- int trip, struct thermal_cooling_device *cdev);
+ int trip, struct thermal_cooling_device *cdev);
- This interface function bind a thermal cooling device to the certain trip point
- of a thermal zone device.
- This function is usually called in the thermal zone device .bind callback.
- tz: the thermal zone device
- cdev: thermal cooling device
- trip: indicates which trip point the cooling devices is associated with
- in this thermal zone.
+ This interface function bind a thermal cooling device to the certain trip
+ point of a thermal zone device.
+ This function is usually called in the thermal zone device .bind callback.
+ tz: the thermal zone device
+ cdev: thermal cooling device
+ trip: indicates which trip point the cooling devices is associated with
+ in this thermal zone.
1.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
- int trip, struct thermal_cooling_device *cdev);
+ int trip, struct thermal_cooling_device *cdev);
- This interface function unbind a thermal cooling device from the certain trip point
- of a thermal zone device.
- This function is usually called in the thermal zone device .unbind callback.
- tz: the thermal zone device
- cdev: thermal cooling device
- trip: indicates which trip point the cooling devices is associated with
- in this thermal zone.
+ This interface function unbind a thermal cooling device from the certain
+ trip point of a thermal zone device. This function is usually called in
+ the thermal zone device .unbind callback.
+ tz: the thermal zone device
+ cdev: thermal cooling device
+ trip: indicates which trip point the cooling devices is associated with
+ in this thermal zone.
2. sysfs attributes structure
@@ -114,153 +114,166 @@ if hwmon is compiled in or built as a module.
Thermal zone device sys I/F, created once it's registered:
/sys/class/thermal/thermal_zone[0-*]:
- |-----type: Type of the thermal zone
- |-----temp: Current temperature
- |-----mode: Working mode of the thermal zone
- |-----trip_point_[0-*]_temp: Trip point temperature
- |-----trip_point_[0-*]_type: Trip point type
+ |---type: Type of the thermal zone
+ |---temp: Current temperature
+ |---mode: Working mode of the thermal zone
+ |---trip_point_[0-*]_temp: Trip point temperature
+ |---trip_point_[0-*]_type: Trip point type
Thermal cooling device sys I/F, created once it's registered:
/sys/class/thermal/cooling_device[0-*]:
- |-----type : Type of the cooling device(processor/fan/...)
- |-----max_state: Maximum cooling state of the cooling device
- |-----cur_state: Current cooling state of the cooling device
+ |---type: Type of the cooling device(processor/fan/...)
+ |---max_state: Maximum cooling state of the cooling device
+ |---cur_state: Current cooling state of the cooling device
-These two dynamic attributes are created/removed in pairs.
-They represent the relationship between a thermal zone and its associated cooling device.
-They are created/removed for each
-thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful execution.
+Then next two dynamic attributes are created/removed in pairs. They represent
+the relationship between a thermal zone and its associated cooling device.
+They are created/removed for each successful execution of
+thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device.
-/sys/class/thermal/thermal_zone[0-*]
- |-----cdev[0-*]: The [0-*]th cooling device in the current thermal zone
- |-----cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with
+/sys/class/thermal/thermal_zone[0-*]:
+ |---cdev[0-*]: [0-*]th cooling device in current thermal zone
+ |---cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with
Besides the thermal zone device sysfs I/F and cooling device sysfs I/F,
-the generic thermal driver also creates a hwmon sysfs I/F for each _type_ of
-thermal zone device. E.g. the generic thermal driver registers one hwmon class device
-and build the associated hwmon sysfs I/F for all the registered ACPI thermal zones.
+the generic thermal driver also creates a hwmon sysfs I/F for each _type_
+of thermal zone device. E.g. the generic thermal driver registers one hwmon
+class device and build the associated hwmon sysfs I/F for all the registered
+ACPI thermal zones.
+
/sys/class/hwmon/hwmon[0-*]:
- |-----name: The type of the thermal zone devices.
- |-----temp[1-*]_input: The current temperature of thermal zone [1-*].
- |-----temp[1-*]_critical: The critical trip point of thermal zone [1-*].
+ |---name: The type of the thermal zone devices
+ |---temp[1-*]_input: The current temperature of thermal zone [1-*]
+ |---temp[1-*]_critical: The critical trip point of thermal zone [1-*]
+
Please read Documentation/hwmon/sysfs-interface for additional information.
***************************
* Thermal zone attributes *
***************************
-type Strings which represent the thermal zone type.
- This is given by thermal zone driver as part of registration.
- Eg: "acpitz" indicates it's an ACPI thermal device.
- In order to keep it consistent with hwmon sys attribute,
- this should be a short, lowercase string,
- not containing spaces nor dashes.
- RO
- Required
-
-temp Current temperature as reported by thermal zone (sensor)
- Unit: millidegree Celsius
- RO
- Required
-
-mode One of the predefined values in [kernel, user]
- This file gives information about the algorithm
- that is currently managing the thermal zone.
- It can be either default kernel based algorithm
- or user space application.
- RW
- Optional
- kernel = Thermal management in kernel thermal zone driver.
- user = Preventing kernel thermal zone driver actions upon
- trip points so that user application can take full
- charge of the thermal management.
-
-trip_point_[0-*]_temp The temperature above which trip point will be fired
- Unit: millidegree Celsius
- RO
- Optional
-
-trip_point_[0-*]_type Strings which indicate the type of the trip point
- E.g. it can be one of critical, hot, passive,
- active[0-*] for ACPI thermal zone.
- RO
- Optional
-
-cdev[0-*] Sysfs link to the thermal cooling device node where the sys I/F
- for cooling device throttling control represents.
- RO
- Optional
-
-cdev[0-*]_trip_point The trip point with which cdev[0-*] is associated in this thermal zone
- -1 means the cooling device is not associated with any trip point.
- RO
- Optional
-
-******************************
-* Cooling device attributes *
-******************************
-
-type String which represents the type of device
- eg: For generic ACPI: this should be "Fan",
- "Processor" or "LCD"
- eg. For memory controller device on intel_menlow platform:
- this should be "Memory controller"
- RO
- Required
-
-max_state The maximum permissible cooling state of this cooling device.
- RO
- Required
-
-cur_state The current cooling state of this cooling device.
- the value can any integer numbers between 0 and max_state,
- cur_state == 0 means no cooling
- cur_state == max_state means the maximum cooling.
- RW
- Required
+type
+ Strings which represent the thermal zone type.
+ This is given by thermal zone driver as part of registration.
+ E.g: "acpitz" indicates it's an ACPI thermal device.
+ In order to keep it consistent with hwmon sys attribute; this should
+ be a short, lowercase string, not containing spaces nor dashes.
+ RO, Required
+
+temp
+ Current temperature as reported by thermal zone (sensor).
+ Unit: millidegree Celsius
+ RO, Required
+
+mode
+ One of the predefined values in [kernel, user].
+ This file gives information about the algorithm that is currently
+ managing the thermal zone. It can be either default kernel based
+ algorithm or user space application.
+ kernel = Thermal management in kernel thermal zone driver.
+ user = Preventing kernel thermal zone driver actions upon
+ trip points so that user application can take full
+ charge of the thermal management.
+ RW, Optional
+
+trip_point_[0-*]_temp
+ The temperature above which trip point will be fired.
+ Unit: millidegree Celsius
+ RO, Optional
+
+trip_point_[0-*]_type
+ Strings which indicate the type of the trip point.
+ E.g. it can be one of critical, hot, passive, active[0-*] for ACPI
+ thermal zone.
+ RO, Optional
+
+cdev[0-*]
+ Sysfs link to the thermal cooling device node where the sys I/F
+ for cooling device throttling control represents.
+ RO, Optional
+
+cdev[0-*]_trip_point
+ The trip point with which cdev[0-*] is associated in this thermal
+ zone; -1 means the cooling device is not associated with any trip
+ point.
+ RO, Optional
+
+passive
+ Attribute is only present for zones in which the passive cooling
+ policy is not supported by native thermal driver. Default is zero
+ and can be set to a temperature (in millidegrees) to enable a
+ passive trip point for the zone. Activation is done by polling with
+ an interval of 1 second.
+ Unit: millidegrees Celsius
+ RW, Optional
+
+*****************************
+* Cooling device attributes *
+*****************************
+
+type
+ String which represents the type of device, e.g:
+ - for generic ACPI: should be "Fan", "Processor" or "LCD"
+ - for memory controller device on intel_menlow platform:
+ should be "Memory controller".
+ RO, Required
+
+max_state
+ The maximum permissible cooling state of this cooling device.
+ RO, Required
+
+cur_state
+ The current cooling state of this cooling device.
+ The value can any integer numbers between 0 and max_state:
+ - cur_state == 0 means no cooling
+ - cur_state == max_state means the maximum cooling.
+ RW, Required
3. A simple implementation
-ACPI thermal zone may support multiple trip points like critical/hot/passive/active.
-If an ACPI thermal zone supports critical, passive, active[0] and active[1] at the same time,
-it may register itself as a thermal_zone_device (thermal_zone1) with 4 trip points in all.
-It has one processor and one fan, which are both registered as thermal_cooling_device.
-If the processor is listed in _PSL method, and the fan is listed in _AL0 method,
-the sys I/F structure will be built like this:
+ACPI thermal zone may support multiple trip points like critical, hot,
+passive, active. If an ACPI thermal zone supports critical, passive,
+active[0] and active[1] at the same time, it may register itself as a
+thermal_zone_device (thermal_zone1) with 4 trip points in all.
+It has one processor and one fan, which are both registered as
+thermal_cooling_device.
+
+If the processor is listed in _PSL method, and the fan is listed in _AL0
+method, the sys I/F structure will be built like this:
/sys/class/thermal:
|thermal_zone1:
- |-----type: acpitz
- |-----temp: 37000
- |-----mode: kernel
- |-----trip_point_0_temp: 100000
- |-----trip_point_0_type: critical
- |-----trip_point_1_temp: 80000
- |-----trip_point_1_type: passive
- |-----trip_point_2_temp: 70000
- |-----trip_point_2_type: active0
- |-----trip_point_3_temp: 60000
- |-----trip_point_3_type: active1
- |-----cdev0: --->/sys/class/thermal/cooling_device0
- |-----cdev0_trip_point: 1 /* cdev0 can be used for passive */
- |-----cdev1: --->/sys/class/thermal/cooling_device3
- |-----cdev1_trip_point: 2 /* cdev1 can be used for active[0]*/
+ |---type: acpitz
+ |---temp: 37000
+ |---mode: kernel
+ |---trip_point_0_temp: 100000
+ |---trip_point_0_type: critical
+ |---trip_point_1_temp: 80000
+ |---trip_point_1_type: passive
+ |---trip_point_2_temp: 70000
+ |---trip_point_2_type: active0
+ |---trip_point_3_temp: 60000
+ |---trip_point_3_type: active1
+ |---cdev0: --->/sys/class/thermal/cooling_device0
+ |---cdev0_trip_point: 1 /* cdev0 can be used for passive */
+ |---cdev1: --->/sys/class/thermal/cooling_device3
+ |---cdev1_trip_point: 2 /* cdev1 can be used for active[0]*/
|cooling_device0:
- |-----type: Processor
- |-----max_state: 8
- |-----cur_state: 0
+ |---type: Processor
+ |---max_state: 8
+ |---cur_state: 0
|cooling_device3:
- |-----type: Fan
- |-----max_state: 2
- |-----cur_state: 0
+ |---type: Fan
+ |---max_state: 2
+ |---cur_state: 0
/sys/class/hwmon:
|hwmon0:
- |-----name: acpitz
- |-----temp1_input: 37000
- |-----temp1_crit: 100000
+ |---name: acpitz
+ |---temp1_input: 37000
+ |---temp1_crit: 100000
diff --git a/Documentation/trace/ftrace-design.txt b/Documentation/trace/ftrace-design.txt
index 7003e10f10f5..641a1ef2a7ff 100644
--- a/Documentation/trace/ftrace-design.txt
+++ b/Documentation/trace/ftrace-design.txt
@@ -213,10 +213,19 @@ If you can't trace NMI functions, then skip this option.
<details to be filled>
-HAVE_FTRACE_SYSCALLS
+HAVE_SYSCALL_TRACEPOINTS
---------------------
-<details to be filled>
+You need very few things to get the syscalls tracing in an arch.
+
+- Have a NR_syscalls variable in <asm/unistd.h> that provides the number
+ of syscalls supported by the arch.
+- Implement arch_syscall_addr() that resolves a syscall address from a
+ syscall number.
+- Support the TIF_SYSCALL_TRACEPOINT thread flags
+- Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace
+ in the ptrace syscalls tracing path.
+- Tag this arch as HAVE_SYSCALL_TRACEPOINTS.
HAVE_FTRACE_MCOUNT_RECORD
diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt
index 957b22fde2df..8179692fbb90 100644
--- a/Documentation/trace/ftrace.txt
+++ b/Documentation/trace/ftrace.txt
@@ -1231,6 +1231,7 @@ something like this simple program:
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
+#include <string.h>
#define _STR(x) #x
#define STR(x) _STR(x)
@@ -1265,6 +1266,7 @@ const char *find_debugfs(void)
return NULL;
}
+ strcat(debugfs, "/tracing/");
debugfs_found = 1;
return debugfs;
diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt
new file mode 100644
index 000000000000..47aabeebbdf6
--- /dev/null
+++ b/Documentation/trace/kprobetrace.txt
@@ -0,0 +1,149 @@
+ Kprobe-based Event Tracing
+ ==========================
+
+ Documentation is written by Masami Hiramatsu
+
+
+Overview
+--------
+These events are similar to tracepoint based events. Instead of Tracepoint,
+this is based on kprobes (kprobe and kretprobe). So it can probe wherever
+kprobes can probe (this means, all functions body except for __kprobes
+functions). Unlike the Tracepoint based event, this can be added and removed
+dynamically, on the fly.
+
+To enable this feature, build your kernel with CONFIG_KPROBE_TRACING=y.
+
+Similar to the events tracer, this doesn't need to be activated via
+current_tracer. Instead of that, add probe points via
+/sys/kernel/debug/tracing/kprobe_events, and enable it via
+/sys/kernel/debug/tracing/events/kprobes/<EVENT>/enabled.
+
+
+Synopsis of kprobe_events
+-------------------------
+ p[:[GRP/]EVENT] SYMBOL[+offs]|MEMADDR [FETCHARGS] : Set a probe
+ r[:[GRP/]EVENT] SYMBOL[+0] [FETCHARGS] : Set a return probe
+
+ GRP : Group name. If omitted, use "kprobes" for it.
+ EVENT : Event name. If omitted, the event name is generated
+ based on SYMBOL+offs or MEMADDR.
+ SYMBOL[+offs] : Symbol+offset where the probe is inserted.
+ MEMADDR : Address where the probe is inserted.
+
+ FETCHARGS : Arguments. Each probe can have up to 128 args.
+ %REG : Fetch register REG
+ @ADDR : Fetch memory at ADDR (ADDR should be in kernel)
+ @SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol)
+ $stackN : Fetch Nth entry of stack (N >= 0)
+ $stack : Fetch stack address.
+ $argN : Fetch function argument. (N >= 0)(*)
+ $retval : Fetch return value.(**)
+ +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***)
+ NAME=FETCHARG: Set NAME as the argument name of FETCHARG.
+
+ (*) aN may not correct on asmlinkaged functions and at the middle of
+ function body.
+ (**) only for return probe.
+ (***) this is useful for fetching a field of data structures.
+
+
+Per-Probe Event Filtering
+-------------------------
+ Per-probe event filtering feature allows you to set different filter on each
+probe and gives you what arguments will be shown in trace buffer. If an event
+name is specified right after 'p:' or 'r:' in kprobe_events, it adds an event
+under tracing/events/kprobes/<EVENT>, at the directory you can see 'id',
+'enabled', 'format' and 'filter'.
+
+enabled:
+ You can enable/disable the probe by writing 1 or 0 on it.
+
+format:
+ This shows the format of this probe event.
+
+filter:
+ You can write filtering rules of this event.
+
+id:
+ This shows the id of this probe event.
+
+
+Event Profiling
+---------------
+ You can check the total number of probe hits and probe miss-hits via
+/sys/kernel/debug/tracing/kprobe_profile.
+ The first column is event name, the second is the number of probe hits,
+the third is the number of probe miss-hits.
+
+
+Usage examples
+--------------
+To add a probe as a new event, write a new definition to kprobe_events
+as below.
+
+ echo p:myprobe do_sys_open dfd=$arg0 filename=$arg1 flags=$arg2 mode=$arg3 > /sys/kernel/debug/tracing/kprobe_events
+
+ This sets a kprobe on the top of do_sys_open() function with recording
+1st to 4th arguments as "myprobe" event. As this example shows, users can
+choose more familiar names for each arguments.
+
+ echo r:myretprobe do_sys_open $retval >> /sys/kernel/debug/tracing/kprobe_events
+
+ This sets a kretprobe on the return point of do_sys_open() function with
+recording return value as "myretprobe" event.
+ You can see the format of these events via
+/sys/kernel/debug/tracing/events/kprobes/<EVENT>/format.
+
+ cat /sys/kernel/debug/tracing/events/kprobes/myprobe/format
+name: myprobe
+ID: 75
+format:
+ field:unsigned short common_type; offset:0; size:2;
+ field:unsigned char common_flags; offset:2; size:1;
+ field:unsigned char common_preempt_count; offset:3; size:1;
+ field:int common_pid; offset:4; size:4;
+ field:int common_tgid; offset:8; size:4;
+
+ field: unsigned long ip; offset:16;tsize:8;
+ field: int nargs; offset:24;tsize:4;
+ field: unsigned long dfd; offset:32;tsize:8;
+ field: unsigned long filename; offset:40;tsize:8;
+ field: unsigned long flags; offset:48;tsize:8;
+ field: unsigned long mode; offset:56;tsize:8;
+
+print fmt: "(%lx) dfd=%lx filename=%lx flags=%lx mode=%lx", REC->ip, REC->dfd, REC->filename, REC->flags, REC->mode
+
+
+ You can see that the event has 4 arguments as in the expressions you specified.
+
+ echo > /sys/kernel/debug/tracing/kprobe_events
+
+ This clears all probe points.
+
+ Right after definition, each event is disabled by default. For tracing these
+events, you need to enable it.
+
+ echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
+ echo 1 > /sys/kernel/debug/tracing/events/kprobes/myretprobe/enable
+
+ And you can see the traced information via /sys/kernel/debug/tracing/trace.
+
+ cat /sys/kernel/debug/tracing/trace
+# tracer: nop
+#
+# TASK-PID CPU# TIMESTAMP FUNCTION
+# | | | | |
+ <...>-1447 [001] 1038282.286875: myprobe: (do_sys_open+0x0/0xd6) dfd=3 filename=7fffd1ec4440 flags=8000 mode=0
+ <...>-1447 [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) $retval=fffffffffffffffe
+ <...>-1447 [001] 1038282.286885: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=40413c flags=8000 mode=1b6
+ <...>-1447 [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3
+ <...>-1447 [001] 1038282.286969: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=4041c6 flags=98800 mode=10
+ <...>-1447 [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3
+
+
+ Each line shows when the kernel hits an event, and <- SYMBOL means kernel
+returns from SYMBOL(e.g. "sys_open+0x1b/0x1d <- do_sys_open" means kernel
+returns from do_sys_open to sys_open+0x1b).
+
+
diff --git a/Documentation/vm/hwpoison.txt b/Documentation/vm/hwpoison.txt
new file mode 100644
index 000000000000..3ffadf8da61f
--- /dev/null
+++ b/Documentation/vm/hwpoison.txt
@@ -0,0 +1,136 @@
+What is hwpoison?
+
+Upcoming Intel CPUs have support for recovering from some memory errors
+(``MCA recovery''). This requires the OS to declare a page "poisoned",
+kill the processes associated with it and avoid using it in the future.
+
+This patchkit implements the necessary infrastructure in the VM.
+
+To quote the overview comment:
+
+ * High level machine check handler. Handles pages reported by the
+ * hardware as being corrupted usually due to a 2bit ECC memory or cache
+ * failure.
+ *
+ * This focusses on pages detected as corrupted in the background.
+ * When the current CPU tries to consume corruption the currently
+ * running process can just be killed directly instead. This implies
+ * that if the error cannot be handled for some reason it's safe to
+ * just ignore it because no corruption has been consumed yet. Instead
+ * when that happens another machine check will happen.
+ *
+ * Handles page cache pages in various states. The tricky part
+ * here is that we can access any page asynchronous to other VM
+ * users, because memory failures could happen anytime and anywhere,
+ * possibly violating some of their assumptions. This is why this code
+ * has to be extremely careful. Generally it tries to use normal locking
+ * rules, as in get the standard locks, even if that means the
+ * error handling takes potentially a long time.
+ *
+ * Some of the operations here are somewhat inefficient and have non
+ * linear algorithmic complexity, because the data structures have not
+ * been optimized for this case. This is in particular the case
+ * for the mapping from a vma to a process. Since this case is expected
+ * to be rare we hope we can get away with this.
+
+The code consists of a the high level handler in mm/memory-failure.c,
+a new page poison bit and various checks in the VM to handle poisoned
+pages.
+
+The main target right now is KVM guests, but it works for all kinds
+of applications. KVM support requires a recent qemu-kvm release.
+
+For the KVM use there was need for a new signal type so that
+KVM can inject the machine check into the guest with the proper
+address. This in theory allows other applications to handle
+memory failures too. The expection is that near all applications
+won't do that, but some very specialized ones might.
+
+---
+
+There are two (actually three) modi memory failure recovery can be in:
+
+vm.memory_failure_recovery sysctl set to zero:
+ All memory failures cause a panic. Do not attempt recovery.
+ (on x86 this can be also affected by the tolerant level of the
+ MCE subsystem)
+
+early kill
+ (can be controlled globally and per process)
+ Send SIGBUS to the application as soon as the error is detected
+ This allows applications who can process memory errors in a gentle
+ way (e.g. drop affected object)
+ This is the mode used by KVM qemu.
+
+late kill
+ Send SIGBUS when the application runs into the corrupted page.
+ This is best for memory error unaware applications and default
+ Note some pages are always handled as late kill.
+
+---
+
+User control:
+
+vm.memory_failure_recovery
+ See sysctl.txt
+
+vm.memory_failure_early_kill
+ Enable early kill mode globally
+
+PR_MCE_KILL
+ Set early/late kill mode/revert to system default
+ arg1: PR_MCE_KILL_CLEAR: Revert to system default
+ arg1: PR_MCE_KILL_SET: arg2 defines thread specific mode
+ PR_MCE_KILL_EARLY: Early kill
+ PR_MCE_KILL_LATE: Late kill
+ PR_MCE_KILL_DEFAULT: Use system global default
+PR_MCE_KILL_GET
+ return current mode
+
+
+---
+
+Testing:
+
+madvise(MADV_POISON, ....)
+ (as root)
+ Poison a page in the process for testing
+
+
+hwpoison-inject module through debugfs
+ /sys/debug/hwpoison/corrupt-pfn
+
+Inject hwpoison fault at PFN echoed into this file
+
+
+Architecture specific MCE injector
+
+x86 has mce-inject, mce-test
+
+Some portable hwpoison test programs in mce-test, see blow.
+
+---
+
+References:
+
+http://halobates.de/mce-lc09-2.pdf
+ Overview presentation from LinuxCon 09
+
+git://git.kernel.org/pub/scm/utils/cpu/mce/mce-test.git
+ Test suite (hwpoison specific portable tests in tsrc)
+
+git://git.kernel.org/pub/scm/utils/cpu/mce/mce-inject.git
+ x86 specific injector
+
+
+---
+
+Limitations:
+
+- Not all page types are supported and never will. Most kernel internal
+objects cannot be recovered, only LRU pages for now.
+- Right now hugepage support is missing.
+
+---
+Andi Kleen, Oct 2009
+
diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c
index 3ec4f2a22585..4793c6aac733 100644
--- a/Documentation/vm/page-types.c
+++ b/Documentation/vm/page-types.c
@@ -218,7 +218,7 @@ static void fatal(const char *x, ...)
exit(EXIT_FAILURE);
}
-int checked_open(const char *pathname, int flags)
+static int checked_open(const char *pathname, int flags)
{
int fd = open(pathname, flags);
diff --git a/MAINTAINERS b/MAINTAINERS
index ff968842ce56..4f96ac81089c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -65,43 +65,51 @@ trivial patch so apply some common sense.
8. Happy hacking.
- -----------------------------------
-
-Maintainers List (try to look for most precise areas first)
+Descriptions of section entries:
+
+ P: Person (obsolete)
+ M: Mail patches to: FullName <address@domain>
+ L: Mailing list that is relevant to this area
+ W: Web-page with status/info
+ T: SCM tree type and location. Type is one of: git, hg, quilt, stgit.
+ S: Status, one of the following:
+ Supported: Someone is actually paid to look after this.
+ Maintained: Someone actually looks after it.
+ Odd Fixes: It has a maintainer but they don't have time to do
+ much other than throw the odd patch in. See below..
+ Orphan: No current maintainer [but maybe you could take the
+ role as you write your new code].
+ Obsolete: Old code. Something tagged obsolete generally means
+ it has been replaced by a better system and you
+ should be using that.
+ F: Files and directories with wildcard patterns.
+ A trailing slash includes all files and subdirectory files.
+ F: drivers/net/ all files in and below drivers/net
+ F: drivers/net/* all files in drivers/net, but not below
+ F: */net/* all files in "any top level directory"/net
+ One pattern per line. Multiple F: lines acceptable.
+ X: Files and directories that are NOT maintained, same rules as F:
+ Files exclusions are tested before file matches.
+ Can be useful for excluding a specific subdirectory, for instance:
+ F: net/
+ X: net/ipv6/
+ matches all files in and below net excluding net/ipv6/
+ K: Keyword perl extended regex pattern to match content in a
+ patch or file. For instance:
+ K: of_get_profile
+ matches patches or files that contain "of_get_profile"
+ K: \b(printk|pr_(info|err))\b
+ matches patches or files that contain one or more of the words
+ printk, pr_info or pr_err
+ One regex pattern per line. Multiple K: lines acceptable.
Note: For the hard of thinking, this list is meant to remain in alphabetical
order. If you could add yourselves to it in alphabetical order that would be
so much easier [Ed]
-P: Person (obsolete)
-M: Mail patches to: FullName <address@domain>
-L: Mailing list that is relevant to this area
-W: Web-page with status/info
-T: SCM tree type and location. Type is one of: git, hg, quilt, stgit.
-S: Status, one of the following:
-
- Supported: Someone is actually paid to look after this.
- Maintained: Someone actually looks after it.
- Odd Fixes: It has a maintainer but they don't have time to do
- much other than throw the odd patch in. See below..
- Orphan: No current maintainer [but maybe you could take the
- role as you write your new code].
- Obsolete: Old code. Something tagged obsolete generally means
- it has been replaced by a better system and you
- should be using that.
+Maintainers List (try to look for most precise areas first)
-F: Files and directories with wildcard patterns.
- A trailing slash includes all files and subdirectory files.
- F: drivers/net/ all files in and below drivers/net
- F: drivers/net/* all files in drivers/net, but not below
- F: */net/* all files in "any top level directory"/net
- One pattern per line. Multiple F: lines acceptable.
-X: Files and directories that are NOT maintained, same rules as F:
- Files exclusions are tested before file matches.
- Can be useful for excluding a specific subdirectory, for instance:
- F: net/
- X: net/ipv6/
- matches all files in and below net excluding net/ipv6/
+ -----------------------------------
3C505 NETWORK DRIVER
M: Philip Blundell <philb@gnu.org>
@@ -174,7 +182,7 @@ M: Ron Minnich <rminnich@sandia.gov>
M: Latchesar Ionkov <lucho@ionkov.net>
L: v9fs-developer@lists.sourceforge.net
W: http://swik.net/v9fs
-T: git git://git.kernel.org/pub/scm/linux/kernel/ericvh/v9fs.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git
S: Maintained
F: Documentation/filesystems/9p.txt
F: fs/9p/
@@ -504,10 +512,32 @@ W: http://www.arm.linux.org.uk/
S: Maintained
F: arch/arm/
+ARM PRIMECELL AACI PL041 DRIVER
+M: Russell King <linux@arm.linux.org.uk>
+S: Maintained
+F: sound/arm/aaci.*
+
+ARM PRIMECELL CLCD PL110 DRIVER
+M: Russell King <linux@arm.linux.org.uk>
+S: Maintained
+F: drivers/video/amba-clcd.*
+
+ARM PRIMECELL KMI PL050 DRIVER
+M: Russell King <linux@arm.linux.org.uk>
+S: Maintained
+F: drivers/input/serio/ambakmi.*
+F: include/linux/amba/kmi.h
+
ARM PRIMECELL MMCI PL180/1 DRIVER
S: Orphan
F: drivers/mmc/host/mmci.*
+ARM PRIMECELL BUS SUPPORT
+M: Russell King <linux@arm.linux.org.uk>
+S: Maintained
+F: drivers/amba/
+F: include/linux/amba/bus.h
+
ARM/ADI ROADRUNNER MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -898,7 +928,6 @@ M: Karol Kozimor <sziwan@users.sourceforge.net>
L: acpi4asus-user@lists.sourceforge.net
W: http://acpi4asus.sf.net
S: Maintained
-F: arch/x86/kernel/acpi/boot.c
F: drivers/platform/x86/asus_acpi.c
ASUS ASB100 HARDWARE MONITOR DRIVER
@@ -992,7 +1021,7 @@ F: drivers/net/atlx/
ATM
M: Chas Williams <chas@cmf.nrl.navy.mil>
-L: linux-atm-general@lists.sourceforge.net (subscribers-only)
+L: linux-atm-general@lists.sourceforge.net (moderated for non-subscribers)
L: netdev@vger.kernel.org
W: http://linux-atm.sourceforge.net
S: Maintained
@@ -1020,7 +1049,7 @@ F: drivers/serial/atmel_serial.c
ATMEL LCDFB DRIVER
M: Nicolas Ferre <nicolas.ferre@atmel.com>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/atmel_lcdfb.c
F: include/video/atmel_lcdc.h
@@ -1237,11 +1266,10 @@ S: Supported
F: drivers/net/tg3.*
BROCADE BFA FC SCSI DRIVER
-P: Jing Huang
-M: huangj@brocade.com
-L: linux-scsi@vger.kernel.org
-S: Supported
-F: drivers/scsi/bfa/
+M: Jing Huang <huangj@brocade.com>
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/bfa/
BSG (block layer generic sg v4 driver)
M: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
@@ -1480,6 +1508,7 @@ F: mm/*cgroup*
CORETEMP HARDWARE MONITORING DRIVER
M: Rudolf Marek <r.marek@assembler.cz>
+M: Huaxu Wan <huaxu.wan@intel.com>
L: lm-sensors@lm-sensors.org
S: Maintained
F: Documentation/hwmon/coretemp
@@ -2106,7 +2135,7 @@ F: drivers/net/wan/dlci.c
F: drivers/net/wan/sdla.c
FRAMEBUFFER LAYER
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
W: http://linux-fbdev.sourceforge.net/
S: Orphan
F: Documentation/fb/
@@ -2129,7 +2158,7 @@ F: drivers/i2c/busses/i2c-cpm.c
FREESCALE IMX / MXC FRAMEBUFFER DRIVER
M: Sascha Hauer <kernel@pengutronix.de>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/plat-mxc/include/mach/imxfb.h
@@ -2151,7 +2180,7 @@ S: Supported
F: arch/powerpc/sysdev/qe_lib/
F: arch/powerpc/include/asm/*qe.h
-FREESCALE USB PERIPHERIAL DRIVERS
+FREESCALE USB PERIPHERAL DRIVERS
M: Li Yang <leoli@freescale.com>
L: linux-usb@vger.kernel.org
L: linuxppc-dev@ozlabs.org
@@ -2202,18 +2231,6 @@ F: Documentation/filesystems/caching/
F: fs/fscache/
F: include/linux/fscache*.h
-TRACING
-M: Steven Rostedt <rostedt@goodmis.org>
-M: Frederic Weisbecker <fweisbec@gmail.com>
-M: Ingo Molnar <mingo@redhat.com>
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
-S: Maintained
-F: Documentation/trace/ftrace.txt
-F: arch/*/*/*/ftrace.h
-F: arch/*/kernel/ftrace.c
-F: include/*/ftrace.h include/trace/ include/linux/trace*.h
-F: kernel/trace/
-
FUJITSU FR-V (FRV) PORT
M: David Howells <dhowells@redhat.com>
S: Maintained
@@ -2272,9 +2289,8 @@ S: Maintained
F: include/asm-generic
GENERIC UIO DRIVER FOR PCI DEVICES
-M: Michael S. Tsirkin <mst@redhat.com>
+M: "Michael S. Tsirkin" <mst@redhat.com>
L: kvm@vger.kernel.org
-L: linux-kernel@vger.kernel.org
S: Supported
F: drivers/uio/uio_pci_generic.c
@@ -2318,6 +2334,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
F: drivers/media/video/gspca/finepix.c
+GSPCA GL860 SUBDRIVER
+M: Olivier Lorin <o.lorin@laposte.net>
+L: linux-media@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+S: Maintained
+F: drivers/media/video/gspca/gl860/
+
GSPCA M5602 SUBDRIVER
M: Erik Andren <erik.andren@gmail.com>
L: linux-media@vger.kernel.org
@@ -2539,8 +2562,7 @@ S: Maintained
F: Documentation/i2c/
F: drivers/i2c/
F: include/linux/i2c.h
-F: include/linux/i2c-dev.h
-F: include/linux/i2c-id.h
+F: include/linux/i2c-*.h
I2C-TINY-USB DRIVER
M: Till Harbaum <till@harbaum.org>
@@ -2615,6 +2637,7 @@ L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
S: Maintained
+F: Documentation/debugging-via-ohci1394.txt
F: drivers/ieee1394/
IEEE 1394 RAW I/O DRIVER
@@ -2640,7 +2663,7 @@ S: Supported
F: security/integrity/ima/
IMS TWINTURBO FRAMEBUFFER DRIVER
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Orphan
F: drivers/video/imsttfb.c
@@ -2675,14 +2698,14 @@ F: drivers/input/
INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
M: Sylvain Meyer <sylvain.meyer@worldonline.fr>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Maintained
F: Documentation/fb/intelfb.txt
F: drivers/video/intelfb/
INTEL 810/815 FRAMEBUFFER DRIVER
M: Antonino Daplas <adaplas@gmail.com>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/i810/
@@ -2828,7 +2851,7 @@ F: drivers/infiniband/hw/ipath/
IPMI SUBSYSTEM
M: Corey Minyard <minyard@acm.org>
-L: openipmi-developer@lists.sourceforge.net
+L: openipmi-developer@lists.sourceforge.net (moderated for non-subscribers)
W: http://openipmi.sourceforge.net/
S: Supported
F: Documentation/IPMI.txt
@@ -2992,19 +3015,16 @@ S: Maintained
F: fs/autofs4/
KERNEL BUILD
-M: Sam Ravnborg <sam@ravnborg.org>
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes.git
L: linux-kbuild@vger.kernel.org
-S: Maintained
+S: Orphan
F: Documentation/kbuild/
F: Makefile
F: scripts/Makefile.*
KERNEL JANITORS
L: kernel-janitors@vger.kernel.org
-W: http://www.kerneljanitors.org/
-S: Maintained
+W: http://janitor.kernelnewbies.org/
+S: Odd Fixes
KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
M: "J. Bruce Fields" <bfields@fieldses.org>
@@ -3089,9 +3109,13 @@ F: kernel/kgdb.c
KMEMCHECK
M: Vegard Nossum <vegardno@ifi.uio.no>
-P Pekka Enberg
-M: penberg@cs.helsinki.fi
+M: Pekka Enberg <penberg@cs.helsinki.fi>
S: Maintained
+F: Documentation/kmemcheck.txt
+F: arch/x86/include/asm/kmemcheck.h
+F: arch/x86/mm/kmemcheck/
+F: include/linux/kmemcheck.h
+F: mm/kmemcheck.c
KMEMLEAK
M: Catalin Marinas <catalin.marinas@arm.com>
@@ -3392,7 +3416,7 @@ S: Supported
MATROX FRAMEBUFFER DRIVER
M: Petr Vandrovec <vandrove@vc.cvut.cz>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/matrox/matroxfb_*
F: include/linux/matroxfb.h
@@ -3621,7 +3645,7 @@ L: netfilter@vger.kernel.org
L: coreteam@netfilter.org
W: http://www.netfilter.org/
W: http://www.iptables.org/
-T: git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git
S: Supported
F: include/linux/netfilter*
F: include/linux/netfilter/
@@ -3666,7 +3690,9 @@ NETWORKING [GENERAL]
M: "David S. Miller" <davem@davemloft.net>
L: netdev@vger.kernel.org
W: http://www.linuxfoundation.org/en/Net
+W: http://patchwork.ozlabs.org/project/netdev/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git
S: Maintained
F: net/
F: include/net/
@@ -3777,13 +3803,13 @@ F: fs/ntfs/
NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
M: Antonino Daplas <adaplas@gmail.com>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/riva/
F: drivers/video/nvidia/
OMAP SUPPORT
-M: "Tony Lindgren <tony@atomide.com>" <tony@atomide.com>
+M: Tony Lindgren <tony@atomide.com>
L: linux-omap@vger.kernel.org
W: http://www.muru.com/linux/omap/
W: http://linux.omap.com/
@@ -3812,7 +3838,7 @@ F: sound/soc/omap/
OMAP FRAMEBUFFER SUPPORT
M: Imre Deak <imre.deak@nokia.com>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
L: linux-omap@vger.kernel.org
S: Maintained
F: drivers/video/omap/
@@ -3888,6 +3914,15 @@ S: Maintained
F: Documentation/i2c/busses/i2c-ocores
F: drivers/i2c/busses/i2c-ocores.c
+OPEN FIRMWARE AND FLATTENED DEVICE TREE
+M: Grant Likely <grant.likely@secretlab.ca>
+L: devicetree-discuss@lists.ozlabs.org
+W: http://fdt.secretlab.ca
+S: Maintained
+F: drivers/of
+F: include/linux/of*.h
+K: of_get_property
+
OPROFILE
M: Robert Richter <robert.richter@amd.com>
L: oprofile-list@lists.sf.net
@@ -4076,6 +4111,13 @@ M: Peter Zijlstra <a.p.zijlstra@chello.nl>
M: Paul Mackerras <paulus@samba.org>
M: Ingo Molnar <mingo@elte.hu>
S: Supported
+F: kernel/perf_event.c
+F: include/linux/perf_event.h
+F: arch/*/*/kernel/perf_event.c
+F: arch/*/include/asm/perf_event.h
+F: arch/*/lib/perf_event.c
+F: arch/*/kernel/perf_callchain.c
+F: tools/perf/
PERSONALITY HANDLING
M: Christoph Hellwig <hch@infradead.org>
@@ -4302,21 +4344,23 @@ F: include/linux/qnxtypes.h
RADEON FRAMEBUFFER DISPLAY DRIVER
M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/aty/radeon*
F: include/linux/radeonfb.h
RAGE128 FRAMEBUFFER DISPLAY DRIVER
M: Paul Mackerras <paulus@samba.org>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/aty/aty128fb.c
RALINK RT2X00 WIRELESS LAN DRIVER
P: rt2x00 project
+M: Ivo van Doorn <IvDoorn@gmail.com>
+M: Gertjan van Wingerde <gwingerde@gmail.com>
L: linux-wireless@vger.kernel.org
-L: users@rt2x00.serialmonkey.com
+L: users@rt2x00.serialmonkey.com (moderated for non-subscribers)
W: http://rt2x00.serialmonkey.com/
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git
@@ -4402,7 +4446,7 @@ RFKILL
M: Johannes Berg <johannes@sipsolutions.net>
L: linux-wireless@vger.kernel.org
S: Maintained
-F Documentation/rfkill.txt
+F: Documentation/rfkill.txt
F: net/rfkill/
RISCOM8 DRIVER
@@ -4446,7 +4490,7 @@ F: drivers/net/wireless/rtl818x/rtl8187*
S3 SAVAGE FRAMEBUFFER DRIVER
M: Antonino Daplas <adaplas@gmail.com>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/savage/
@@ -4525,12 +4569,11 @@ F: kernel/sched*
F: include/linux/sched.h
SCORE ARCHITECTURE
-P: Chen Liqin
-M: liqin.chen@sunplusct.com
-P: Lennox Wu
-M: lennox.wu@gmail.com
+M: Chen Liqin <liqin.chen@sunplusct.com>
+M: Lennox Wu <lennox.wu@gmail.com>
W: http://www.sunplusct.com
S: Supported
+F: arch/score/
SCSI CDROM DRIVER
M: Jens Axboe <axboe@kernel.dk>
@@ -4603,27 +4646,27 @@ S: Maintained
F: drivers/mmc/host/sdricoh_cs.c
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
-S: Orphan
-L: linux-mmc@vger.kernel.org
-F: drivers/mmc/host/sdhci.*
+S: Orphan
+L: linux-mmc@vger.kernel.org
+F: drivers/mmc/host/sdhci.*
SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
M: Anton Vorontsov <avorontsov@ru.mvista.com>
L: linuxppc-dev@ozlabs.org
-L: linux-mmc@vger.kernel.org
+L: linux-mmc@vger.kernel.org
S: Maintained
-F: drivers/mmc/host/sdhci-of.*
+F: drivers/mmc/host/sdhci-of.*
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER
M: Ben Dooks <ben-linux@fluff.org>
-L: linux-mmc@vger.kernel.org
+L: linux-mmc@vger.kernel.org
S: Maintained
F: drivers/mmc/host/sdhci-s3c.c
SECURITY SUBSYSTEM
M: James Morris <jmorris@namei.org>
L: linux-security-module@vger.kernel.org (suggested Cc:)
-T: git git://www.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
W: http://security.wiki.kernel.org/
S: Supported
F: security/
@@ -4659,12 +4702,11 @@ F: include/linux/ata.h
F: include/linux/libata.h
SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
-P: Jayamohan Kallickal
-M: jayamohank@serverengines.com
-L: linux-scsi@vger.kernel.org
-W: http://www.serverengines.com
-S: Supported
-F: drivers/scsi/be2iscsi/
+M: Jayamohan Kallickal <jayamohank@serverengines.com>
+L: linux-scsi@vger.kernel.org
+W: http://www.serverengines.com
+S: Supported
+F: drivers/scsi/be2iscsi/
SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
M: Sathya Perla <sathyap@serverengines.com>
@@ -4719,8 +4761,7 @@ F: drivers/usb/gadget/lh7a40*
F: drivers/usb/host/ohci-lh7a40*
SIMPLE FIRMWARE INTERFACE (SFI)
-P: Len Brown
-M: lenb@kernel.org
+M: Len Brown <lenb@kernel.org>
L: sfi-devel@simplefirmware.org
W: http://simplefirmware.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-sfi-2.6.git
@@ -5168,6 +5209,20 @@ L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
F: drivers/char/tpm/
+TRACING
+M: Steven Rostedt <rostedt@goodmis.org>
+M: Frederic Weisbecker <fweisbec@gmail.com>
+M: Ingo Molnar <mingo@redhat.com>
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
+S: Maintained
+F: Documentation/trace/ftrace.txt
+F: arch/*/*/*/ftrace.h
+F: arch/*/kernel/ftrace.c
+F: include/*/ftrace.h
+F: include/linux/trace*.h
+F: include/trace/
+F: kernel/trace/
+
TRIVIAL PATCHES
M: Jiri Kosina <trivial@kernel.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git
@@ -5598,7 +5653,7 @@ S: Maintained
UVESAFB DRIVER
M: Michal Januszewski <spock@gentoo.org>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
W: http://dev.gentoo.org/~spock/projects/uvesafb/
S: Maintained
F: Documentation/fb/uvesafb.txt
@@ -5631,7 +5686,7 @@ F: drivers/mmc/host/via-sdmmc.c
VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER
M: Joseph Chan <JosephChan@via.com.tw>
M: Scott Fang <ScottFang@viatech.com.cn>
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/via/
@@ -5656,6 +5711,13 @@ S: Maintained
F: drivers/vlynq/vlynq.c
F: include/linux/vlynq.h
+VMWARE VMXNET3 ETHERNET DRIVER
+M: Shreyas Bhatewara <sbhatewara@vmware.com>
+M: "VMware, Inc." <pv-drivers@vmware.com>
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/vmxnet3/
+
VOLTAGE AND CURRENT REGULATOR FRAMEWORK
M: Liam Girdwood <lrg@slimlogic.co.uk>
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
@@ -5727,8 +5789,7 @@ S: Maintained
F: drivers/scsi/wd7000.c
WINBOND CIR DRIVER
-P: David Härdeman
-M: david@hardeman.nu
+M: David Härdeman <david@hardeman.nu>
S: Maintained
F: drivers/input/misc/winbond-cir.c
@@ -5785,9 +5846,7 @@ F: drivers/input/touchscreen/*wm97*
F: include/linux/wm97xx.h
WOLFSON MICROELECTRONICS PMIC DRIVERS
-P: Mark Brown
-M: broonie@opensource.wolfsonmicro.com
-L: linux-kernel@vger.kernel.org
+M: Mark Brown <broonie@opensource.wolfsonmicro.com>
T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
W: http://opensource.wolfsonmicro.com/node/8
S: Supported
diff --git a/Makefile b/Makefile
index 326791575b0a..33d4732a6c4a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 32
-EXTRAVERSION = -rc4
+EXTRAVERSION =
NAME = Man-Eating Seals of Antiquity
# *DOCUMENTATION*
@@ -221,7 +221,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
HOSTCC = gcc
HOSTCXX = g++
-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTCXXFLAGS = -O2
# Decide whether to build built-in, modular, or both.
@@ -379,6 +379,7 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exc
PHONY += scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
+ $(Q)rm -f .tmp_quiet_recordmcount
# To avoid any implicit rule to kick in, define an empty command.
scripts/basic/%: scripts_basic ;
diff --git a/arch/Kconfig b/arch/Kconfig
index 7f418bbc261a..eef3bbb97075 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -126,4 +126,11 @@ config HAVE_DMA_API_DEBUG
config HAVE_DEFAULT_NO_SPIN_MUTEXES
bool
+config HAVE_HW_BREAKPOINT
+ bool
+ depends on HAVE_PERF_EVENTS
+ select ANON_INODES
+ select PERF_EVENTS
+
+
source "kernel/gcov/Kconfig"
diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c
index 9d0727d18aee..367d53d031fc 100644
--- a/arch/alpha/boot/tools/objstrip.c
+++ b/arch/alpha/boot/tools/objstrip.c
@@ -35,7 +35,7 @@
const char * prog_name;
-void
+static void
usage (void)
{
fprintf(stderr,
diff --git a/arch/alpha/include/asm/fcntl.h b/arch/alpha/include/asm/fcntl.h
index e42823e954aa..25da0017ec87 100644
--- a/arch/alpha/include/asm/fcntl.h
+++ b/arch/alpha/include/asm/fcntl.h
@@ -26,8 +26,6 @@
#define F_GETOWN 6 /* for sockets. */
#define F_SETSIG 10 /* for sockets. */
#define F_GETSIG 11 /* for sockets. */
-#define F_SETOWN_EX 12
-#define F_GETOWN_EX 13
/* for posix fcntl() and lockf() */
#define F_RDLCK 1
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index 5076a8860b18..b3e888638bb7 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -50,32 +50,35 @@ struct thread_info {
register struct thread_info *__current_thread_info __asm__("$8");
#define current_thread_info() __current_thread_info
+#endif /* __ASSEMBLY__ */
+
/* Thread information allocation. */
#define THREAD_SIZE_ORDER 1
#define THREAD_SIZE (2*PAGE_SIZE)
-#endif /* __ASSEMBLY__ */
-
#define PREEMPT_ACTIVE 0x40000000
/*
* Thread information flags:
* - these are process state flags and used from assembly
- * - pending work-to-be-done flags come first to fit in and immediate operand.
+ * - pending work-to-be-done flags come first and must be assigned to be
+ * within bits 0 to 7 to fit in and immediate operand.
+ * - ALPHA_UAC_SHIFT below must be kept consistent with the unaligned
+ * control flags.
*
* TIF_SYSCALL_TRACE is known to be 0 via blbs.
*/
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
-#define TIF_SIGPENDING 1 /* signal pending */
-#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG 3 /* poll_idle is polling NEED_RESCHED */
-#define TIF_DIE_IF_KERNEL 4 /* dik recursion lock */
-#define TIF_UAC_NOPRINT 5 /* see sysinfo.h */
-#define TIF_UAC_NOFIX 6
-#define TIF_UAC_SIGBUS 7
-#define TIF_MEMDIE 8
-#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */
-#define TIF_NOTIFY_RESUME 10 /* callback before returning to user */
+#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
+#define TIF_SIGPENDING 2 /* signal pending */
+#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+#define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */
+#define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */
+#define TIF_UAC_NOPRINT 10 /* see sysinfo.h */
+#define TIF_UAC_NOFIX 11
+#define TIF_UAC_SIGBUS 12
+#define TIF_MEMDIE 13
+#define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */
#define TIF_FREEZE 16 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -94,7 +97,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \
| _TIF_SYSCALL_TRACE)
-#define ALPHA_UAC_SHIFT 6
+#define ALPHA_UAC_SHIFT 10
#define ALPHA_UAC_MASK (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \
1 << TIF_UAC_SIGBUS)
diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
index 8e059e58b0ac..53dd2f1a53aa 100644
--- a/arch/alpha/kernel/core_marvel.c
+++ b/arch/alpha/kernel/core_marvel.c
@@ -1103,6 +1103,8 @@ marvel_agp_info(void)
* Allocate the info structure.
*/
agp = kmalloc(sizeof(*agp), GFP_KERNEL);
+ if (!agp)
+ return NULL;
/*
* Fill it in.
diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
index 76686497b1e2..219bf271c0ba 100644
--- a/arch/alpha/kernel/core_titan.c
+++ b/arch/alpha/kernel/core_titan.c
@@ -757,6 +757,8 @@ titan_agp_info(void)
* Allocate the info structure.
*/
agp = kmalloc(sizeof(*agp), GFP_KERNEL);
+ if (!agp)
+ return NULL;
/*
* Fill it in.
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index cc7834661427..c0de072b8305 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -92,7 +92,7 @@ show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
#endif
- seq_printf(p, " %14s", irq_desc[irq].chip->typename);
+ seq_printf(p, " %14s", irq_desc[irq].chip->name);
seq_printf(p, " %c%s",
(action->flags & IRQF_DISABLED)?'+':' ',
action->name);
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index 38c805dfc544..cfde865b78e0 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -228,7 +228,7 @@ struct irqaction timer_irqaction = {
};
static struct irq_chip rtc_irq_type = {
- .typename = "RTC",
+ .name = "RTC",
.startup = rtc_startup,
.shutdown = rtc_enable_disable,
.enable = rtc_enable_disable,
diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c
index 50bfec9b588f..83a9ac280890 100644
--- a/arch/alpha/kernel/irq_i8259.c
+++ b/arch/alpha/kernel/irq_i8259.c
@@ -84,7 +84,7 @@ i8259a_end_irq(unsigned int irq)
}
struct irq_chip i8259a_irq_type = {
- .typename = "XT-PIC",
+ .name = "XT-PIC",
.startup = i8259a_startup_irq,
.shutdown = i8259a_disable_irq,
.enable = i8259a_enable_irq,
diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c
index 69199a76ec4a..989ce46a0cf3 100644
--- a/arch/alpha/kernel/irq_pyxis.c
+++ b/arch/alpha/kernel/irq_pyxis.c
@@ -71,7 +71,7 @@ pyxis_mask_and_ack_irq(unsigned int irq)
}
static struct irq_chip pyxis_irq_type = {
- .typename = "PYXIS",
+ .name = "PYXIS",
.startup = pyxis_startup_irq,
.shutdown = pyxis_disable_irq,
.enable = pyxis_enable_irq,
diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c
index 85229369a1f8..d63e93e1e8bf 100644
--- a/arch/alpha/kernel/irq_srm.c
+++ b/arch/alpha/kernel/irq_srm.c
@@ -49,7 +49,7 @@ srm_end_irq(unsigned int irq)
/* Handle interrupts from the SRM, assuming no additional weirdness. */
static struct irq_chip srm_irq_type = {
- .typename = "SRM",
+ .name = "SRM",
.startup = srm_startup_irq,
.shutdown = srm_disable_irq,
.enable = srm_enable_irq,
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index 382035ef7394..20a30b8b9655 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -90,7 +90,7 @@ alcor_end_irq(unsigned int irq)
}
static struct irq_chip alcor_irq_type = {
- .typename = "ALCOR",
+ .name = "ALCOR",
.startup = alcor_startup_irq,
.shutdown = alcor_disable_irq,
.enable = alcor_enable_irq,
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
index ed349436732b..affd0f3f25df 100644
--- a/arch/alpha/kernel/sys_cabriolet.c
+++ b/arch/alpha/kernel/sys_cabriolet.c
@@ -72,7 +72,7 @@ cabriolet_end_irq(unsigned int irq)
}
static struct irq_chip cabriolet_irq_type = {
- .typename = "CABRIOLET",
+ .name = "CABRIOLET",
.startup = cabriolet_startup_irq,
.shutdown = cabriolet_disable_irq,
.enable = cabriolet_enable_irq,
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 46e70ece5176..d64e1e497e76 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -199,7 +199,7 @@ clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
}
static struct irq_chip dp264_irq_type = {
- .typename = "DP264",
+ .name = "DP264",
.startup = dp264_startup_irq,
.shutdown = dp264_disable_irq,
.enable = dp264_enable_irq,
@@ -210,7 +210,7 @@ static struct irq_chip dp264_irq_type = {
};
static struct irq_chip clipper_irq_type = {
- .typename = "CLIPPER",
+ .name = "CLIPPER",
.startup = clipper_startup_irq,
.shutdown = clipper_disable_irq,
.enable = clipper_enable_irq,
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
index 660c23ef661f..df2090ce5e7f 100644
--- a/arch/alpha/kernel/sys_eb64p.c
+++ b/arch/alpha/kernel/sys_eb64p.c
@@ -70,7 +70,7 @@ eb64p_end_irq(unsigned int irq)
}
static struct irq_chip eb64p_irq_type = {
- .typename = "EB64P",
+ .name = "EB64P",
.startup = eb64p_startup_irq,
.shutdown = eb64p_disable_irq,
.enable = eb64p_enable_irq,
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
index b99ea488d844..3ca1dbcf4044 100644
--- a/arch/alpha/kernel/sys_eiger.c
+++ b/arch/alpha/kernel/sys_eiger.c
@@ -81,7 +81,7 @@ eiger_end_irq(unsigned int irq)
}
static struct irq_chip eiger_irq_type = {
- .typename = "EIGER",
+ .name = "EIGER",
.startup = eiger_startup_irq,
.shutdown = eiger_disable_irq,
.enable = eiger_enable_irq,
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index ef0b83a070ac..7a7ae36fff91 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -119,7 +119,7 @@ jensen_local_end(unsigned int irq)
}
static struct irq_chip jensen_local_irq_type = {
- .typename = "LOCAL",
+ .name = "LOCAL",
.startup = jensen_local_startup,
.shutdown = jensen_local_shutdown,
.enable = jensen_local_enable,
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index bbfc4f20ca72..0bb3b5c4f693 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -170,7 +170,7 @@ marvel_irq_noop_return(unsigned int irq)
}
static struct irq_chip marvel_legacy_irq_type = {
- .typename = "LEGACY",
+ .name = "LEGACY",
.startup = marvel_irq_noop_return,
.shutdown = marvel_irq_noop,
.enable = marvel_irq_noop,
@@ -180,7 +180,7 @@ static struct irq_chip marvel_legacy_irq_type = {
};
static struct irq_chip io7_lsi_irq_type = {
- .typename = "LSI",
+ .name = "LSI",
.startup = io7_startup_irq,
.shutdown = io7_disable_irq,
.enable = io7_enable_irq,
@@ -190,7 +190,7 @@ static struct irq_chip io7_lsi_irq_type = {
};
static struct irq_chip io7_msi_irq_type = {
- .typename = "MSI",
+ .name = "MSI",
.startup = io7_startup_irq,
.shutdown = io7_disable_irq,
.enable = io7_enable_irq,
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index 4e366641a08e..ee8865169811 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -69,7 +69,7 @@ mikasa_end_irq(unsigned int irq)
}
static struct irq_chip mikasa_irq_type = {
- .typename = "MIKASA",
+ .name = "MIKASA",
.startup = mikasa_startup_irq,
.shutdown = mikasa_disable_irq,
.enable = mikasa_enable_irq,
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index 35753a173bac..86503fe73a88 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -74,7 +74,7 @@ noritake_end_irq(unsigned int irq)
}
static struct irq_chip noritake_irq_type = {
- .typename = "NORITAKE",
+ .name = "NORITAKE",
.startup = noritake_startup_irq,
.shutdown = noritake_disable_irq,
.enable = noritake_enable_irq,
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index f3aec7e085c8..26c322bf89ee 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -136,7 +136,7 @@ rawhide_end_irq(unsigned int irq)
}
static struct irq_chip rawhide_irq_type = {
- .typename = "RAWHIDE",
+ .name = "RAWHIDE",
.startup = rawhide_startup_irq,
.shutdown = rawhide_disable_irq,
.enable = rawhide_enable_irq,
diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c
index d9f9cfeb9931..8de1046fe91e 100644
--- a/arch/alpha/kernel/sys_ruffian.c
+++ b/arch/alpha/kernel/sys_ruffian.c
@@ -66,7 +66,7 @@ ruffian_init_irq(void)
common_init_isa_dma();
}
-#define RUFFIAN_LATCH ((PIT_TICK_RATE + HZ / 2) / HZ)
+#define RUFFIAN_LATCH DIV_ROUND_CLOSEST(PIT_TICK_RATE, HZ)
static void __init
ruffian_init_rtc(void)
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
index fc9246373452..be161129eab9 100644
--- a/arch/alpha/kernel/sys_rx164.c
+++ b/arch/alpha/kernel/sys_rx164.c
@@ -73,7 +73,7 @@ rx164_end_irq(unsigned int irq)
}
static struct irq_chip rx164_irq_type = {
- .typename = "RX164",
+ .name = "RX164",
.startup = rx164_startup_irq,
.shutdown = rx164_disable_irq,
.enable = rx164_enable_irq,
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index 426eb6906d01..b2abe27a23cf 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -502,7 +502,7 @@ sable_lynx_mask_and_ack_irq(unsigned int irq)
}
static struct irq_chip sable_lynx_irq_type = {
- .typename = "SABLE/LYNX",
+ .name = "SABLE/LYNX",
.startup = sable_lynx_startup_irq,
.shutdown = sable_lynx_disable_irq,
.enable = sable_lynx_enable_irq,
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
index 830318c21661..230464885b5c 100644
--- a/arch/alpha/kernel/sys_takara.c
+++ b/arch/alpha/kernel/sys_takara.c
@@ -75,7 +75,7 @@ takara_end_irq(unsigned int irq)
}
static struct irq_chip takara_irq_type = {
- .typename = "TAKARA",
+ .name = "TAKARA",
.startup = takara_startup_irq,
.shutdown = takara_disable_irq,
.enable = takara_enable_irq,
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 88978fc60f83..288053342c83 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -195,7 +195,7 @@ init_titan_irqs(struct irq_chip * ops, int imin, int imax)
}
static struct irq_chip titan_irq_type = {
- .typename = "TITAN",
+ .name = "TITAN",
.startup = titan_startup_irq,
.shutdown = titan_disable_irq,
.enable = titan_enable_irq,
diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
index e91b4c3838a8..62fd972e18ef 100644
--- a/arch/alpha/kernel/sys_wildfire.c
+++ b/arch/alpha/kernel/sys_wildfire.c
@@ -158,7 +158,7 @@ wildfire_end_irq(unsigned int irq)
}
static struct irq_chip wildfire_irq_type = {
- .typename = "WILDFIRE",
+ .name = "WILDFIRE",
.startup = wildfire_startup_irq,
.shutdown = wildfire_disable_irq,
.enable = wildfire_enable_irq,
diff --git a/arch/arm/configs/ams_delta_defconfig b/arch/arm/configs/ams_delta_defconfig
index 764732529ea3..e8f7380b67d6 100644
--- a/arch/arm/configs/ams_delta_defconfig
+++ b/arch/arm/configs/ams_delta_defconfig
@@ -55,10 +55,10 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
-# CONFIG_EMBEDDED is not set
+CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS is not set
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
@@ -224,7 +224,7 @@ CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
-# CONFIG_ARM_THUMB is not set
+CONFIG_ARM_THUMB=y
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
CONFIG_CPU_DCACHE_WRITETHROUGH=y
@@ -248,7 +248,7 @@ CONFIG_CPU_DCACHE_WRITETHROUGH=y
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_PREEMPT=y
CONFIG_HZ=100
-# CONFIG_AEABI is not set
+CONFIG_AEABI=y
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -299,7 +299,9 @@ CONFIG_BINFMT_ELF=y
#
# Power management options
#
-# CONFIG_PM is not set
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
#
# Networking
@@ -670,7 +672,7 @@ 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_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
@@ -784,6 +786,7 @@ CONFIG_I2C_OMAP=y
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
+CONFIG_GPIO_SYSFS=y
#
# Dallas's 1-wire bus
@@ -820,6 +823,7 @@ CONFIG_LEDS_AMS_DELTA=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
#
# Multimedia devices
@@ -896,7 +900,13 @@ CONFIG_LOGO_LINUX_CLUT224=y
#
# Sound
#
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_OMAP_SOC_AMS_DELTA=y
#
# HID Devices
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
index af74cc2de8b6..bcfade33bca9 100644
--- a/arch/arm/configs/kirkwood_defconfig
+++ b/arch/arm/configs/kirkwood_defconfig
@@ -1,15 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc4
-# Mon May 4 11:58:57 2009
+# Linux kernel version: 2.6.32-rc6
+# Sat Nov 7 20:31:18 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,13 +16,12 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -46,11 +43,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=19
# CONFIG_GROUP_SCHED is not set
@@ -73,7 +71,6 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -86,6 +83,10 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
@@ -95,13 +96,17 @@ CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
-# CONFIG_MARKERS is not set
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
@@ -114,7 +119,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -135,19 +140,22 @@ CONFIG_DEFAULT_IOSCHED="cfq"
#
# System Type
#
+CONFIG_MMU=y
# CONFIG_ARCH_AAEC2000 is not set
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_NOMADIK is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
@@ -156,25 +164,27 @@ CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
CONFIG_ARCH_KIRKWOOD=y
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_LOKI is not set
# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_MSM is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_BCMRING is not set
#
# Marvell Kirkwood Implementations
@@ -185,6 +195,7 @@ CONFIG_MACH_RD88F6281=y
CONFIG_MACH_MV88F6281GTW_GE=y
CONFIG_MACH_SHEEVAPLUG=y
CONFIG_MACH_TS219=y
+CONFIG_MACH_OPENRD_BASE=y
CONFIG_PLAT_ORION=y
#
@@ -195,7 +206,7 @@ CONFIG_CPU_FEROCEON=y
# CONFIG_CPU_FEROCEON_OLD_ID is not set
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_FEROCEON=y
CONFIG_CPU_TLB_FEROCEON=y
@@ -211,6 +222,7 @@ CONFIG_ARM_THUMB=y
CONFIG_OUTER_CACHE=y
CONFIG_CACHE_FEROCEON_L2=y
# CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
#
# Bus support
@@ -235,11 +247,12 @@ CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_HZ=100
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_HIGHMEM is not set
@@ -254,10 +267,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ALIGNMENT_TRAP=y
+CONFIG_UACCESS_WITH_MEMCPY=y
#
# Boot options
@@ -345,6 +360,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -367,6 +383,7 @@ CONFIG_NET_DSA_MV88E6123_61_65=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -383,17 +400,18 @@ CONFIG_NET_PKTGEN=m
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEFAULT_PS_VALUE=1
+# CONFIG_CFG80211_DEBUGFS is not set
CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
CONFIG_LIB80211=y
# CONFIG_LIB80211_DEBUG is not set
CONFIG_MAC80211=y
-
-#
-# Rate control algorithm selection
-#
CONFIG_MAC80211_RC_MINSTREL=y
# CONFIG_MAC80211_RC_DEFAULT_PID is not set
CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
@@ -414,6 +432,7 @@ CONFIG_MAC80211_RC_DEFAULT="minstrel"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -425,9 +444,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@@ -494,6 +513,7 @@ CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_DATAFLASH is not set
CONFIG_MTD_M25P80=y
CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -543,6 +563,7 @@ 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
+# CONFIG_MG_DISK is not set
# CONFIG_MISC_DEVICES is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -567,10 +588,6 @@ CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
@@ -587,6 +604,8 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -595,6 +614,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
@@ -611,7 +631,6 @@ 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
@@ -623,11 +642,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SIL24 is not set
@@ -649,6 +671,7 @@ CONFIG_SATA_MV=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -676,6 +699,7 @@ CONFIG_SATA_MV=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -693,13 +717,16 @@ CONFIG_SATA_MV=y
#
#
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -768,6 +795,9 @@ CONFIG_NET_PCI=y
# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
@@ -789,6 +819,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
CONFIG_MV643XX_ETH=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
@@ -797,10 +828,7 @@ CONFIG_MV643XX_ETH=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
CONFIG_WLAN_80211=y
CONFIG_LIBERTAS=y
@@ -820,9 +848,7 @@ CONFIG_LIBERTAS_SDIO=y
# CONFIG_MAC80211_HWSIM is not set
# CONFIG_MWL8K is not set
# CONFIG_P54_COMMON is not set
-# CONFIG_ATH5K is not set
-# CONFIG_ATH9K is not set
-# CONFIG_AR9170_USB is not set
+# CONFIG_ATH_COMMON is not set
# CONFIG_IPW2100 is not set
# CONFIG_IPW2200 is not set
# CONFIG_IWLWIFI is not set
@@ -832,6 +858,8 @@ CONFIG_LIBERTAS_SDIO=y
# CONFIG_ZD1211RW is not set
# CONFIG_RT2X00 is not set
# CONFIG_HERMES is not set
+# CONFIG_WL12XX is not set
+# CONFIG_IWM is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -855,6 +883,7 @@ CONFIG_LIBERTAS_SDIO=y
# 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
@@ -878,13 +907,19 @@ CONFIG_INPUT_EVDEV=y
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
@@ -943,6 +978,7 @@ CONFIG_LEGACY_PTY_COUNT=16
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -998,10 +1034,6 @@ CONFIG_I2C_MV64XXX=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1023,11 +1055,47 @@ CONFIG_SPI_ORION=y
#
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1041,33 +1109,28 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1087,7 +1150,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1106,10 +1168,12 @@ CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
CONFIG_HID_KYE=y
CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1123,9 +1187,14 @@ CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
@@ -1150,18 +1219,21 @@ CONFIG_USB_DEVICE_CLASS=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_WHCI_HCD is not set
# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
#
# USB Device Class drivers
@@ -1252,11 +1324,14 @@ CONFIG_SDIO_UART=y
# MMC/SD/SDIO Host Controller Drivers
#
# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
# CONFIG_MMC_TIFM_SD is not set
CONFIG_MMC_MVSDIO=y
# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_CB710 is not set
+# CONFIG_MMC_VIA_SDMMC is not set
# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
@@ -1266,7 +1341,7 @@ CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_GPIO_PLATFORM=y
-# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_DAC124S085 is not set
# CONFIG_LEDS_BD2802 is not set
@@ -1278,11 +1353,14 @@ CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
#
# iptables trigger is under Netfilter config (LED target)
#
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -1314,6 +1392,7 @@ CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_DRV_S35390A=y
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
#
# SPI RTC drivers
@@ -1325,6 +1404,7 @@ CONFIG_RTC_DRV_S35390A=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1360,8 +1440,11 @@ CONFIG_DMA_ENGINE=y
# CONFIG_ASYNC_TX_DMA is not set
# CONFIG_DMATEST is not set
# CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -1379,10 +1462,13 @@ CONFIG_JBD=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1455,7 +1541,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1530,6 +1615,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -1547,6 +1633,7 @@ CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
@@ -1567,12 +1654,14 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
@@ -1581,25 +1670,12 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_FTRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1623,7 +1699,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1665,11 +1740,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1714,6 +1791,7 @@ CONFIG_CRYPTO_ARC4=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_MV_CESA=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
CONFIG_BINARY_PRINTF=y
diff --git a/arch/arm/configs/n8x0_defconfig b/arch/arm/configs/n8x0_defconfig
index 8da75dede52e..264f52b5c52d 100644
--- a/arch/arm/configs/n8x0_defconfig
+++ b/arch/arm/configs/n8x0_defconfig
@@ -304,7 +304,7 @@ CONFIG_ALIGNMENT_TRAP=y
CONFIG_ZBOOT_ROM_TEXT=0x10C08000
CONFIG_ZBOOT_ROM_BSS=0x10200000
# CONFIG_ZBOOT_ROM is not set
-CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 console=ttyS0,115200n8"
+CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 console=ttyS2,115200n8"
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set
diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig
index 357d4021e2d0..b3c8cce0f8fb 100644
--- a/arch/arm/configs/omap3_beagle_defconfig
+++ b/arch/arm/configs/omap3_beagle_defconfig
@@ -969,7 +969,6 @@ CONFIG_USB_ETH_RNDIS=y
#
CONFIG_USB_OTG_UTILS=y
# CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_ISP1301_OMAP is not set
CONFIG_TWL4030_USB=y
# CONFIG_NOP_USB_XCEIV is not set
CONFIG_MMC=y
diff --git a/arch/arm/configs/omap3_pandora_defconfig b/arch/arm/configs/omap3_pandora_defconfig
index b54ad2e2da36..150deafb0a6a 100644
--- a/arch/arm/configs/omap3_pandora_defconfig
+++ b/arch/arm/configs/omap3_pandora_defconfig
@@ -611,7 +611,7 @@ CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
# CONFIG_MOUSE_SERIAL is not set
@@ -634,7 +634,8 @@ CONFIG_TOUCHSCREEN_ADS7846=y
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_INPUT_MISC is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_TWL4030_PWRBUTTON=y
#
# Hardware I/O ports
@@ -834,7 +835,29 @@ CONFIG_DAB=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_USB=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_OMAP_SOC_MCBSP=y
+CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+CONFIG_SND_SOC_TWL4030=y
+
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
@@ -1020,7 +1043,13 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_MMC_SPI is not set
# CONFIG_MEMSTICK is not set
# CONFIG_ACCESSIBILITY is not set
-# CONFIG_NEW_LEDS is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -1084,9 +1113,12 @@ CONFIG_RTC_DRV_TWL4030=y
# on-CPU RTC drivers
#
# CONFIG_DMADEVICES is not set
-# CONFIG_REGULATOR is not set
# CONFIG_UIO is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_TWL4030=y
+
#
# File systems
#
@@ -1407,3 +1439,10 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+
+# added by hand for now
+CONFIG_KEYBOARD_TWL4030=y
+CONFIG_USB_OTG_UTILS=y
+CONFIG_TWL4030_USB=y
+CONFIG_MMC_OMAP_HS=y
+
diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig
index 8a4a7e2ba87b..5a305f015307 100644
--- a/arch/arm/configs/omap_3430sdp_defconfig
+++ b/arch/arm/configs/omap_3430sdp_defconfig
@@ -1703,7 +1703,14 @@ CONFIG_RTC_DRV_TWL4030=y
# on-CPU RTC drivers
#
# CONFIG_DMADEVICES is not set
-# CONFIG_REGULATOR is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_TWL4030=y
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 9e2385293ecb..5383cd0dff54 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -1,15 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc4
-# Mon May 4 14:07:25 2009
+# Linux kernel version: 2.6.32-rc6
+# Sat Nov 7 20:52:21 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,13 +16,12 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -46,11 +43,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_GROUP_SCHED is not set
@@ -69,7 +67,6 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -82,6 +79,10 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
# CONFIG_SLUB_DEBUG is not set
@@ -91,13 +92,17 @@ CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
-# CONFIG_MARKERS is not set
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
@@ -109,7 +114,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -130,19 +135,22 @@ CONFIG_DEFAULT_IOSCHED="cfq"
#
# System Type
#
+CONFIG_MMU=y
# CONFIG_ARCH_AAEC2000 is not set
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_NOMADIK is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
@@ -151,25 +159,27 @@ CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_LOKI is not set
# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
CONFIG_ARCH_ORION5X=y
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_MSM is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_BCMRING is not set
#
# Orion Implementations
@@ -187,6 +197,9 @@ CONFIG_MACH_WRT350N_V2=y
CONFIG_MACH_TS78XX=y
CONFIG_MACH_MV2120=y
CONFIG_MACH_EDMINI_V2=y
+CONFIG_MACH_D2NET=y
+CONFIG_MACH_BIGDISK=y
+CONFIG_MACH_NET2BIG=y
CONFIG_MACH_MSS2=y
CONFIG_MACH_WNR854T=y
CONFIG_MACH_RD88F5181L_GE=y
@@ -202,7 +215,7 @@ CONFIG_CPU_FEROCEON=y
CONFIG_CPU_FEROCEON_OLD_ID=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_FEROCEON=y
CONFIG_CPU_TLB_FEROCEON=y
@@ -215,7 +228,7 @@ CONFIG_CPU_CP15_MMU=y
CONFIG_ARM_THUMB=y
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_OUTER_CACHE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
#
# Bus support
@@ -240,11 +253,12 @@ CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_HIGHMEM is not set
@@ -259,12 +273,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_LEDS=y
CONFIG_LEDS_CPU=y
CONFIG_ALIGNMENT_TRAP=y
+CONFIG_UACCESS_WITH_MEMCPY=y
#
# Boot options
@@ -308,6 +324,7 @@ CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
# CONFIG_SUSPEND is not set
# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
@@ -356,6 +373,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -378,6 +396,7 @@ CONFIG_NET_DSA_MV88E6123_61_65=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -394,11 +413,15 @@ CONFIG_NET_PKTGEN=m
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
# CONFIG_WIRELESS_OLD_REGULATORY is not set
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
-# CONFIG_MAC80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -411,6 +434,7 @@ CONFIG_WIRELESS_EXT_SYSFS=y
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -422,9 +446,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@@ -537,6 +561,7 @@ 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
+# CONFIG_MG_DISK is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
# CONFIG_SGI_IOC4 is not set
@@ -552,7 +577,9 @@ CONFIG_MISC_DEVICES=y
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -576,10 +603,6 @@ CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
@@ -596,6 +619,8 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -604,6 +629,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
@@ -620,7 +646,6 @@ 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
@@ -632,11 +657,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -658,6 +686,7 @@ CONFIG_SATA_MV=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -685,6 +714,7 @@ CONFIG_SATA_MV=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -703,13 +733,16 @@ CONFIG_SATA_MV=y
#
#
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -777,6 +810,8 @@ CONFIG_NET_PCI=y
# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
@@ -798,6 +833,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
CONFIG_MV643XX_ETH=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
@@ -806,10 +842,7 @@ CONFIG_MV643XX_ETH=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -835,6 +868,7 @@ CONFIG_MV643XX_ETH=y
# 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
@@ -855,13 +889,19 @@ CONFIG_INPUT_EVDEV=y
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
@@ -912,6 +952,7 @@ CONFIG_HW_RANDOM_TIMERIOMEM=m
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -967,20 +1008,55 @@ CONFIG_I2C_MV64XXX=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1030,6 +1106,8 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1041,9 +1119,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1057,33 +1133,26 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
+# CONFIG_VGA_ARB is not set
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1097,7 +1166,6 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1116,10 +1184,11 @@ CONFIG_USB_HID=y
# CONFIG_HID_CHERRY is not set
# CONFIG_HID_CHICONY is not set
# CONFIG_HID_CYPRESS is not set
-# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_DRAGONRISE is not set
# CONFIG_HID_EZKEY is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LOGITECH is not set
# CONFIG_HID_MICROSOFT is not set
@@ -1130,10 +1199,11 @@ CONFIG_USB_HID=y
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SONY is not set
# CONFIG_HID_SUNPLUS is not set
-# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
# CONFIG_HID_TOPSEED is not set
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1160,18 +1230,21 @@ CONFIG_USB_DEVICE_CLASS=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_WHCI_HCD is not set
# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
#
# USB Device Class drivers
@@ -1248,7 +1321,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
@@ -1258,7 +1330,7 @@ CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_GPIO_PLATFORM=y
-# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_BD2802 is not set
@@ -1269,11 +1341,14 @@ CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
#
# iptables trigger is under Netfilter config (LED target)
#
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -1306,6 +1381,7 @@ CONFIG_RTC_DRV_M41T80=y
CONFIG_RTC_DRV_S35390A=y
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
#
# SPI RTC drivers
@@ -1344,8 +1420,11 @@ CONFIG_DMA_ENGINE=y
# CONFIG_ASYNC_TX_DMA is not set
# CONFIG_DMATEST is not set
# CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -1358,10 +1437,10 @@ CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_EXT4_FS=m
-# CONFIG_EXT4DEV_COMPAT is not set
CONFIG_EXT4_FS_XATTR=y
# CONFIG_EXT4_FS_POSIX_ACL is not set
# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_JBD2=m
@@ -1370,10 +1449,13 @@ CONFIG_FS_MBCACHE=m
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1446,7 +1528,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1537,6 +1618,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -1552,6 +1634,7 @@ CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
@@ -1572,6 +1655,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
CONFIG_FRAME_POINTER=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
@@ -1579,6 +1663,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_LATENCYTOP=y
@@ -1587,25 +1672,12 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_FTRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1629,20 +1701,19 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
-CONFIG_CRYPTO_ALGAPI=m
-CONFIG_CRYPTO_ALGAPI2=m
-CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_BLKCIPHER2=m
-CONFIG_CRYPTO_HASH2=m
-CONFIG_CRYPTO_RNG2=m
-CONFIG_CRYPTO_PCOMP=m
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=m
-CONFIG_CRYPTO_MANAGER2=m
+CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
-CONFIG_CRYPTO_WORKQUEUE=m
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1670,11 +1741,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1691,7 +1764,7 @@ CONFIG_CRYPTO_PCBC=m
#
# Ciphers
#
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
@@ -1719,6 +1792,7 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_MV_CESA=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
CONFIG_BINARY_PRINTF=y
diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig
index 7d61ae6e75da..953ba0297fc4 100644
--- a/arch/arm/configs/u300_defconfig
+++ b/arch/arm/configs/u300_defconfig
@@ -1,14 +1,14 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc3
-# Thu Jul 16 23:36:10 2009
+# Linux kernel version: 2.6.32-rc5
+# Sat Oct 17 23:32:24 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
+CONFIG_HAVE_TCM=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -44,11 +44,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_GROUP_SCHED is not set
@@ -80,17 +81,15 @@ CONFIG_SHMEM=y
# CONFIG_AIO is not set
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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
@@ -133,6 +132,7 @@ CONFIG_DEFAULT_IOSCHED="deadline"
#
# System Type
#
+CONFIG_MMU=y
# CONFIG_ARCH_AAEC2000 is not set
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_REALVIEW is not set
@@ -147,6 +147,7 @@ CONFIG_DEFAULT_IOSCHED="deadline"
# CONFIG_ARCH_STMP3XXX is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
@@ -169,11 +170,13 @@ CONFIG_DEFAULT_IOSCHED="deadline"
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
CONFIG_ARCH_U300=y
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
#
# ST-Ericsson AB U300/U330/U335/U365 Platform
@@ -195,6 +198,7 @@ CONFIG_MACH_U300_BS335=y
CONFIG_MACH_U300_DUAL_RAM=y
CONFIG_U300_DEBUG=y
# CONFIG_MACH_U300_SEMI_IS_SHARED is not set
+CONFIG_MACH_U300_SPIDUMMY=y
#
# All the settings below must match the bootloader's settings
@@ -207,7 +211,7 @@ CONFIG_CPU_32=y
CONFIG_CPU_ARM926T=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_TLB_V4WBI=y
@@ -222,6 +226,7 @@ CONFIG_ARM_THUMB=y
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_ARM_VIC=y
CONFIG_ARM_VIC_NR=2
CONFIG_COMMON_CLKDEV=y
@@ -245,6 +250,8 @@ CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_HZ=100
CONFIG_AEABI=y
@@ -265,6 +272,7 @@ CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_UACCESS_WITH_MEMCPY is not set
@@ -313,6 +321,7 @@ CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
# CONFIG_SUSPEND is not set
# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
@@ -351,6 +360,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -391,6 +401,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=y
@@ -402,9 +413,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@@ -453,6 +464,7 @@ CONFIG_MTD_CFI_I2=y
#
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -520,6 +532,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_MD is not set
# CONFIG_NETDEVICES is not set
# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
#
# Input device support
@@ -540,12 +553,16 @@ CONFIG_INPUT_EVDEV=y
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_KEYBOARD_MATRIX is not set
# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
@@ -597,6 +614,7 @@ CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
@@ -629,9 +647,6 @@ CONFIG_I2C_STU300=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -653,16 +668,21 @@ CONFIG_SPI_PL022=y
#
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
# CONFIG_W1 is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
# CONFIG_PDA_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
# CONFIG_BATTERY_BQ27x00 is not set
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -690,10 +710,24 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TC6387XB is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
CONFIG_AB3100_CORE=y
+CONFIG_AB3100_OTP=y
# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+CONFIG_REGULATOR_AB3100=y
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
# CONFIG_MEDIA_SUPPORT is not set
#
@@ -792,9 +826,10 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
CONFIG_MMC_ARMMMCI=y
# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
# CONFIG_MMC_SPI is not set
# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
@@ -820,10 +855,10 @@ CONFIG_LEDS_TRIGGER_BACKLIGHT=y
#
# iptables trigger is under Netfilter config (LED target)
#
+# CONFIG_ACCESSIBILITY is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_HCTOSYS is not set
# CONFIG_RTC_DEBUG is not set
#
@@ -863,6 +898,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -878,27 +914,25 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_AB3100=y
#
# on-CPU RTC drivers
#
# CONFIG_RTC_DRV_PL030 is not set
# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_RTC_DRV_COH901331=y
CONFIG_DMADEVICES=y
#
# DMA Devices
#
# CONFIG_AUXDISPLAY is not set
-CONFIG_REGULATOR=y
-# CONFIG_REGULATOR_DEBUG is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_REGULATOR_MAX1586 is not set
-# CONFIG_REGULATOR_LP3971 is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -913,6 +947,7 @@ CONFIG_REGULATOR=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
@@ -975,7 +1010,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
#
@@ -1033,6 +1067,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1066,11 +1101,13 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1121,6 +1158,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC32 is not set
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_ALLOCATOR=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index fd03fb63a332..3d0cdd21b882 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -414,9 +414,14 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
static inline void __flush_icache_all(void)
{
+#ifdef CONFIG_ARM_ERRATA_411920
+ extern void v6_icache_inval_all(void);
+ v6_icache_inval_all();
+#else
asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
:
: "r" (0));
+#endif
}
#define ARCH_HAS_FLUSH_ANON_PAGE
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index c3b911ee9151..6aac3f5bb2f3 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -98,6 +98,9 @@ extern int elf_check_arch(const struct elf32_hdr *);
extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk)
+int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
+#define ELF_CORE_COPY_TASK_REGS dump_task_regs
+
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h
index d16ec97ec9a9..c019949a5189 100644
--- a/arch/arm/include/asm/kmap_types.h
+++ b/arch/arm/include/asm/kmap_types.h
@@ -22,4 +22,10 @@ enum km_type {
KM_TYPE_NR
};
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define KM_NMI (-1)
+#define KM_NMI_PTE (-1)
+#define KM_IRQ_PTE (-1)
+#endif
+
#endif
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index a45ab5dd8255..c2f1605de359 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -350,7 +350,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
if (tlb_flag(TLB_WB))
dsb();
- if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) {
+ if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
if (tlb_flag(TLB_V3_FULL))
asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
if (tlb_flag(TLB_V4_U_FULL))
@@ -360,6 +360,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
if (tlb_flag(TLB_V4_I_FULL))
asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
}
+ put_cpu();
if (tlb_flag(TLB_V6_U_ASID))
asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc");
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 7020217fc49f..4e506d09e5f9 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -403,6 +403,15 @@
#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
/*
+ * *NOTE*: This is a ghost syscall private to the kernel. Only the
+ * __kuser_cmpxchg code in entry-armv.S should be aware of its
+ * existence. Don't ever use this from user code.
+ */
+#ifdef __KERNEL__
+#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)
+#endif
+
+/*
* The following syscalls are obsolete and no longer available for EABI.
*/
#if defined(__ARM_EABI__) && !defined(__KERNEL__)
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 322410be573c..d2903e3bc861 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -21,6 +21,7 @@
#include <mach/entry-macro.S>
#include <asm/thread_notify.h>
#include <asm/unwind.h>
+#include <asm/unistd.h>
#include "entry-header.S"
@@ -608,33 +609,33 @@ call_fpe:
THUMB( add pc, r8 )
nop
- W(mov) pc, lr @ CP#0
+ movw_pc lr @ CP#0
W(b) do_fpe @ CP#1 (FPE)
W(b) do_fpe @ CP#2 (FPE)
- W(mov) pc, lr @ CP#3
+ movw_pc lr @ CP#3
#ifdef CONFIG_CRUNCH
b crunch_task_enable @ CP#4 (MaverickCrunch)
b crunch_task_enable @ CP#5 (MaverickCrunch)
b crunch_task_enable @ CP#6 (MaverickCrunch)
#else
- W(mov) pc, lr @ CP#4
- W(mov) pc, lr @ CP#5
- W(mov) pc, lr @ CP#6
+ movw_pc lr @ CP#4
+ movw_pc lr @ CP#5
+ movw_pc lr @ CP#6
#endif
- W(mov) pc, lr @ CP#7
- W(mov) pc, lr @ CP#8
- W(mov) pc, lr @ CP#9
+ movw_pc lr @ CP#7
+ movw_pc lr @ CP#8
+ movw_pc lr @ CP#9
#ifdef CONFIG_VFP
W(b) do_vfp @ CP#10 (VFP)
W(b) do_vfp @ CP#11 (VFP)
#else
- W(mov) pc, lr @ CP#10 (VFP)
- W(mov) pc, lr @ CP#11 (VFP)
+ movw_pc lr @ CP#10 (VFP)
+ movw_pc lr @ CP#11 (VFP)
#endif
- W(mov) pc, lr @ CP#12
- W(mov) pc, lr @ CP#13
- W(mov) pc, lr @ CP#14 (Debug)
- W(mov) pc, lr @ CP#15 (Control)
+ movw_pc lr @ CP#12
+ movw_pc lr @ CP#13
+ movw_pc lr @ CP#14 (Debug)
+ movw_pc lr @ CP#15 (Control)
#ifdef CONFIG_NEON
.align 6
@@ -908,10 +909,10 @@ __kuser_cmpxchg: @ 0xffff0fc0
* A special ghost syscall is used for that (see traps.c).
*/
stmfd sp!, {r7, lr}
- mov r7, #0xff00 @ 0xfff0 into r7 for EABI
- orr r7, r7, #0xf0
- swi #0x9ffff0
+ ldr r7, =1f @ it's 20 bits
+ swi __ARM_NR_cmpxchg
ldmfd sp!, {r7, pc}
+1: .word __ARM_NR_cmpxchg
#elif __LINUX_ARM_ARCH__ < 6
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index ac34c0d9384b..7e9ed1eea40a 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -110,6 +110,13 @@
mov \rd, sp, lsr #13
mov \rd, \rd, lsl #13
.endm
+
+ @
+ @ 32-bit wide "mov pc, reg"
+ @
+ .macro movw_pc, reg
+ mov pc, \reg
+ .endm
#else /* CONFIG_THUMB2_KERNEL */
.macro svc_exit, rpsr
clrex @ clear the exclusive monitor
@@ -146,6 +153,14 @@
lsr \rd, \rd, #13
mov \rd, \rd, lsl #13
.endm
+
+ @
+ @ 32-bit wide "mov pc, reg"
+ @
+ .macro movw_pc, reg
+ mov pc, \reg
+ nop
+ .endm
#endif /* !CONFIG_THUMB2_KERNEL */
/*
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 885a7214418d..b9505aa267c0 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -97,7 +97,7 @@ __error_a:
bl printhex8
adr r0, str_a2
bl printascii
- adr r3, 3f
+ adr r3, 4f
ldmia r3, {r4, r5, r6} @ get machine desc list
sub r4, r3, r4 @ get offset between virt&phys
add r5, r5, r4 @ convert virt addresses to
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 790fbee92ec5..0d96d0171c05 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -328,6 +328,15 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
}
/*
+ * Fill in the task's elfregs structure for a core dump.
+ */
+int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
+{
+ elf_core_copy_regs(elfregs, task_pt_regs(t));
+ return 1;
+}
+
+/*
* fill in the fpe structure for a core dump...
*/
int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 1423a3419789..e7714f367eb8 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/kernel/signal.c
*
- * Copyright (C) 1995-2002 Russell King
+ * Copyright (C) 1995-2009 Russell King
*
* 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
@@ -29,6 +29,7 @@
*/
#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
+#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)
/*
* With EABI, the syscall number has to be loaded into r7.
@@ -49,6 +50,18 @@ const unsigned long sigreturn_codes[7] = {
};
/*
+ * Either we support OABI only, or we have EABI with the OABI
+ * compat layer enabled. In the later case we don't know if
+ * user space is EABI or not, and if not we must not clobber r7.
+ * Always using the OABI syscall solves that issue and works for
+ * all those cases.
+ */
+const unsigned long syscall_restart_code[2] = {
+ SWI_SYS_RESTART, /* swi __NR_restart_syscall */
+ 0xe49df004, /* ldr pc, [sp], #4 */
+};
+
+/*
* atomically swap in the new signal mask, and wait for a signal.
*/
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
@@ -645,32 +658,16 @@ static void do_signal(struct pt_regs *regs, int syscall)
regs->ARM_pc -= 4;
#else
u32 __user *usp;
- u32 swival = __NR_restart_syscall;
- regs->ARM_sp -= 12;
+ regs->ARM_sp -= 4;
usp = (u32 __user *)regs->ARM_sp;
- /*
- * Either we supports OABI only, or we have
- * EABI with the OABI compat layer enabled.
- * In the later case we don't know if user
- * space is EABI or not, and if not we must
- * not clobber r7. Always using the OABI
- * syscall solves that issue and works for
- * all those cases.
- */
- swival = swival - __NR_SYSCALL_BASE + __NR_OABI_SYSCALL_BASE;
-
- put_user(regs->ARM_pc, &usp[0]);
- /* swi __NR_restart_syscall */
- put_user(0xef000000 | swival, &usp[1]);
- /* ldr pc, [sp], #12 */
- put_user(0xe49df00c, &usp[2]);
-
- flush_icache_range((unsigned long)usp,
- (unsigned long)(usp + 3));
-
- regs->ARM_pc = regs->ARM_sp + 4;
+ if (put_user(regs->ARM_pc, usp) == 0) {
+ regs->ARM_pc = KERN_RESTART_CODE;
+ } else {
+ regs->ARM_sp += 4;
+ force_sigsegv(0, current);
+ }
#endif
}
}
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
index 27beece15502..6fcfe8398aa4 100644
--- a/arch/arm/kernel/signal.h
+++ b/arch/arm/kernel/signal.h
@@ -1,12 +1,14 @@
/*
* linux/arch/arm/kernel/signal.h
*
- * Copyright (C) 2005 Russell King.
+ * Copyright (C) 2005-2009 Russell King.
*
* 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.
*/
#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
+#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
extern const unsigned long sigreturn_codes[7];
+extern const unsigned long syscall_restart_code[2];
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index d3831f616ee9..9ab4149bd983 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -37,6 +37,10 @@ void __init scu_enable(void __iomem *scu_base)
u32 scu_ctrl;
scu_ctrl = __raw_readl(scu_base + SCU_CTRL);
+ /* already enabled? */
+ if (scu_ctrl & 1)
+ return;
+
scu_ctrl |= 1;
__raw_writel(scu_ctrl, scu_base + SCU_CTRL);
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index f838f36eb702..3f361a783f43 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/kernel/traps.c
*
- * Copyright (C) 1995-2002 Russell King
+ * Copyright (C) 1995-2009 Russell King
* Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
*
* This program is free software; you can redistribute it and/or modify
@@ -528,7 +528,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
* __kuser_cmpxchg code in entry-armv.S should be aware of its
* existence. Don't ever use this from user code.
*/
- case 0xfff0:
+ case NR(cmpxchg):
for (;;) {
extern void do_DataAbort(unsigned long addr, unsigned int fsr,
struct pt_regs *regs);
@@ -573,7 +573,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
if not implemented, rather than raising SIGILL. This
way the calling program can gracefully determine whether
a feature is supported. */
- if (no <= 0x7ff)
+ if ((no & 0xffff) <= 0x7ff)
return -ENOSYS;
break;
}
@@ -751,6 +751,8 @@ void __init early_trap_init(void)
*/
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
sizeof(sigreturn_codes));
+ memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
+ sizeof(syscall_restart_code));
flush_icache_range(vectors, vectors + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 39baf1128bfa..786ac2b6914a 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -26,6 +26,15 @@
* http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
*/
+#if !defined (__ARM_EABI__)
+#warning Your compiler does not have EABI support.
+#warning ARM unwind is known to compile only with EABI compilers.
+#warning Change compiler or disable ARM_UNWIND option.
+#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2)
+#warning Your compiler is too buggy; it is known to not compile ARM unwind support.
+#warning Change compiler or disable ARM_UNWIND option.
+#endif
+
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index e35d54d43e70..2fd88437348b 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -289,13 +289,6 @@ config MACH_NEOCORE926
help
Select this if you are using the Adeneo Neocore 926 board.
-config MACH_AT91SAM9G20EK_2MMC
- bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots"
- depends on ARCH_AT91SAM9G20
- help
- Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
- Rev A or B modified for 2 MMC Slots.
-
endif
# ----------------------------------------------------------
@@ -322,7 +315,16 @@ config MACH_AT91SAM9G20EK
bool "Atmel AT91SAM9G20-EK Evaluation Kit"
depends on ARCH_AT91SAM9G20
help
- Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit.
+ Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit
+ that embeds only one SD/MMC slot.
+
+config MACH_AT91SAM9G20EK_2MMC
+ bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots"
+ depends on ARCH_AT91SAM9G20
+ help
+ Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
+ with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and
+ onwards.
config MACH_CPU9G20
bool "Eukrea CPU9G20 board"
@@ -392,7 +394,7 @@ config MTD_AT91_DATAFLASH_CARD
config MTD_NAND_ATMEL_BUSWIDTH_16
bool "Enable 16-bit data bus interface to NAND flash"
- depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK)
+ depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G20EK_2MMC || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK)
help
On AT91SAM926x boards both types of NAND flash can be present
(8 and 16 bit data bus width).
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index d581cff80c4c..332b784050b2 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -838,7 +838,7 @@ static void __init at91_add_device_rtt(void)
* Watchdog
* -------------------------------------------------------------------- */
-#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
static struct platform_device at91sam9g45_wdt_device = {
.name = "at91_wdt",
.id = -1,
diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
index a28e53faf71d..a4102d72cc9b 100644
--- a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
@@ -90,7 +90,7 @@ static struct at91_udc_data __initdata ek_udc_data = {
* SPI devices.
*/
static struct spi_board_info ek_spi_devices[] = {
-#if !defined(CONFIG_MMC_ATMELMCI)
+#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
{ /* DataFlash chip */
.modalias = "mtd_dataflash",
.chip_select = 1,
@@ -113,7 +113,7 @@ static struct spi_board_info ek_spi_devices[] = {
* MACB Ethernet device
*/
static struct at91_eth_data __initdata ek_macb_data = {
- .phy_irq_pin = AT91_PIN_PC12,
+ .phy_irq_pin = AT91_PIN_PB0,
.is_rmii = 1,
};
@@ -194,24 +194,27 @@ static void __init ek_add_device_nand(void)
/*
* MCI (SD/MMC)
- * det_pin and wp_pin are not connected
+ * wp_pin is not connected
*/
#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
static struct mci_platform_data __initdata ek_mmc_data = {
.slot[0] = {
.bus_width = 4,
- .detect_pin = -ENODEV,
+ .detect_pin = AT91_PIN_PC2,
.wp_pin = -ENODEV,
},
.slot[1] = {
.bus_width = 4,
- .detect_pin = -ENODEV,
+ .detect_pin = AT91_PIN_PC9,
.wp_pin = -ENODEV,
},
};
#else
-static struct amci_platform_data __initdata ek_mmc_data = {
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .slot_b = 1, /* Only one slot so use slot B */
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PC9,
};
#endif
@@ -221,13 +224,13 @@ static struct amci_platform_data __initdata ek_mmc_data = {
static struct gpio_led ek_leds[] = {
{ /* "bottom" led, green, userled1 to be defined */
.name = "ds5",
- .gpio = AT91_PIN_PB12,
+ .gpio = AT91_PIN_PB8,
.active_low = 1,
.default_trigger = "none",
},
{ /* "power" led, yellow */
.name = "ds1",
- .gpio = AT91_PIN_PB13,
+ .gpio = AT91_PIN_PB9,
.default_trigger = "heartbeat",
}
};
@@ -254,7 +257,11 @@ static void __init ek_board_init(void)
/* Ethernet */
at91_add_device_eth(&ek_macb_data);
/* MMC */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
at91_add_device_mci(0, &ek_mmc_data);
+#else
+ at91_add_device_mmc(0, &ek_mmc_data);
+#endif
/* I2C */
at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
/* LEDs */
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 34a9502c48bc..c22df30ed5e5 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -25,6 +25,8 @@
#define ARCH_ID_AT91SAM9G20 0x019905a0
#define ARCH_ID_AT91SAM9RL64 0x019b03a0
#define ARCH_ID_AT91SAM9G45 0x819b05a0
+#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */
+#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */
#define ARCH_ID_AT91CAP9 0x039A03A0
#define ARCH_ID_AT91SAM9XE128 0x329973a0
@@ -41,6 +43,11 @@ static inline unsigned long at91_cpu_identify(void)
return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
}
+static inline unsigned long at91_cpu_fully_identify(void)
+{
+ return at91_sys_read(AT91_DBGU_CIDR);
+}
+
#define ARCH_EXID_AT91SAM9M11 0x00000001
#define ARCH_EXID_AT91SAM9M10 0x00000002
#define ARCH_EXID_AT91SAM9G45 0x00000004
@@ -118,8 +125,10 @@ static inline unsigned long at91cap9_rev_identify(void)
#ifdef CONFIG_ARCH_AT91SAM9G45
#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
+#define cpu_is_at91sam9g45es() (at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES)
#else
#define cpu_is_at91sam9g45() (0)
+#define cpu_is_at91sam9g45es() (0)
#endif
#ifdef CONFIG_ARCH_AT91CAP9
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index f95dc160c34b..b4357c388d2e 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -206,7 +206,6 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
for (i = 0; i < 8; i++) {
if (status & (1 << i)) {
int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
- desc = irq_desc + gpio_irq;
generic_handle_irq(gpio_irq);
}
}
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index ca71cf1a72a0..a4a7be308000 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -112,7 +112,7 @@ static void __init edb93xx_register_i2c(void)
ARRAY_SIZE(edb93xxa_i2c_board_info));
} else if (machine_is_edb9307() || machine_is_edb9312() ||
machine_is_edb9315()) {
- ep93xx_register_i2c(&edb93xx_i2c_gpio_data
+ ep93xx_register_i2c(&edb93xx_i2c_gpio_data,
edb93xx_i2c_board_info,
ARRAY_SIZE(edb93xx_i2c_board_info));
}
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index a3ec33fd79d4..469fd968d517 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -17,7 +17,6 @@ struct ep93xx_eth_data
void ep93xx_map_io(void);
void ep93xx_init_irq(void);
-void ep93xx_init_time(unsigned long);
/* EP93xx System Controller software locked register write */
void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg);
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index d83b80478b09..f3757a1c5a10 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
+#include <linux/io.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-integrator/include/mach/memory.h b/arch/arm/mach-integrator/include/mach/memory.h
index 2b2e7a110724..4891828454f5 100644
--- a/arch/arm/mach-integrator/include/mach/memory.h
+++ b/arch/arm/mach-integrator/include/mach/memory.h
@@ -28,5 +28,6 @@
#define BUS_OFFSET UL(0x80000000)
#define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET)
#define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET)
+#define __pfn_to_bus(x) (((x) << PAGE_SHIFT) + BUS_OFFSET)
#endif
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
index 1da5d1c18ecb..2e69168fc699 100644
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -105,7 +105,7 @@ void __init kirkwood_setup_cpu_mbus(void)
setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE,
TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE);
setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
- TARGET_PCIE, ATTR_PCIE_MEM, -1);
+ TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE);
/*
* Setup window for NAND controller.
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 0acb61f3c10b..242dd0775343 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -845,7 +845,7 @@ int __init kirkwood_find_tclk(void)
return 166666667;
}
-static void kirkwood_timer_init(void)
+static void __init kirkwood_timer_init(void)
{
kirkwood_tclk = kirkwood_find_tclk();
orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
@@ -915,6 +915,14 @@ void __init kirkwood_init(void)
kirkwood_uart0_data[0].uartclk = kirkwood_tclk;
kirkwood_uart1_data[0].uartclk = kirkwood_tclk;
+ /*
+ * Disable propagation of mbus errors to the CPU local bus,
+ * as this causes mbus errors (which can occur for example
+ * for PCI aborts) to throw CPU aborts, which we're not set
+ * up to deal with.
+ */
+ writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
+
kirkwood_setup_cpu_mbus();
#ifdef CONFIG_CACHE_FEROCEON_L2
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
index 9e80d9232c83..418f5017c50e 100644
--- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -13,6 +13,9 @@
#include <mach/kirkwood.h>
+#define CPU_CONFIG (BRIDGE_VIRT_BASE | 0x0100)
+#define CPU_CONFIG_ERROR_PROP 0x00000004
+
#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104)
#define CPU_RESET 0x00000002
diff --git a/arch/arm/mach-kirkwood/include/mach/io.h b/arch/arm/mach-kirkwood/include/mach/io.h
index a643a846d5fb..44e8be04f259 100644
--- a/arch/arm/mach-kirkwood/include/mach/io.h
+++ b/arch/arm/mach-kirkwood/include/mach/io.h
@@ -15,7 +15,7 @@
static inline void __iomem *__io(unsigned long addr)
{
- return (void __iomem *)((addr - KIRKWOOD_PCIE_IO_PHYS_BASE)
+ return (void __iomem *)((addr - KIRKWOOD_PCIE_IO_BUS_BASE)
+ KIRKWOOD_PCIE_IO_VIRT_BASE);
}
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index 54c132731d2d..a15cf0ee22bd 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -43,6 +43,7 @@
#define KIRKWOOD_REGS_SIZE SZ_1M
#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000
+#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000
#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M
/*
diff --git a/arch/arm/mach-kirkwood/openrd_base-setup.c b/arch/arm/mach-kirkwood/openrd_base-setup.c
index 947dfb8cd5b2..77617c722299 100644
--- a/arch/arm/mach-kirkwood/openrd_base-setup.c
+++ b/arch/arm/mach-kirkwood/openrd_base-setup.c
@@ -70,8 +70,20 @@ static void __init openrd_base_init(void)
kirkwood_ge00_init(&openrd_base_ge00_data);
kirkwood_sata_init(&openrd_base_sata_data);
kirkwood_sdio_init(&openrd_base_mvsdio_data);
+
+ kirkwood_i2c_init();
}
+static int __init openrd_base_pci_init(void)
+{
+ if (machine_is_openrd_base())
+ kirkwood_pcie_init();
+
+ return 0;
+ }
+subsys_initcall(openrd_base_pci_init);
+
+
MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
.phys_io = KIRKWOOD_REGS_PHYS_BASE,
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index d90b9aae308d..a604b2a701aa 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -93,7 +93,7 @@ static struct pci_ops pcie_ops = {
};
-static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
+static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
{
struct resource *res;
extern unsigned int kirkwood_clk_ctrl;
@@ -115,7 +115,7 @@ static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
*/
res[0].name = "PCIe I/O Space";
res[0].flags = IORESOURCE_IO;
- res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
+ res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
if (request_resource(&ioport_resource, &res[0]))
panic("Request PCIe IO resource failed\n");
@@ -126,7 +126,7 @@ static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
*/
res[1].name = "PCIe Memory Space";
res[1].flags = IORESOURCE_MEM;
- res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
+ res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE;
res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
if (request_resource(&iomem_resource, &res[1]))
panic("Request PCIe Memory resource failed\n");
diff --git a/arch/arm/mach-ks8695/include/mach/regs-switch.h b/arch/arm/mach-ks8695/include/mach/regs-switch.h
index 56d12e8de895..97e8acb1cf6c 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-switch.h
+++ b/arch/arm/mach-ks8695/include/mach/regs-switch.h
@@ -25,7 +25,7 @@
#define KS8695_SEC1 (0x04) /* Switch Engine Control 1 */
#define KS8695_SEC2 (0x08) /* Switch Engine Control 2 */
-#define KS8695_P(x)_C(z) (0xc0 + (((x)-1)*3 + ((z)-1))*4) /* Port Configuration Registers */
+#define KS8695_SEPXCZ(x,z) (0x0c + (((x)-1)*3 + ((z)-1))*4) /* Port Configuration Registers */
#define KS8695_SEP12AN (0x48) /* Port 1 & 2 Auto-Negotiation */
#define KS8695_SEP34AN (0x4c) /* Port 3 & 4 Auto-Negotiation */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
index bf1189ff9a34..7e8a80f25ddc 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
@@ -160,7 +160,7 @@
#define MMC1_WP_MMC1_WP MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM)
/* PWM */
-#define GPIO27 PWM3 AF2 MFP_CFG(GPIO27, AF2)
+#define GPIO27_PWM3_AF2 MFP_CFG(GPIO27, AF2)
#define GPIO51_PWM2_OUT MFP_CFG(GPIO51, AF2)
#define GPIO117_PWM1_OUT MFP_CFG(GPIO117, AF2)
#define GPIO118_PWM2_OUT MFP_CFG(GPIO118, AF2)
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index 1b22e4af8791..08465eb6a2c2 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -845,6 +845,8 @@ static char * __init mv78xx0_id(void)
} else if (dev == MV78100_DEV_ID) {
if (rev == MV78100_REV_A0)
return "MV78100-A0";
+ else if (rev == MV78100_REV_A1)
+ return "MV78100-A1";
else
return "MV78100-Rev-Unsupported";
} else if (dev == MV78200_DEV_ID) {
diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
index d715b92b0908..788bdace1304 100644
--- a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
+++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
@@ -112,6 +112,7 @@
#define MV78100_DEV_ID 0x7810
#define MV78100_REV_A0 1
+#define MV78100_REV_A1 2
#define MV78200_DEV_ID 0x7820
#define MV78200_REV_A0 1
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c
index 4089951acb47..ff5e33298914 100644
--- a/arch/arm/mach-mx2/clock_imx27.c
+++ b/arch/arm/mach-mx2/clock_imx27.c
@@ -638,9 +638,9 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
_REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
_REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
- _REGISTER_CLOCK(NULL, "cspi1", cspi1_clk)
- _REGISTER_CLOCK(NULL, "cspi2", cspi2_clk)
- _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk)
+ _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
_REGISTER_CLOCK(NULL, "csi", csi_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
@@ -665,7 +665,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
_REGISTER_CLOCK(NULL, "ata", ata_clk)
_REGISTER_CLOCK(NULL, "mstick", mstick_clk)
- _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+ _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
_REGISTER_CLOCK(NULL, "gpio", gpio_clk)
_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c
index ee65dda584cf..906d59b0a7aa 100644
--- a/arch/arm/mach-mx2/pcm038.c
+++ b/arch/arm/mach-mx2/pcm038.c
@@ -23,6 +23,10 @@
#include <linux/mtd/plat-ram.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -35,6 +39,7 @@
#include <mach/iomux.h>
#include <mach/imx-uart.h>
#include <mach/mxc_nand.h>
+#include <mach/spi.h>
#include "devices.h"
@@ -78,8 +83,6 @@ static int pcm038_pins[] = {
PC6_PF_I2C2_SCL,
/* SPI1 */
PD25_PF_CSPI1_RDY,
- PD27_PF_CSPI1_SS1,
- PD28_PF_CSPI1_SS0,
PD29_PF_CSPI1_SCLK,
PD30_PF_CSPI1_MISO,
PD31_PF_CSPI1_MOSI,
@@ -196,6 +199,86 @@ static struct i2c_board_info pcm038_i2c_devices[] = {
}
};
+static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
+
+static struct spi_imx_master pcm038_spi_0_data = {
+ .chipselect = pcm038_spi_cs,
+ .num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
+};
+
+static struct regulator_consumer_supply sdhc1_consumers[] = {
+ {
+ .dev = &mxc_sdhc_device1.dev,
+ .supply = "sdhc_vcc",
+ },
+};
+
+static struct regulator_init_data sdhc1_data = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3400000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdhc1_consumers),
+ .consumer_supplies = sdhc1_consumers,
+};
+
+static struct regulator_consumer_supply cam_consumers[] = {
+ {
+ .dev = NULL,
+ .supply = "imx_cam_vcc",
+ },
+};
+
+static struct regulator_init_data cam_data = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3400000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
+ .consumer_supplies = cam_consumers,
+};
+
+struct mc13783_regulator_init_data pcm038_regulators[] = {
+ {
+ .id = MC13783_REGU_VCAM,
+ .init_data = &cam_data,
+ }, {
+ .id = MC13783_REGU_VMMC1,
+ .init_data = &sdhc1_data,
+ },
+};
+
+static struct mc13783_platform_data pcm038_pmic = {
+ .regulators = pcm038_regulators,
+ .num_regulators = ARRAY_SIZE(pcm038_regulators),
+ .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
+ MC13783_USE_TOUCHSCREEN,
+};
+
+static struct spi_board_info pcm038_spi_board_info[] __initdata = {
+ {
+ .modalias = "mc13783",
+ .irq = IRQ_GPIOB(23),
+ .max_speed_hz = 300000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &pcm038_pmic,
+ .mode = SPI_CS_HIGH,
+ }
+};
+
static void __init pcm038_init(void)
{
mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
@@ -219,6 +302,15 @@ static void __init pcm038_init(void)
/* PE18 for user-LED D40 */
mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
+ mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+
+ /* MC13783 IRQ */
+ mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
+
+ mxc_register_device(&mxc_spi_device0, &pcm038_spi_0_data);
+ spi_register_board_info(pcm038_spi_board_info,
+ ARRAY_SIZE(pcm038_spi_board_info));
+
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
#ifdef CONFIG_MACH_PCM970_BASEBOARD
diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c
index c261f59b0b4c..3cb7f457e5d0 100644
--- a/arch/arm/mach-mx2/pcm970-baseboard.c
+++ b/arch/arm/mach-mx2/pcm970-baseboard.c
@@ -39,7 +39,6 @@ static int pcm970_pins[] = {
PB7_PF_SD2_D3,
PB8_PF_SD2_CMD,
PB9_PF_SD2_CLK,
- GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN, /* card detect */
/* display */
PA5_PF_LSCLK,
PA6_PF_LD0,
@@ -228,6 +227,7 @@ void __init pcm970_baseboard_init(void)
"PCM970");
mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
+ mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN);
mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
platform_device_register(&pcm970_sja1000);
}
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c
index eb12de1da42d..63511de3a559 100644
--- a/arch/arm/mach-mx25/devices.c
+++ b/arch/arm/mach-mx25/devices.c
@@ -1,4 +1,23 @@
+/*
+ * Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <mach/mx25.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-mx25/mx25pdk.c b/arch/arm/mach-mx25/mx25pdk.c
index 92aa4fd19d99..d23ae571c03f 100644
--- a/arch/arm/mach-mx25/mx25pdk.c
+++ b/arch/arm/mach-mx25/mx25pdk.c
@@ -1,3 +1,21 @@
+/*
+ * Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
#include <linux/types.h>
#include <linux/init.h>
#include <linux/clk.h>
@@ -23,19 +41,12 @@ static struct imxuart_platform_data uart_pdata = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct mxc_nand_platform_data nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
static void __init mx25pdk_init(void)
{
mxc_register_device(&mxc_uart_device0, &uart_pdata);
mxc_register_device(&mxc_usbh2, NULL);
- mxc_register_device(&mxc_nand_device, &nand_board_info);
}
-
static void __init mx25pdk_timer_init(void)
{
mx25_clocks_init(26000000);
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index fe5c4217322e..c595260ec1f9 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -443,7 +443,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
- _REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
_REGISTER_CLOCK(NULL, "max", max_clk)
_REGISTER_CLOCK(NULL, "admux", admux_clk)
_REGISTER_CLOCK(NULL, "csi", csi_clk)
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c
index 06bd6180bfc3..b2a3bcf8266e 100644
--- a/arch/arm/mach-mx3/clock.c
+++ b/arch/arm/mach-mx3/clock.c
@@ -530,7 +530,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
- _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+ _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
_REGISTER_CLOCK(NULL, "epit", epit1_clk)
_REGISTER_CLOCK(NULL, "epit", epit2_clk)
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index 8a577f367250..e6abe181b967 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -459,7 +459,7 @@ struct platform_device mxc_usbh2 = {
* SPI master controller
* 3 channels
*/
-static struct resource imx_spi_0_resources[] = {
+static struct resource mxc_spi_0_resources[] = {
{
.start = CSPI1_BASE_ADDR,
.end = CSPI1_BASE_ADDR + SZ_4K - 1,
@@ -471,7 +471,7 @@ static struct resource imx_spi_0_resources[] = {
},
};
-static struct resource imx_spi_1_resources[] = {
+static struct resource mxc_spi_1_resources[] = {
{
.start = CSPI2_BASE_ADDR,
.end = CSPI2_BASE_ADDR + SZ_4K - 1,
@@ -483,7 +483,7 @@ static struct resource imx_spi_1_resources[] = {
},
};
-static struct resource imx_spi_2_resources[] = {
+static struct resource mxc_spi_2_resources[] = {
{
.start = CSPI3_BASE_ADDR,
.end = CSPI3_BASE_ADDR + SZ_4K - 1,
@@ -495,25 +495,25 @@ static struct resource imx_spi_2_resources[] = {
},
};
-struct platform_device imx_spi_device0 = {
+struct platform_device mxc_spi_device0 = {
.name = "spi_imx",
.id = 0,
- .num_resources = ARRAY_SIZE(imx_spi_0_resources),
- .resource = imx_spi_0_resources,
+ .num_resources = ARRAY_SIZE(mxc_spi_0_resources),
+ .resource = mxc_spi_0_resources,
};
-struct platform_device imx_spi_device1 = {
+struct platform_device mxc_spi_device1 = {
.name = "spi_imx",
.id = 1,
- .num_resources = ARRAY_SIZE(imx_spi_1_resources),
- .resource = imx_spi_1_resources,
+ .num_resources = ARRAY_SIZE(mxc_spi_1_resources),
+ .resource = mxc_spi_1_resources,
};
-struct platform_device imx_spi_device2 = {
+struct platform_device mxc_spi_device2 = {
.name = "spi_imx",
.id = 2,
- .num_resources = ARRAY_SIZE(imx_spi_2_resources),
- .resource = imx_spi_2_resources,
+ .num_resources = ARRAY_SIZE(mxc_spi_2_resources),
+ .resource = mxc_spi_2_resources,
};
#ifdef CONFIG_ARCH_MX35
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index 79f2be45d139..ab87419dc9a0 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -20,7 +20,7 @@ extern struct platform_device mxc_otg_host;
extern struct platform_device mxc_usbh1;
extern struct platform_device mxc_usbh2;
extern struct platform_device mxc_rnga_device;
-extern struct platform_device imx_spi_device0;
-extern struct platform_device imx_spi_device1;
-extern struct platform_device imx_spi_device2;
+extern struct platform_device mxc_spi_device0;
+extern struct platform_device mxc_spi_device1;
+extern struct platform_device mxc_spi_device2;
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
index ad5a1122d765..bedf5b8d976a 100644
--- a/arch/arm/mach-mx3/mm.c
+++ b/arch/arm/mach-mx3/mm.c
@@ -81,6 +81,7 @@ void __init mx31_map_io(void)
iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
}
+#ifdef CONFIG_ARCH_MX35
void __init mx35_map_io(void)
{
mxc_set_cpu_type(MXC_CPU_MX35);
@@ -89,6 +90,7 @@ void __init mx35_map_io(void)
iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
}
+#endif
void __init mx31_init_irq(void)
{
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 42920f9c1a11..8ad5cc3e83e3 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -219,6 +219,10 @@ static struct platform_device *ams_delta_devices[] __initdata = {
static void __init ams_delta_init(void)
{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+
iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
omap_board_config = ams_delta_config;
@@ -231,6 +235,8 @@ static void __init ams_delta_init(void)
omap_usb_init(&ams_delta_usb_config);
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
+
+ omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
}
static struct plat_serial8250_port ams_delta_modem_ports[] = {
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index fb47239da72f..6c8a41f20e51 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -64,6 +64,14 @@ static void __init omap_generic_init(void)
{
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap15xx()) {
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
omap_usb_init(&generic1510_usb_config);
}
#endif
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index cc2abbb2d0f4..cd6c39514826 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -376,6 +376,26 @@ static void __init innovator_init(void)
{
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
+ unsigned char reg;
+
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
+ reg = fpga_read(OMAP1510_FPGA_POWER);
+ reg |= OMAP1510_FPGA_PCR_COM1_EN;
+ fpga_write(reg, OMAP1510_FPGA_POWER);
+ udelay(10);
+
+ reg = fpga_read(OMAP1510_FPGA_POWER);
+ reg |= OMAP1510_FPGA_PCR_COM2_EN;
+ fpga_write(reg, OMAP1510_FPGA_POWER);
+ udelay(10);
+
platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
spi_register_board_info(innovator1510_boardinfo,
ARRAY_SIZE(innovator1510_boardinfo));
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 90dd0431b0dc..4de258420f39 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -342,6 +342,14 @@ static void __init palmte_misc_gpio_setup(void)
static void __init omap_palmte_init(void)
{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
omap_board_config = palmte_config;
omap_board_config_size = ARRAY_SIZE(palmte_config);
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 8256139891ff..d972cf941b76 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -289,6 +289,14 @@ static void __init omap_mpu_wdt_mode(int mode) {
static void __init omap_palmtt_init(void)
{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
omap_mpu_wdt_mode(0);
omap_board_config = palmtt_config;
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 81b6bde1c5a3..986bd4df0e97 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -307,6 +307,14 @@ palmz71_gpio_setup(int early)
static void __init
omap_palmz71_init(void)
{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
palmz71_gpio_setup(1);
omap_mpu_wdt_mode(0);
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 02c85ca2e1df..056ae64e0f55 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -377,6 +377,14 @@ static struct omap_board_config_kernel sx1_config[] __initdata = {
static void __init omap_sx1_init(void)
{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices));
omap_board_config = sx1_config;
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index c06e7a553472..07b07522d5bf 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -152,6 +152,14 @@ static void __init voiceblue_init_irq(void)
static void __init voiceblue_init(void)
{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
/* Watchdog */
gpio_request(0, "Watchdog");
/* smc91x reset */
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index d496e50fec40..d23979bc0fd5 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -131,8 +131,6 @@ void __init omap_serial_init(void)
}
for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
- unsigned char reg;
-
switch (i) {
case 0:
uart1_ck = clk_get(NULL, "uart1_ck");
@@ -143,16 +141,6 @@ void __init omap_serial_init(void)
if (cpu_is_omap15xx())
clk_set_rate(uart1_ck, 12000000);
}
- if (cpu_is_omap15xx()) {
- omap_cfg_reg(UART1_TX);
- omap_cfg_reg(UART1_RTS);
- if (machine_is_omap_innovator()) {
- reg = fpga_read(OMAP1510_FPGA_POWER);
- reg |= OMAP1510_FPGA_PCR_COM1_EN;
- fpga_write(reg, OMAP1510_FPGA_POWER);
- udelay(10);
- }
- }
break;
case 1:
uart2_ck = clk_get(NULL, "uart2_ck");
@@ -165,16 +153,6 @@ void __init omap_serial_init(void)
else
clk_set_rate(uart2_ck, 48000000);
}
- if (cpu_is_omap15xx()) {
- omap_cfg_reg(UART2_TX);
- omap_cfg_reg(UART2_RTS);
- if (machine_is_omap_innovator()) {
- reg = fpga_read(OMAP1510_FPGA_POWER);
- reg |= OMAP1510_FPGA_PCR_COM2_EN;
- fpga_write(reg, OMAP1510_FPGA_POWER);
- udelay(10);
- }
- }
break;
case 2:
uart3_ck = clk_get(NULL, "uart3_ck");
@@ -185,10 +163,6 @@ void __init omap_serial_init(void)
if (cpu_is_omap15xx())
clk_set_rate(uart3_ck, 12000000);
}
- if (cpu_is_omap15xx()) {
- omap_cfg_reg(UART3_TX);
- omap_cfg_reg(UART3_RX);
- }
break;
}
omap_serial_reset(&serial_platform_data[i]);
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 75b1c7efae7e..aad194f61a33 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -73,9 +73,21 @@ config MACH_OMAP_3430SDP
bool "OMAP 3430 SDP board"
depends on ARCH_OMAP3 && ARCH_OMAP34XX
+config MACH_NOKIA_N800
+ bool
+
+config MACH_NOKIA_N810
+ bool
+
+config MACH_NOKIA_N810_WIMAX
+ bool
+
config MACH_NOKIA_N8X0
bool "Nokia N800/N810"
depends on ARCH_OMAP2420
+ select MACH_NOKIA_N800
+ select MACH_NOKIA_N810
+ select MACH_NOKIA_N810_WIMAX
config MACH_NOKIA_RX51
bool "Nokia RX-51 board"
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index efaf053eba85..0acb5560229c 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/i2c/twl4030.h>
@@ -38,7 +39,6 @@
#include <mach/gpmc.h>
#include <mach/control.h>
-#include <mach/keypad.h>
#include <mach/gpmc-smc91x.h>
#include "sdram-qimonda-hyb18m512160af-6.h"
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index eb37c40ea83a..609a5a4a7e29 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -58,6 +58,8 @@ static void __init gic_init_irq(void)
static void __init omap_4430sdp_init_irq(void)
{
+ omap_board_config = sdp4430_config;
+ omap_board_config_size = ARRAY_SIZE(sdp4430_config);
omap2_init_common_hw(NULL, NULL);
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(1);
@@ -70,8 +72,6 @@ static void __init omap_4430sdp_init_irq(void)
static void __init omap_4430sdp_init(void)
{
platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
- omap_board_config = sdp4430_config;
- omap_board_config_size = ARRAY_SIZE(sdp4430_config);
omap_serial_init();
}
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index d110a7fdfbd8..d57ec2f4d0a9 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
#include <linux/gpio_keys.h>
#include <linux/workqueue.h>
#include <linux/err.h>
@@ -41,7 +42,6 @@
#include <asm/delay.h>
#include <mach/control.h>
#include <mach/usb.h>
-#include <mach/keypad.h>
#include "mmc-twl4030.h"
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 70df6b4dbcd4..08b0816afa61 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -162,7 +162,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
+ gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index e4ec0c591216..4c4d7f8dbd72 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -20,6 +20,7 @@
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
#include <linux/leds.h>
#include <linux/spi/spi.h>
@@ -37,7 +38,6 @@
#include <mach/usb.h>
#include <mach/common.h>
#include <mach/mcspi.h>
-#include <mach/keypad.h>
#include "sdram-micron-mt46h32m32lf-6.h"
#include "mmc-twl4030.h"
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 7f6bf8772af7..7519edb69155 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -27,6 +27,7 @@
#include <linux/i2c/twl4030.h>
#include <linux/leds.h>
#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
#include <linux/gpio_keys.h>
#include <asm/mach-types.h>
@@ -39,7 +40,6 @@
#include <mach/hardware.h>
#include <mach/mcspi.h>
#include <mach/usb.h>
-#include <mach/keypad.h>
#include <mach/mux.h>
#include "sdram-micron-mt46h32m32lf-6.h"
@@ -134,50 +134,50 @@ static void __init pandora_keys_gpio_init(void)
}
static int board_keymap[] = {
- /* col, row, code */
+ /* row, col, code */
KEY(0, 0, KEY_9),
- KEY(0, 1, KEY_0),
- KEY(0, 2, KEY_BACKSPACE),
- KEY(0, 3, KEY_O),
- KEY(0, 4, KEY_P),
- KEY(0, 5, KEY_K),
- KEY(0, 6, KEY_L),
- KEY(0, 7, KEY_ENTER),
- KEY(1, 0, KEY_8),
+ KEY(0, 1, KEY_8),
+ KEY(0, 2, KEY_I),
+ KEY(0, 3, KEY_J),
+ KEY(0, 4, KEY_N),
+ KEY(0, 5, KEY_M),
+ KEY(1, 0, KEY_0),
KEY(1, 1, KEY_7),
- KEY(1, 2, KEY_6),
- KEY(1, 3, KEY_5),
- KEY(1, 4, KEY_4),
- KEY(1, 5, KEY_3),
- KEY(1, 6, KEY_2),
- KEY(1, 7, KEY_1),
- KEY(2, 0, KEY_I),
- KEY(2, 1, KEY_U),
+ KEY(1, 2, KEY_U),
+ KEY(1, 3, KEY_H),
+ KEY(1, 4, KEY_B),
+ KEY(1, 5, KEY_SPACE),
+ KEY(2, 0, KEY_BACKSPACE),
+ KEY(2, 1, KEY_6),
KEY(2, 2, KEY_Y),
- KEY(2, 3, KEY_T),
- KEY(2, 4, KEY_R),
- KEY(2, 5, KEY_E),
- KEY(2, 6, KEY_W),
- KEY(2, 7, KEY_Q),
- KEY(3, 0, KEY_J),
- KEY(3, 1, KEY_H),
- KEY(3, 2, KEY_G),
+ KEY(2, 3, KEY_G),
+ KEY(2, 4, KEY_V),
+ KEY(2, 5, KEY_FN),
+ KEY(3, 0, KEY_O),
+ KEY(3, 1, KEY_5),
+ KEY(3, 2, KEY_T),
KEY(3, 3, KEY_F),
- KEY(3, 4, KEY_D),
- KEY(3, 5, KEY_S),
- KEY(3, 6, KEY_A),
- KEY(3, 7, KEY_LEFTSHIFT),
- KEY(4, 0, KEY_N),
- KEY(4, 1, KEY_B),
- KEY(4, 2, KEY_V),
- KEY(4, 3, KEY_C),
+ KEY(3, 4, KEY_C),
+ KEY(4, 0, KEY_P),
+ KEY(4, 1, KEY_4),
+ KEY(4, 2, KEY_R),
+ KEY(4, 3, KEY_D),
KEY(4, 4, KEY_X),
- KEY(4, 5, KEY_Z),
- KEY(4, 6, KEY_DOT),
- KEY(4, 7, KEY_COMMA),
- KEY(5, 0, KEY_M),
- KEY(5, 1, KEY_SPACE),
- KEY(5, 2, KEY_FN),
+ KEY(5, 0, KEY_K),
+ KEY(5, 1, KEY_3),
+ KEY(5, 2, KEY_E),
+ KEY(5, 3, KEY_S),
+ KEY(5, 4, KEY_Z),
+ KEY(6, 0, KEY_L),
+ KEY(6, 1, KEY_2),
+ KEY(6, 2, KEY_W),
+ KEY(6, 3, KEY_A),
+ KEY(6, 4, KEY_DOT),
+ KEY(7, 0, KEY_ENTER),
+ KEY(7, 1, KEY_1),
+ KEY(7, 2, KEY_Q),
+ KEY(7, 3, KEY_LEFTSHIFT),
+ KEY(7, 4, KEY_COMMA),
};
static struct matrix_keymap_data board_map_data = {
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index c1af5326e92f..e34d96a825e3 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
#include <linux/i2c.h>
#include <linux/i2c/twl4030.h>
@@ -27,7 +28,6 @@
#include <mach/common.h>
#include <mach/dma.h>
#include <mach/gpmc.h>
-#include <mach/keypad.h>
#include <mach/onenand.h>
#include <mach/gpmc-smc91x.h>
@@ -444,7 +444,7 @@ static int __init rx51_i2c_init(void)
rx51_twldata.vaux3 = &rx51_vaux3_cam;
rx51_twldata.vmmc2 = &rx51_vmmc2;
}
- omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1,
+ omap_register_i2c_bus(1, 2200, rx51_peripherals_i2c_board_info_1,
ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
omap_register_i2c_bus(2, 100, NULL, 0);
omap_register_i2c_bus(3, 400, NULL, 0);
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index f9196c3b1a7b..78869a9a1cc2 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -26,7 +26,6 @@
#include <mach/mux.h>
#include <mach/board.h>
#include <mach/common.h>
-#include <mach/keypad.h>
#include <mach/dma.h>
#include <mach/gpmc.h>
#include <mach/usb.h>
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index b7b32208ced7..51e0b3ba5f3a 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
#include <linux/gpio.h>
#include <linux/i2c/twl4030.h>
#include <linux/regulator/machine.h>
@@ -22,64 +23,63 @@
#include <mach/common.h>
#include <mach/usb.h>
-#include <mach/keypad.h>
#include "mmc-twl4030.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
/* Zoom2 has Qwerty keyboard*/
static int board_keymap[] = {
KEY(0, 0, KEY_E),
- KEY(1, 0, KEY_R),
- KEY(2, 0, KEY_T),
- KEY(3, 0, KEY_HOME),
- KEY(6, 0, KEY_I),
- KEY(7, 0, KEY_LEFTSHIFT),
- KEY(0, 1, KEY_D),
+ KEY(0, 1, KEY_R),
+ KEY(0, 2, KEY_T),
+ KEY(0, 3, KEY_HOME),
+ KEY(0, 6, KEY_I),
+ KEY(0, 7, KEY_LEFTSHIFT),
+ KEY(1, 0, KEY_D),
KEY(1, 1, KEY_F),
- KEY(2, 1, KEY_G),
- KEY(3, 1, KEY_SEND),
- KEY(6, 1, KEY_K),
- KEY(7, 1, KEY_ENTER),
- KEY(0, 2, KEY_X),
- KEY(1, 2, KEY_C),
+ KEY(1, 2, KEY_G),
+ KEY(1, 3, KEY_SEND),
+ KEY(1, 6, KEY_K),
+ KEY(1, 7, KEY_ENTER),
+ KEY(2, 0, KEY_X),
+ KEY(2, 1, KEY_C),
KEY(2, 2, KEY_V),
- KEY(3, 2, KEY_END),
- KEY(6, 2, KEY_DOT),
- KEY(7, 2, KEY_CAPSLOCK),
- KEY(0, 3, KEY_Z),
- KEY(1, 3, KEY_KPPLUS),
- KEY(2, 3, KEY_B),
+ KEY(2, 3, KEY_END),
+ KEY(2, 6, KEY_DOT),
+ KEY(2, 7, KEY_CAPSLOCK),
+ KEY(3, 0, KEY_Z),
+ KEY(3, 1, KEY_KPPLUS),
+ KEY(3, 2, KEY_B),
KEY(3, 3, KEY_F1),
- KEY(6, 3, KEY_O),
- KEY(7, 3, KEY_SPACE),
- KEY(0, 4, KEY_W),
- KEY(1, 4, KEY_Y),
- KEY(2, 4, KEY_U),
- KEY(3, 4, KEY_F2),
+ KEY(3, 6, KEY_O),
+ KEY(3, 7, KEY_SPACE),
+ KEY(4, 0, KEY_W),
+ KEY(4, 1, KEY_Y),
+ KEY(4, 2, KEY_U),
+ KEY(4, 3, KEY_F2),
KEY(4, 4, KEY_VOLUMEUP),
- KEY(6, 4, KEY_L),
- KEY(7, 4, KEY_LEFT),
- KEY(0, 5, KEY_S),
- KEY(1, 5, KEY_H),
- KEY(2, 5, KEY_J),
- KEY(3, 5, KEY_F3),
+ KEY(4, 6, KEY_L),
+ KEY(4, 7, KEY_LEFT),
+ KEY(5, 0, KEY_S),
+ KEY(5, 1, KEY_H),
+ KEY(5, 2, KEY_J),
+ KEY(5, 3, KEY_F3),
KEY(5, 5, KEY_VOLUMEDOWN),
- KEY(6, 5, KEY_M),
- KEY(4, 5, KEY_ENTER),
- KEY(7, 5, KEY_RIGHT),
- KEY(0, 6, KEY_Q),
- KEY(1, 6, KEY_A),
- KEY(2, 6, KEY_N),
- KEY(3, 6, KEY_BACKSPACE),
+ KEY(5, 6, KEY_M),
+ KEY(5, 7, KEY_ENTER),
+ KEY(6, 0, KEY_Q),
+ KEY(6, 1, KEY_A),
+ KEY(6, 2, KEY_N),
+ KEY(6, 3, KEY_BACKSPACE),
KEY(6, 6, KEY_P),
- KEY(7, 6, KEY_UP),
KEY(6, 7, KEY_SELECT),
- KEY(7, 7, KEY_DOWN),
- KEY(0, 7, KEY_PROG1), /*MACRO 1 <User defined> */
- KEY(1, 7, KEY_PROG2), /*MACRO 2 <User defined> */
- KEY(2, 7, KEY_PROG3), /*MACRO 3 <User defined> */
- KEY(3, 7, KEY_PROG4), /*MACRO 4 <User defined> */
- 0
+ KEY(7, 0, KEY_PROG1), /*MACRO 1 <User defined> */
+ KEY(7, 1, KEY_PROG2), /*MACRO 2 <User defined> */
+ KEY(7, 2, KEY_PROG3), /*MACRO 3 <User defined> */
+ KEY(7, 3, KEY_PROG4), /*MACRO 4 <User defined> */
+ KEY(7, 5, KEY_RIGHT),
+ KEY(7, 6, KEY_UP),
+ KEY(7, 7, KEY_DOWN)
};
static struct matrix_keymap_data board_map_data = {
@@ -213,7 +213,8 @@ static void __init omap_zoom2_init_irq(void)
{
omap_board_config = zoom2_config;
omap_board_config_size = ARRAY_SIZE(zoom2_config);
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_init_irq();
omap_gpio_init();
}
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index bc5d3ac66611..e2dbedd581e8 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -769,6 +769,7 @@ int __init omap2_clk_init(void)
if (c->cpu & cpu_mask) {
clkdev_add(&c->lk);
clk_register(c->lk.clk);
+ omap2_init_clk_clkdm(c->lk.clk);
}
/* Check the MPU rate set by bootloader */
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 489556eecbd1..7c5c00df3c70 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -473,7 +473,7 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
unsigned long fint;
u16 f = 0;
- fint = clk->dpll_data->clk_ref->rate / (n + 1);
+ fint = clk->dpll_data->clk_ref->rate / n;
pr_debug("clock: fint is %lu\n", fint);
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index c8119781e00a..9565c05bebd2 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -489,9 +489,9 @@ static struct clk core_ck = {
static struct clk dpll3_m2x2_ck = {
.name = "dpll3_m2x2_ck",
.ops = &clkops_null,
- .parent = &dpll3_x2_ck,
+ .parent = &dpll3_m2_ck,
.clkdm_name = "dpll3_clkdm",
- .recalc = &followparent_recalc,
+ .recalc = &omap3_clkoutx2_recalc,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 4ef7b4f5474e..58aff8485df9 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -137,6 +137,36 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)
}
}
+/*
+ * _omap2_clkdm_set_hwsup - set the hwsup idle transition bit
+ * @clkdm: struct clockdomain *
+ * @enable: int 0 to disable, 1 to enable
+ *
+ * Internal helper for actually switching the bit that controls hwsup
+ * idle transitions for clkdm.
+ */
+static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
+{
+ u32 v;
+
+ if (cpu_is_omap24xx()) {
+ if (enable)
+ v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
+ else
+ v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
+ } else if (cpu_is_omap34xx()) {
+ if (enable)
+ v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
+ else
+ v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
+ } else {
+ BUG();
+ }
+
+ cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
+ v << __ffs(clkdm->clktrctrl_mask),
+ clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
+}
static struct clockdomain *_clkdm_lookup(const char *name)
{
@@ -456,8 +486,6 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
*/
void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
{
- u32 v;
-
if (!clkdm)
return;
@@ -473,18 +501,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
if (atomic_read(&clkdm->usecount) > 0)
_clkdm_add_autodeps(clkdm);
- if (cpu_is_omap24xx())
- v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
- else if (cpu_is_omap34xx())
- v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
- else
- BUG();
-
-
- cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
- v << __ffs(clkdm->clktrctrl_mask),
- clkdm->pwrdm.ptr->prcm_offs,
- CM_CLKSTCTRL);
+ _omap2_clkdm_set_hwsup(clkdm, 1);
pwrdm_clkdm_state_switch(clkdm);
}
@@ -500,8 +517,6 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
*/
void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
{
- u32 v;
-
if (!clkdm)
return;
@@ -514,16 +529,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
clkdm->name);
- if (cpu_is_omap24xx())
- v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
- else if (cpu_is_omap34xx())
- v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
- else
- BUG();
-
- cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
- v << __ffs(clkdm->clktrctrl_mask),
- clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
+ _omap2_clkdm_set_hwsup(clkdm, 0);
if (atomic_read(&clkdm->usecount) > 0)
_clkdm_del_autodeps(clkdm);
@@ -569,10 +575,14 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
v = omap2_clkdm_clktrctrl_read(clkdm);
if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
- (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO))
+ (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
+ /* Disable HW transitions when we are changing deps */
+ _omap2_clkdm_set_hwsup(clkdm, 0);
_clkdm_add_autodeps(clkdm);
- else
+ _omap2_clkdm_set_hwsup(clkdm, 1);
+ } else {
omap2_clkdm_wakeup(clkdm);
+ }
pwrdm_wait_transition(clkdm->pwrdm.ptr);
pwrdm_clkdm_state_switch(clkdm);
@@ -623,10 +633,14 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
v = omap2_clkdm_clktrctrl_read(clkdm);
if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
- (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO))
+ (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
+ /* Disable HW transitions when we are changing deps */
+ _omap2_clkdm_set_hwsup(clkdm, 0);
_clkdm_del_autodeps(clkdm);
- else
+ _omap2_clkdm_set_hwsup(clkdm, 1);
+ } else {
omap2_clkdm_sleep(clkdm);
+ }
pwrdm_clkdm_state_switch(clkdm);
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 15876828db23..f3c992e29651 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -366,7 +366,7 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
if (r < 0)
goto out;
- gpmc_cs_enable_mem(cs, res->start, res->end - res->start + 1);
+ gpmc_cs_enable_mem(cs, res->start, resource_size(res));
*base = res->start;
gpmc_cs_set_reserved(cs, 1);
out:
@@ -378,7 +378,7 @@ EXPORT_SYMBOL(gpmc_cs_request);
void gpmc_cs_free(int cs)
{
spin_lock(&gpmc_mem_lock);
- if (cs >= GPMC_CS_NUM || !gpmc_cs_reserved(cs)) {
+ if (cs >= GPMC_CS_NUM || cs < 0 || !gpmc_cs_reserved(cs)) {
printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
BUG();
spin_unlock(&gpmc_mem_lock);
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index e3a3bad1d84f..56be87d13edb 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -302,7 +302,9 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
pwrdm_init(powerdomains_omap);
clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
omap2_clk_init();
+#endif
omap_serial_early_init();
+#ifndef CONFIG_ARCH_OMAP4
omap_hwmod_late_init();
omap_pm_if_init();
omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index c035ad3426d0..ef57b38a56a4 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -300,7 +300,7 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "invalid mem resource\n");
return -ENODEV;
}
- mbox_base = ioremap(res->start, res->end - res->start);
+ mbox_base = ioremap(res->start, resource_size(res));
if (!mbox_base)
return -ENOMEM;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 378c2f618358..89463190923a 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -639,14 +639,15 @@ static void __init prcm_setup_regs(void)
prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
- /* Enable GPIO wakeups in PER */
+ /* Enable wakeups in PER */
prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
- OMAP3430_EN_GPIO6, OMAP3430_PER_MOD, PM_WKEN);
+ OMAP3430_EN_GPIO6 | OMAP3430_EN_UART3,
+ OMAP3430_PER_MOD, PM_WKEN);
/* and allow them to wake up MPU */
prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
- OMAP3430_GRPSEL_GPIO6,
+ OMAP3430_GRPSEL_GPIO6 | OMAP3430_EN_UART3,
OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
/* Don't attach IVA interrupts */
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index ae2186892c85..54dfeb5d5667 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -109,16 +109,6 @@ static struct plat_serial8250_port serial_platform_data2[] = {
.regshift = 2,
.uartclk = OMAP24XX_BASE_BAUD * 16,
}, {
-#ifdef CONFIG_ARCH_OMAP4
- .membase = OMAP2_IO_ADDRESS(OMAP_UART4_BASE),
- .mapbase = OMAP_UART4_BASE,
- .irq = 70,
- .flags = UPF_BOOT_AUTOCONF,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = OMAP24XX_BASE_BAUD * 16,
- }, {
-#endif
.flags = 0
}
};
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index aac2cda60e09..102916f1e465 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -43,10 +43,10 @@
#define CM_X300_ETH_PHYS 0x08000010
-#define GPIO82_MMC2_IRQ (82)
-#define GPIO85_MMC2_WP (85)
+#define GPIO82_MMC_IRQ (82)
+#define GPIO85_MMC_WP (85)
-#define CM_X300_MMC2_IRQ IRQ_GPIO(GPIO82_MMC2_IRQ)
+#define CM_X300_MMC_IRQ IRQ_GPIO(GPIO82_MMC_IRQ)
#define GPIO95_RTC_CS (95)
#define GPIO96_RTC_WR (96)
@@ -292,37 +292,37 @@ static inline void cm_x300_init_nand(void) {}
#endif
#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
-/* The first MMC slot of CM-X300 is hardwired to Libertas card and has
+static struct pxamci_platform_data cm_x300_mci_platform_data = {
+ .detect_delay = 20,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .gpio_card_detect = GPIO82_MMC_IRQ,
+ .gpio_card_ro = GPIO85_MMC_WP,
+ .gpio_power = -1,
+};
+
+/* The second MMC slot of CM-X300 is hardwired to Libertas card and has
no detection/ro pins */
-static int cm_x300_mci_init(struct device *dev,
- irq_handler_t cm_x300_detect_int,
- void *data)
+static int cm_x300_mci2_init(struct device *dev,
+ irq_handler_t cm_x300_detect_int,
+ void *data)
{
return 0;
}
-static void cm_x300_mci_exit(struct device *dev, void *data)
+static void cm_x300_mci2_exit(struct device *dev, void *data)
{
}
-static struct pxamci_platform_data cm_x300_mci_platform_data = {
+static struct pxamci_platform_data cm_x300_mci2_platform_data = {
.detect_delay = 20,
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
- .init = cm_x300_mci_init,
- .exit = cm_x300_mci_exit,
+ .init = cm_x300_mci2_init,
+ .exit = cm_x300_mci2_exit,
.gpio_card_detect = -1,
.gpio_card_ro = -1,
.gpio_power = -1,
};
-static struct pxamci_platform_data cm_x300_mci2_platform_data = {
- .detect_delay = 20,
- .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
- .gpio_card_detect = GPIO82_MMC2_IRQ,
- .gpio_card_ro = GPIO85_MMC2_WP,
- .gpio_power = -1,
-};
-
static void __init cm_x300_init_mmc(void)
{
pxa_set_mci_info(&cm_x300_mci_platform_data);
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
index 494572825c7d..ec0e14b96682 100644
--- a/arch/arm/mach-pxa/colibri-pxa320.c
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -27,6 +27,7 @@
#include <mach/colibri.h>
#include <mach/pxafb.h>
#include <mach/ohci.h>
+#include <mach/audio.h>
#include "generic.h"
#include "devices.h"
@@ -145,7 +146,8 @@ static void __init colibri_pxa320_init_lcd(void)
static inline void colibri_pxa320_init_lcd(void) {}
#endif
-#if defined(SND_AC97_CODEC) || defined(SND_AC97_CODEC_MODULE)
+#if defined(CONFIG_SND_AC97_CODEC) || \
+ defined(CONFIG_SND_AC97_CODEC_MODULE)
static mfp_cfg_t colibri_pxa320_ac97_pin_config[] __initdata = {
GPIO34_AC97_SYSCLK,
GPIO35_AC97_SDATA_IN_0,
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
index 983cc8c20081..9e4d9816726a 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
@@ -447,6 +447,7 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
pxa27x_freq_table[i].frequency = freq;
pxa27x_freq_table[i].index = i;
}
+ pxa27x_freq_table[i].index = i;
pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
/*
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
index 67f34a8d8e60..149cdd9aee4d 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
@@ -102,7 +102,7 @@ static int setup_freqs_table(struct cpufreq_policy *policy,
table[i].index = i;
table[i].frequency = freqs[i].cpufreq_mhz * 1000;
}
- table[num].frequency = i;
+ table[num].index = i;
table[num].frequency = CPUFREQ_TABLE_END;
pxa3xx_freqs = freqs;
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index abff9e132749..83bd3c6e3884 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -604,7 +604,7 @@ static struct platform_device gpio_vbus = {
static const struct ads7846_platform_data tsc2046_info = {
.model = 7846,
.vref_delay_usecs = 100,
- .pressure_max = 512,
+ .pressure_max = 1024,
.debounce_max = 10,
.debounce_tol = 3,
.debounce_rep = 1,
diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S b/arch/arm/mach-pxa/include/mach/entry-macro.S
index 241880608ac6..a73bc86a3c26 100644
--- a/arch/arm/mach-pxa/include/mach/entry-macro.S
+++ b/arch/arm/mach-pxa/include/mach/entry-macro.S
@@ -46,5 +46,6 @@
beq 1001f
bic \irqstat, \irqstat, #0x80000000
mov \irqnr, \irqstat, lsr #16
+ add \irqnr, \irqnr, #(PXA_IRQ(0))
1001:
.endm
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index d694ce289668..6112af431fa4 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -25,6 +25,8 @@
#include "generic.h"
+#define MAX_INTERNAL_IRQS 128
+
#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
#define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
#define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
@@ -122,6 +124,8 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
{
int irq, i;
+ BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
+
pxa_internal_irq_nr = irq_nr;
for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) {
@@ -149,7 +153,8 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
}
#ifdef CONFIG_PM
-static unsigned long saved_icmr[2];
+static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32];
+static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
{
@@ -159,6 +164,8 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
saved_icmr[i] = _ICMR(irq);
_ICMR(irq) = 0;
}
+ for (i = 0; i < pxa_internal_irq_nr; i++)
+ saved_ipr[i] = IPR(i);
return 0;
}
@@ -171,6 +178,8 @@ static int pxa_irq_resume(struct sys_device *dev)
_ICMR(irq) = saved_icmr[i];
_ICLR(irq) = 0;
}
+ for (i = 0; i < pxa_internal_irq_nr; i++)
+ IPR(i) = saved_ipr[i];
ICCR = 1;
return 0;
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index bb2cc0dd44ec..0b92291a58f6 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -292,10 +292,10 @@ const static unsigned int palmtc_keypad_col_gpios[] = {
static struct matrix_keypad_platform_data palmtc_keypad_platform_data = {
.keymap_data = &palmtc_keymap_data,
- .col_gpios = palmtc_keypad_row_gpios,
- .num_col_gpios = 12,
- .row_gpios = palmtc_keypad_col_gpios,
- .num_row_gpios = 4,
+ .row_gpios = palmtc_keypad_row_gpios,
+ .num_row_gpios = ARRAY_SIZE(palmtc_keypad_row_gpios),
+ .col_gpios = palmtc_keypad_col_gpios,
+ .num_col_gpios = ARRAY_SIZE(palmtc_keypad_col_gpios),
.active_low = 1,
.debounce_ms = 20,
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index ee8d6038ce82..d98023f55503 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/gpio_keys.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/mtd/physmap.h>
@@ -375,6 +376,43 @@ static struct platform_device spitzkbd_device = {
};
+static struct gpio_keys_button spitz_gpio_keys[] = {
+ {
+ .type = EV_PWR,
+ .code = KEY_SUSPEND,
+ .gpio = SPITZ_GPIO_ON_KEY,
+ .desc = "On/Off",
+ .wakeup = 1,
+ },
+ /* Two buttons detecting the lid state */
+ {
+ .type = EV_SW,
+ .code = 0,
+ .gpio = SPITZ_GPIO_SWA,
+ .desc = "Display Down",
+ },
+ {
+ .type = EV_SW,
+ .code = 1,
+ .gpio = SPITZ_GPIO_SWB,
+ .desc = "Lid Closed",
+ },
+};
+
+static struct gpio_keys_platform_data spitz_gpio_keys_platform_data = {
+ .buttons = spitz_gpio_keys,
+ .nbuttons = ARRAY_SIZE(spitz_gpio_keys),
+};
+
+static struct platform_device spitz_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &spitz_gpio_keys_platform_data,
+ },
+};
+
+
/*
* Spitz LEDs
*/
@@ -689,6 +727,7 @@ static struct platform_device sharpsl_rom_device = {
static struct platform_device *devices[] __initdata = {
&spitzscoop_device,
&spitzkbd_device,
+ &spitz_gpio_keys_device,
&spitzled_device,
&sharpsl_nand_device,
&sharpsl_rom_device,
@@ -740,11 +779,36 @@ static void __init common_init(void)
pxa_set_i2c_info(NULL);
}
+#if defined(CONFIG_MACH_AKITA) || defined(CONFIG_MACH_BORZOI)
+static struct nand_bbt_descr sharpsl_akita_bbt = {
+ .options = 0,
+ .offs = 4,
+ .len = 1,
+ .pattern = scan_ff_pattern
+};
+
+static struct nand_ecclayout akita_oobinfo = {
+ .eccbytes = 24,
+ .eccpos = {
+ 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
+ 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
+ 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
+ .oobfree = {{0x08, 0x09}}
+};
+#endif
+
#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
static void __init spitz_init(void)
{
spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON;
+#ifdef CONFIG_MACH_BORZOI
+ if (machine_is_borzoi()) {
+ sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt;
+ sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo;
+ }
+#endif
+
platform_scoop_config = &spitz_pcmcia_config;
common_init();
@@ -769,22 +833,6 @@ static struct i2c_board_info akita_i2c_board_info[] = {
},
};
-static struct nand_bbt_descr sharpsl_akita_bbt = {
- .options = 0,
- .offs = 4,
- .len = 1,
- .pattern = scan_ff_pattern
-};
-
-static struct nand_ecclayout akita_oobinfo = {
- .eccbytes = 24,
- .eccpos = {
- 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
- 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
- 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
- .oobfree = {{0x08, 0x09}}
-};
-
static void __init akita_init(void)
{
spitz_ficp_platform_data.gpio_pwdown = AKITA_GPIO_IR_ON;
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index dfc9b0bc6eb2..c48e1f2c3349 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -70,6 +70,8 @@ config MACH_REALVIEW_PBX
bool "Support RealView/PBX platform"
select ARM_GIC
select HAVE_PATA_PLATFORM
+ select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !HIGH_PHYS_OFFSET
+ select ZONE_DMA if SPARSEMEM
help
Include support for the ARM(R) RealView PBX platform.
@@ -82,6 +84,7 @@ config REALVIEW_HIGH_PHYS_OFFSET
0x70000000, 256MB of which being mirrored at 0x00000000. If
the board supports 512MB of RAM, this option allows the
memory to be accessed contiguously at the high physical
- offset.
+ offset. On the PBX board, disabling this option allows 1GB of
+ RAM to be used with SPARSEMEM.
endmenu
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index a2083b60e3fb..9f293438e020 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -59,6 +59,25 @@
/* used by entry-macro.S and platsmp.c */
void __iomem *gic_cpu_base_addr;
+#ifdef CONFIG_ZONE_DMA
+/*
+ * Adjust the zones if there are restrictions for DMA access.
+ */
+void __init realview_adjust_zones(int node, unsigned long *size,
+ unsigned long *hole)
+{
+ unsigned long dma_size = SZ_256M >> PAGE_SHIFT;
+
+ if (!machine_is_realview_pbx() || node || (size[0] <= dma_size))
+ return;
+
+ size[ZONE_NORMAL] = size[0] - dma_size;
+ size[ZONE_DMA] = dma_size;
+ hole[ZONE_NORMAL] = hole[0];
+ hole[ZONE_DMA] = 0;
+}
+#endif
+
/*
* This is the RealView sched_clock implementation. This has
* a resolution of 41.7ns, and a maximum value of about 179s.
@@ -543,7 +562,7 @@ static int realview_clcd_setup(struct clcd_fb *fb)
fb->panel = realview_clcd_panel();
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
- &dma, GFP_KERNEL);
+ &dma, GFP_KERNEL | GFP_DMA);
if (!fb->fb.screen_base) {
printk(KERN_ERR "CLCD: unable to map framebuffer\n");
return -ENOMEM;
@@ -788,3 +807,24 @@ void __init realview_timer_init(unsigned int timer_irq)
realview_clocksource_init();
realview_clockevents_init(timer_irq);
}
+
+/*
+ * Setup the memory banks.
+ */
+void realview_fixup(struct machine_desc *mdesc, struct tag *tags, char **from,
+ struct meminfo *meminfo)
+{
+ /*
+ * Most RealView platforms have 512MB contiguous RAM at 0x70000000.
+ * Half of this is mirrored at 0.
+ */
+#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
+ meminfo->bank[0].start = 0x70000000;
+ meminfo->bank[0].size = SZ_512M;
+ meminfo->nr_banks = 1;
+#else
+ meminfo->bank[0].start = 0;
+ meminfo->bank[0].size = SZ_256M;
+ meminfo->nr_banks = 1;
+#endif
+}
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 46cd6acb4d40..781bca68a9fa 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -25,6 +25,7 @@
#include <linux/amba/bus.h>
#include <linux/io.h>
+#include <asm/setup.h>
#include <asm/leds.h>
#define AMBA_DEVICE(name,busid,base,plat) \
@@ -44,6 +45,8 @@ static struct amba_device name##_device = { \
/* .dma = base##_DMA,*/ \
}
+struct machine_desc;
+
extern struct platform_device realview_flash_device;
extern struct platform_device realview_cf_device;
extern struct platform_device realview_i2c_device;
@@ -61,5 +64,8 @@ extern void realview_timer_init(unsigned int timer_irq);
extern int realview_flash_register(struct resource *res, u32 num);
extern int realview_eth_register(const char *name, struct resource *res);
extern int realview_usb_register(struct resource *res);
+extern void realview_fixup(struct machine_desc *mdesc, struct tag *tags,
+ char **from, struct meminfo *meminfo);
+extern void (*realview_reset)(char);
#endif
diff --git a/arch/arm/mach-realview/include/mach/board-pb1176.h b/arch/arm/mach-realview/include/mach/board-pb1176.h
index 98f8e7eeacc2..34b80b7d40b8 100644
--- a/arch/arm/mach-realview/include/mach/board-pb1176.h
+++ b/arch/arm/mach-realview/include/mach/board-pb1176.h
@@ -73,4 +73,9 @@
#define REALVIEW_PB1176_GIC_DIST_BASE 0x10041000 /* GIC distributor, on FPGA */
#define REALVIEW_PB1176_L220_BASE 0x10110000 /* L220 registers */
+/*
+ * Control register SYS_RESETCTL is set to 1 to force a soft reset
+ */
+#define REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL 0x0100
+
#endif /* __ASM_ARCH_BOARD_PB1176_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pb11mp.h b/arch/arm/mach-realview/include/mach/board-pb11mp.h
index f0d68e0fea01..7abf918b77e9 100644
--- a/arch/arm/mach-realview/include/mach/board-pb11mp.h
+++ b/arch/arm/mach-realview/include/mach/board-pb11mp.h
@@ -81,4 +81,16 @@
#define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */
#define REALVIEW_TC11MP_L220_BASE 0x1F002000 /* L220 registers */
+ /*
+ * Values for REALVIEW_SYS_RESET_CTRL
+ */
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR 0x01
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGINIT 0x02
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_DLLRESET 0x03
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_PLLRESET 0x04
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_POR 0x05
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_DoC 0x06
+
+#define REALVIEW_PB11MP_SYS_CTRL_LED (1 << 0)
+
#endif /* __ASM_ARCH_BOARD_PB11MP_H */
diff --git a/arch/arm/mach-realview/include/mach/memory.h b/arch/arm/mach-realview/include/mach/memory.h
index 293c30025e7e..2417bbcf97fd 100644
--- a/arch/arm/mach-realview/include/mach/memory.h
+++ b/arch/arm/mach-realview/include/mach/memory.h
@@ -29,4 +29,53 @@
#define PHYS_OFFSET UL(0x00000000)
#endif
+#if !defined(__ASSEMBLY__) && defined(CONFIG_ZONE_DMA)
+extern void realview_adjust_zones(int node, unsigned long *size,
+ unsigned long *hole);
+#define arch_adjust_zones(node, size, hole) \
+ realview_adjust_zones(node, size, hole)
+
+#define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_256M - 1)
+#define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_256M)
+#endif
+
+#ifdef CONFIG_SPARSEMEM
+
+/*
+ * Sparsemem definitions for RealView PBX.
+ *
+ * The RealView PBX board has another block of 512MB of RAM at 0x20000000,
+ * however only the block at 0x70000000 (or the 256MB mirror at 0x00000000)
+ * may be used for DMA.
+ *
+ * The macros below define a section size of 256MB and a non-linear virtual to
+ * physical mapping:
+ *
+ * 256MB @ 0x00000000 -> PAGE_OFFSET
+ * 512MB @ 0x20000000 -> PAGE_OFFSET + 0x10000000
+ * 256MB @ 0x80000000 -> PAGE_OFFSET + 0x30000000
+ */
+#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
+#error "SPARSEMEM not available with REALVIEW_HIGH_PHYS_OFFSET"
+#endif
+
+#define MAX_PHYSMEM_BITS 32
+#define SECTION_SIZE_BITS 28
+
+/* bank page offsets */
+#define PAGE_OFFSET1 (PAGE_OFFSET + 0x10000000)
+#define PAGE_OFFSET2 (PAGE_OFFSET + 0x30000000)
+
+#define __phys_to_virt(phys) \
+ ((phys) >= 0x80000000 ? (phys) - 0x80000000 + PAGE_OFFSET2 : \
+ (phys) >= 0x20000000 ? (phys) - 0x20000000 + PAGE_OFFSET1 : \
+ (phys) + PAGE_OFFSET)
+
+#define __virt_to_phys(virt) \
+ ((virt) >= PAGE_OFFSET2 ? (virt) - PAGE_OFFSET2 + 0x80000000 : \
+ (virt) >= PAGE_OFFSET1 ? (virt) - PAGE_OFFSET1 + 0x20000000 : \
+ (virt) - PAGE_OFFSET)
+
+#endif /* CONFIG_SPARSEMEM */
+
#endif
diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h
index c8f50835fed2..4f46bf71e752 100644
--- a/arch/arm/mach-realview/include/mach/platform.h
+++ b/arch/arm/mach-realview/include/mach/platform.h
@@ -119,19 +119,6 @@
#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
-/*
- * Values for REALVIEW_SYS_RESET_CTRL
- */
-#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR 0x01
-#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT 0x02
-#define REALVIEW_SYS_CTRL_RESET_DLLRESET 0x03
-#define REALVIEW_SYS_CTRL_RESET_PLLRESET 0x04
-#define REALVIEW_SYS_CTRL_RESET_POR 0x05
-#define REALVIEW_SYS_CTRL_RESET_DoC 0x06
-
-#define REALVIEW_SYS_CTRL_LED (1 << 0)
-
-
/* ------------------------------------------------------------------------
* RealView control registers
* ------------------------------------------------------------------------
@@ -153,7 +140,7 @@
* SYS_CLD, SYS_BOOTCS
*/
#define REALVIEW_SYS_LOCK_LOCKED (1 << 16)
-#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */
+#define REALVIEW_SYS_LOCKVAL_MASK 0xA05F /* Enable write access */
/*
* REALVIEW_SYS_FLASH
diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h
index 1a15a441e027..a30f2e3ec178 100644
--- a/arch/arm/mach-realview/include/mach/system.h
+++ b/arch/arm/mach-realview/include/mach/system.h
@@ -25,6 +25,8 @@
#include <mach/hardware.h>
#include <mach/platform.h>
+void (*realview_reset)(char mode);
+
static inline void arch_idle(void)
{
/*
@@ -36,16 +38,12 @@ static inline void arch_idle(void)
static inline void arch_reset(char mode, const char *cmd)
{
- void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET;
- unsigned int val;
-
/*
* To reset, we hit the on-board reset register
* in the system FPGA
*/
- val = __raw_readl(hdr_ctrl);
- val |= REALVIEW_SYS_CTRL_RESET_CONFIGCLR;
- __raw_writel(val, hdr_ctrl);
+ if (realview_reset)
+ realview_reset(mode);
}
#endif
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index a88458b4799d..009265818d55 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -146,11 +146,8 @@ static void __init poke_milo(void)
* register. The BootMonitor waits for this register to become
* non-zero.
*/
-#define REALVIEW_SYS_FLAGSS_OFFSET 0x30
-#define REALVIEW_SYS_FLAGSC_OFFSET 0x34
__raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
- __io_address(REALVIEW_SYS_BASE) +
- REALVIEW_SYS_FLAGSS_OFFSET);
+ __io_address(REALVIEW_SYS_FLAGSSET));
mb();
}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 1d65e64ae571..917f8ca3abff 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -415,6 +415,7 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
.phys_io = REALVIEW_EB_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_EB_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
+ .fixup = realview_fixup,
.map_io = realview_eb_map_io,
.init_irq = gic_init_irq,
.timer = &realview_eb_timer,
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 2817fe099319..7fb726d5f8b9 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -290,6 +290,28 @@ static struct sys_timer realview_pb1176_timer = {
.init = realview_pb1176_timer_init,
};
+static void realview_pb1176_reset(char mode)
+{
+ void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
+ REALVIEW_SYS_RESETCTL_OFFSET;
+ void __iomem *rst_hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
+ REALVIEW_SYS_LOCK_OFFSET;
+ __raw_writel(REALVIEW_SYS_LOCKVAL_MASK, rst_hdr_ctrl);
+ __raw_writel(REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL, hdr_ctrl);
+}
+
+static void realview_pb1176_fixup(struct machine_desc *mdesc,
+ struct tag *tags, char **from,
+ struct meminfo *meminfo)
+{
+ /*
+ * RealView PB1176 only has 128MB of RAM mapped at 0.
+ */
+ meminfo->bank[0].start = 0;
+ meminfo->bank[0].size = SZ_128M;
+ meminfo->nr_banks = 1;
+}
+
static void __init realview_pb1176_init(void)
{
int i;
@@ -313,6 +335,7 @@ static void __init realview_pb1176_init(void)
#ifdef CONFIG_LEDS
leds_event = realview_leds_event;
#endif
+ realview_reset = realview_pb1176_reset;
}
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
@@ -320,6 +343,7 @@ MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
.phys_io = REALVIEW_PB1176_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PB1176_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
+ .fixup = realview_pb1176_fixup,
.map_io = realview_pb1176_map_io,
.init_irq = gic_init_irq,
.timer = &realview_pb1176_timer,
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 94680fcf726d..9bbbfc05f225 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -299,6 +299,21 @@ static struct sys_timer realview_pb11mp_timer = {
.init = realview_pb11mp_timer_init,
};
+static void realview_pb11mp_reset(char mode)
+{
+ void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
+ REALVIEW_SYS_RESETCTL_OFFSET;
+ unsigned int val;
+
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA
+ */
+ val = __raw_readl(hdr_ctrl);
+ val |= REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR;
+ __raw_writel(val, hdr_ctrl);
+}
+
static void __init realview_pb11mp_init(void)
{
int i;
@@ -324,6 +339,7 @@ static void __init realview_pb11mp_init(void)
#ifdef CONFIG_LEDS
leds_event = realview_leds_event;
#endif
+ realview_reset = realview_pb11mp_reset;
}
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
@@ -331,6 +347,7 @@ MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
.phys_io = REALVIEW_PB11MP_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PB11MP_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
+ .fixup = realview_fixup,
.map_io = realview_pb11mp_map_io,
.init_irq = gic_init_irq,
.timer = &realview_pb11mp_timer,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 941beb2b9709..fe861e96c566 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -298,6 +298,7 @@ MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
.phys_io = REALVIEW_PBA8_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PBA8_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
+ .fixup = realview_fixup,
.map_io = realview_pba8_map_io,
.init_irq = gic_init_irq,
.timer = &realview_pba8_timer,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 7e4bc6cdca52..ec39488e2b42 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -304,6 +304,26 @@ static struct sys_timer realview_pbx_timer = {
.init = realview_pbx_timer_init,
};
+static void realview_pbx_fixup(struct machine_desc *mdesc, struct tag *tags,
+ char **from, struct meminfo *meminfo)
+{
+#ifdef CONFIG_SPARSEMEM
+ /*
+ * Memory configuration with SPARSEMEM enabled on RealView PBX (see
+ * asm/mach/memory.h for more information).
+ */
+ meminfo->bank[0].start = 0;
+ meminfo->bank[0].size = SZ_256M;
+ meminfo->bank[1].start = 0x20000000;
+ meminfo->bank[1].size = SZ_512M;
+ meminfo->bank[2].start = 0x80000000;
+ meminfo->bank[2].size = SZ_256M;
+ meminfo->nr_banks = 3;
+#else
+ realview_fixup(mdesc, tags, from, meminfo);
+#endif
+}
+
static void __init realview_pbx_init(void)
{
int i;
@@ -345,6 +365,7 @@ MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
.phys_io = REALVIEW_PBX_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PBX_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
+ .fixup = realview_pbx_fixup,
.map_io = realview_pbx_map_io,
.init_irq = gic_init_irq,
.timer = &realview_pbx_timer,
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
index 7974afca297c..9664e011dae2 100644
--- a/arch/arm/mach-s3c2410/gpio.c
+++ b/arch/arm/mach-s3c2410/gpio.c
@@ -28,6 +28,7 @@
#include <linux/io.h>
#include <mach/hardware.h>
+#include <mach/gpio-fns.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index c3a2629e0ded..92e2687009ea 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -110,6 +110,8 @@ enum s3c2410_dma_loadst {
* waiting for reloads */
#define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */
+#define S3C2410_DMAF_CIRCULAR (1 << 2) /* no circular dma support */
+
/* dma buffer */
struct s3c2410_dma_buf;
@@ -194,4 +196,9 @@ struct s3c2410_dma_chan {
typedef unsigned long dma_device_t;
+static inline bool s3c_dma_has_circular(void)
+{
+ return false;
+}
+
#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index d7bba919a77e..a8b69d77571b 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -103,6 +103,7 @@ config MACH_MINI2440
select LEDS_TRIGGER_BACKLIGHT
select SND_S3C24XX_SOC_S3C24XX_UDA134X
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
available via various sources. It can come with a 3.5" or 7" touch LCD.
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
index ec71a6965786..1c3382fefdd2 100644
--- a/arch/arm/mach-s3c2440/mach-mini2440.c
+++ b/arch/arm/mach-s3c2440/mach-mini2440.c
@@ -144,7 +144,7 @@ static struct s3c2410_udc_mach_info mini2440_udc_cfg __initdata = {
.type = (S3C2410_LCDCON1_TFT16BPP |\
S3C2410_LCDCON1_TFT)
-struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
+static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
[0] = { /* mini2440 + 3.5" TFT + touchscreen */
_LCD_DECLARE(
7, /* The 3.5 is quite fast */
@@ -191,7 +191,7 @@ struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
-struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
+static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
.displays = &mini2440_lcd_cfg[0], /* not constant! see init */
.num_displays = 1,
.default_display = 0,
diff --git a/arch/arm/mach-s3c6400/include/mach/dma.h b/arch/arm/mach-s3c6400/include/mach/dma.h
index 1067619f0ba0..6723860748be 100644
--- a/arch/arm/mach-s3c6400/include/mach/dma.h
+++ b/arch/arm/mach-s3c6400/include/mach/dma.h
@@ -58,12 +58,9 @@ enum dma_ch {
DMACH_MAX /* the end */
};
-static __inline__ int s3c_dma_has_circular(void)
+static __inline__ bool s3c_dma_has_circular(void)
{
- /* we will be supporting ciruclar buffers as soon as we have DMA
- * engine support.
- */
- return 1;
+ return true;
}
#define S3C2410_DMAF_CIRCULAR (1 << 0)
diff --git a/arch/arm/mach-s3c6410/Kconfig b/arch/arm/mach-s3c6410/Kconfig
index 53fc3ff657f7..72d4b11b2077 100644
--- a/arch/arm/mach-s3c6410/Kconfig
+++ b/arch/arm/mach-s3c6410/Kconfig
@@ -77,6 +77,7 @@ config SMDK6410_WM1190_EV1
depends on MACH_SMDK6410
select REGULATOR
select REGULATOR_WM8350
+ select S3C24XX_GPIO_EXTRA64
select MFD_WM8350_I2C
select MFD_WM8350_CONFIG_MODE_0
select MFD_WM8350_CONFIG_MODE_3
diff --git a/arch/arm/mach-s3c6410/mach-smdk6410.c b/arch/arm/mach-s3c6410/mach-smdk6410.c
index ea51dbe76e3e..9f1a21462620 100644
--- a/arch/arm/mach-s3c6410/mach-smdk6410.c
+++ b/arch/arm/mach-s3c6410/mach-smdk6410.c
@@ -320,6 +320,9 @@ static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
{
int i;
+ /* Configure the IRQ line */
+ s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
/* Instantiate the regulators */
for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
wm8350_register_regulator(wm8350,
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index be60d6deee8b..653e25be3dd8 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -408,7 +408,7 @@ static struct platform_device keypad_device = {
};
static struct platform_device rtc_device = {
- .name = "rtc0",
+ .name = "rtc-coh901331",
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index e993140edd88..9264d814cd7a 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -122,10 +122,7 @@ config CPU_ARM920T
select CPU_TLB_V4WBI if MMU
help
The ARM920T is licensed to be produced by numerous vendors,
- and is used in the Maverick EP9312 and the Samsung S3C2410.
-
- More information on the Maverick EP9312 at
- <http://linuxdevices.com/products/PD2382866068.html>.
+ and is used in the Cirrus EP93xx and the Samsung S3C2410.
Say Y if you want support for the ARM920T processor.
Otherwise, say N.
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 6bda76a43199..a9e22e31eaa1 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -50,10 +50,7 @@ void __new_context(struct mm_struct *mm)
isb();
flush_tlb_all();
if (icache_is_vivt_asid_tagged()) {
- asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
- "mcr p15, 0, %0, c7, c5, 6 @ flush BTAC/BTB\n"
- :
- : "r" (0));
+ __flush_icache_all();
dsb();
}
}
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index b30925fcbcdc..b9590a7085ca 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -205,7 +205,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
order = get_order(size);
- if (mask != 0xffffffff)
+ if (mask < 0xffffffffULL)
gfp |= GFP_DMA;
page = alloc_pages(gfp, order);
@@ -289,7 +289,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
if (!mask)
goto error;
- if (mask != 0xffffffff)
+ if (mask < 0xffffffffULL)
gfp |= GFP_DMA;
virt = kmalloc(size, gfp);
if (!virt)
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index b27942909b23..7f294f307c83 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -18,10 +18,6 @@
#include "mm.h"
-#ifdef CONFIG_ARM_ERRATA_411920
-extern void v6_icache_inval_all(void);
-#endif
-
#ifdef CONFIG_CPU_CACHE_VIPT
#define ALIAS_FLUSH_START 0xffff4000
@@ -35,16 +31,11 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
flush_tlb_kernel_page(to);
asm( "mcrr p15, 0, %1, %0, c14\n"
- " mcr p15, 0, %2, c7, c10, 4\n"
-#ifndef CONFIG_ARM_ERRATA_411920
- " mcr p15, 0, %2, c7, c5, 0\n"
-#endif
+ " mcr p15, 0, %2, c7, c10, 4"
:
: "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
: "cc");
-#ifdef CONFIG_ARM_ERRATA_411920
- v6_icache_inval_all();
-#endif
+ __flush_icache_all();
}
void flush_cache_mm(struct mm_struct *mm)
@@ -57,16 +48,11 @@ void flush_cache_mm(struct mm_struct *mm)
if (cache_is_vipt_aliasing()) {
asm( "mcr p15, 0, %0, c7, c14, 0\n"
- " mcr p15, 0, %0, c7, c10, 4\n"
-#ifndef CONFIG_ARM_ERRATA_411920
- " mcr p15, 0, %0, c7, c5, 0\n"
-#endif
+ " mcr p15, 0, %0, c7, c10, 4"
:
: "r" (0)
: "cc");
-#ifdef CONFIG_ARM_ERRATA_411920
- v6_icache_inval_all();
-#endif
+ __flush_icache_all();
}
}
@@ -81,16 +67,11 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned
if (cache_is_vipt_aliasing()) {
asm( "mcr p15, 0, %0, c7, c14, 0\n"
- " mcr p15, 0, %0, c7, c10, 4\n"
-#ifndef CONFIG_ARM_ERRATA_411920
- " mcr p15, 0, %0, c7, c5, 0\n"
-#endif
+ " mcr p15, 0, %0, c7, c10, 4"
:
: "r" (0)
: "cc");
-#ifdef CONFIG_ARM_ERRATA_411920
- v6_icache_inval_all();
-#endif
+ __flush_icache_all();
}
}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 40940d7ce4ff..52c40d155672 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -273,7 +273,6 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
struct membank *bank = &mi->bank[i];
if (!bank->highmem)
free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
- memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
}
/*
@@ -370,6 +369,19 @@ int pfn_valid(unsigned long pfn)
return 0;
}
EXPORT_SYMBOL(pfn_valid);
+
+static void arm_memory_present(struct meminfo *mi, int node)
+{
+}
+#else
+static void arm_memory_present(struct meminfo *mi, int node)
+{
+ int i;
+ for_each_nodebank(i, mi, node) {
+ struct membank *bank = &mi->bank[i];
+ memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
+ }
+}
#endif
static int __init meminfo_cmp(const void *_a, const void *_b)
@@ -427,6 +439,12 @@ void __init bootmem_init(void)
*/
if (node == initrd_node)
bootmem_reserve_initrd(node);
+
+ /*
+ * Sparsemem tries to allocate bootmem in memory_present(),
+ * so must be done after the fixed reservations
+ */
+ arm_memory_present(mi, node);
}
/*
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 02243eeccf50..ea67be0223ac 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -117,6 +117,13 @@ static void __init early_cachepolicy(char **p)
}
if (i == ARRAY_SIZE(cache_policies))
printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
+ /*
+ * This restriction is partly to do with the way we boot; it is
+ * unpredictable to have memory mapped using two different sets of
+ * memory attributes (shared, type, and cache attribs). We can not
+ * change these attributes once the initial assembly has setup the
+ * page tables.
+ */
if (cpu_architecture() >= CPU_ARCH_ARMv6) {
printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
cachepolicy = CPOLICY_WRITEBACK;
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 194737d60a22..70f75d2e3ead 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -32,8 +32,10 @@
#ifndef CONFIG_SMP
#define TTB_FLAGS TTB_RGN_WBWA
+#define PMD_FLAGS PMD_SECT_WB
#else
#define TTB_FLAGS TTB_RGN_WBWA|TTB_S
+#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
#endif
ENTRY(cpu_v6_proc_init)
@@ -222,10 +224,9 @@ __v6_proc_info:
.long 0x0007b000
.long 0x0007f000
.long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
+ PMD_SECT_AP_READ | \
+ PMD_FLAGS
.long PMD_TYPE_SECT | \
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 23ebcf6eab9f..3a285218fd15 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -33,9 +33,11 @@
#ifndef CONFIG_SMP
/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
#define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB
+#define PMD_FLAGS PMD_SECT_WB
#else
/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
#define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
+#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
#endif
ENTRY(cpu_v7_proc_init)
@@ -184,9 +186,10 @@ cpu_v7_name:
*/
__v7_setup:
#ifdef CONFIG_SMP
- mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode and
- orr r0, r0, #(1 << 6) | (1 << 0) @ TLB ops broadcasting
- mcr p15, 0, r0, c1, c0, 1
+ mrc p15, 0, r0, c1, c0, 1
+ tst r0, #(1 << 6) @ SMP/nAMP mode enabled?
+ orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and
+ mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting
#endif
adr r12, __v7_setup_stack @ the local stack
stmia r12, {r0-r5, r7, r9, r11, lr}
@@ -326,10 +329,9 @@ __v7_proc_info:
.long 0x000f0000 @ Required ID value
.long 0x000f0000 @ Mask for ID
.long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
+ PMD_SECT_AP_READ | \
+ PMD_FLAGS
.long PMD_TYPE_SECT | \
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
diff --git a/arch/arm/oprofile/op_model_v6.c b/arch/arm/oprofile/op_model_v6.c
index fe581383d3e2..f7d2ec5ee9a1 100644
--- a/arch/arm/oprofile/op_model_v6.c
+++ b/arch/arm/oprofile/op_model_v6.c
@@ -33,6 +33,9 @@ static int irqs[] = {
#ifdef CONFIG_ARCH_OMAP2
3,
#endif
+#ifdef CONFIG_ARCH_BCMRING
+ IRQ_PMUIRQ, /* for BCMRING, ARM PMU interrupt is 43 */
+#endif
};
static void armv6_pmu_stop(void)
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 1868c0d8f9b5..341235c278ac 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -127,7 +127,7 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy)
}
/* FIXME: what's the actual transition time? */
- policy->cpuinfo.transition_latency = 10 * 1000 * 1000;
+ policy->cpuinfo.transition_latency = 300 * 1000;
return 0;
}
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index fd3154ae69b1..68eaae324b6a 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -691,13 +691,16 @@ static inline void disable_lnk(int lch)
static inline void omap2_enable_irq_lch(int lch)
{
u32 val;
+ unsigned long flags;
if (!cpu_class_is_omap2())
return;
+ spin_lock_irqsave(&dma_chan_lock, flags);
val = dma_read(IRQENABLE_L0);
val |= 1 << lch;
dma_write(val, IRQENABLE_L0);
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
}
int omap_request_dma(int dev_id, const char *dev_name,
@@ -799,10 +802,13 @@ void omap_free_dma(int lch)
if (cpu_class_is_omap2()) {
u32 val;
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
/* Disable interrupts */
val = dma_read(IRQENABLE_L0);
val &= ~(1 << lch);
dma_write(val, IRQENABLE_L0);
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
/* Clear the CSR register and IRQ status register */
dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));
@@ -829,10 +835,10 @@ EXPORT_SYMBOL(omap_free_dma);
*
* @param arb_rate
* @param max_fifo_depth
- * @param tparams - Number of thereads to reserve : DMA_THREAD_RESERVE_NORM
- * DMA_THREAD_RESERVE_ONET
- * DMA_THREAD_RESERVE_TWOT
- * DMA_THREAD_RESERVE_THREET
+ * @param tparams - Number of threads to reserve : DMA_THREAD_RESERVE_NORM
+ * DMA_THREAD_RESERVE_ONET
+ * DMA_THREAD_RESERVE_TWOT
+ * DMA_THREAD_RESERVE_THREET
*/
void
omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
@@ -844,11 +850,14 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
return;
}
+ if (max_fifo_depth == 0)
+ max_fifo_depth = 1;
if (arb_rate == 0)
arb_rate = 1;
- reg = (arb_rate & 0xff) << 16;
- reg |= (0xff & max_fifo_depth);
+ reg = 0xff & max_fifo_depth;
+ reg |= (0x3 & tparams) << 12;
+ reg |= (arb_rate & 0xff) << 16;
dma_write(reg, GCR);
}
@@ -975,6 +984,14 @@ void omap_stop_dma(int lch)
{
u32 l;
+ /* Disable all interrupts on the channel */
+ if (cpu_class_is_omap1())
+ dma_write(0, CICR(lch));
+
+ l = dma_read(CCR(lch));
+ l &= ~OMAP_DMA_CCR_EN;
+ dma_write(l, CCR(lch));
+
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch = lch;
char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
@@ -992,18 +1009,8 @@ void omap_stop_dma(int lch)
next_lch = dma_chan[cur_lch].next_lch;
cur_lch = next_lch;
} while (next_lch != -1);
-
- return;
}
- /* Disable all interrupts on the channel */
- if (cpu_class_is_omap1())
- dma_write(0, CICR(lch));
-
- l = dma_read(CCR(lch));
- l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
-
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
}
EXPORT_SYMBOL(omap_stop_dma);
@@ -1107,6 +1114,14 @@ int omap_dma_running(void)
{
int lch;
+ /*
+ * On OMAP1510, internal LCD controller will start the transfer
+ * when it gets enabled, so assume DMA running if LCD enabled.
+ */
+ if (cpu_is_omap1510())
+ if (omap_readw(0xfffec000 + 0x00) & (1 << 0))
+ return 1;
+
/* Check if LCD DMA is running */
if (cpu_is_omap16xx())
if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 71ebd7fcfea1..7c345b757df1 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -373,7 +373,7 @@ static inline int gpio_valid(int gpio)
static int check_gpio(int gpio)
{
- if (unlikely(gpio_valid(gpio)) < 0) {
+ if (unlikely(gpio_valid(gpio) < 0)) {
printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
dump_stack();
return -1;
diff --git a/arch/arm/plat-omap/include/mach/keypad.h b/arch/arm/plat-omap/include/mach/keypad.h
index d91b9be334ff..3ae52ccc793c 100644
--- a/arch/arm/plat-omap/include/mach/keypad.h
+++ b/arch/arm/plat-omap/include/mach/keypad.h
@@ -10,7 +10,7 @@
#ifndef ASMARM_ARCH_KEYPAD_H
#define ASMARM_ARCH_KEYPAD_H
-#include <linux/input/matrix_keypad.h>
+#warning: Please update the board to use matrix_keypad.h instead
struct omap_kp_platform_data {
int rows;
@@ -37,6 +37,9 @@ struct omap_kp_platform_data {
#define KEY_PERSISTENT 0x00800000
#define KEYNUM_MASK 0x00EFFFFF
+#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
+#define PERSISTENT_KEY(col, row) (((col) << 28) | ((row) << 24) | \
+ KEY_PERSISTENT)
#endif
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index 4b6012707307..94584f167a82 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -664,7 +664,7 @@ static size_t iopgtable_clear_entry_core(struct iommu *obj, u32 da)
nent = 1; /* for the next L1 entry */
} else {
bytes = IOPGD_SIZE;
- if (*iopgd & IOPGD_SUPER) {
+ if ((*iopgd & IOPGD_SUPER) == IOPGD_SUPER) {
nent *= 16;
/* rewind to the 1st entry */
iopgd = (u32 *)((u32)iopgd & IOSUPER_MASK);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 88ac9768f1c1..e664b912d7bb 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -595,7 +595,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
rx &= 1;
if (cpu_is_omap2430() || cpu_is_omap34xx()) {
w = OMAP_MCBSP_READ(io_base, RCCR);
- w |= (tx ? RDISABLE : 0);
+ w |= (rx ? RDISABLE : 0);
OMAP_MCBSP_WRITE(io_base, RCCR, w);
}
w = OMAP_MCBSP_READ(io_base, SPCR1);
diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h
index 22086e696e8e..857a6839071c 100644
--- a/arch/arm/plat-pxa/include/plat/mfp.h
+++ b/arch/arm/plat-pxa/include/plat/mfp.h
@@ -16,7 +16,7 @@
#ifndef __ASM_PLAT_MFP_H
#define __ASM_PLAT_MFP_H
-#define mfp_to_gpio(m) ((m) % 128)
+#define mfp_to_gpio(m) ((m) % 256)
/* list of all the configurable MFP pins */
enum {
diff --git a/arch/arm/plat-pxa/mfp.c b/arch/arm/plat-pxa/mfp.c
index 9405d0379c85..be58f9fe65b0 100644
--- a/arch/arm/plat-pxa/mfp.c
+++ b/arch/arm/plat-pxa/mfp.c
@@ -207,7 +207,7 @@ unsigned long mfp_read(int mfp)
{
unsigned long val, flags;
- BUG_ON(mfp >= MFP_PIN_MAX);
+ BUG_ON(mfp < 0 || mfp >= MFP_PIN_MAX);
spin_lock_irqsave(&mfp_spin_lock, flags);
val = mfpr_readl(mfp_table[mfp].mfpr_off);
@@ -220,7 +220,7 @@ void mfp_write(int mfp, unsigned long val)
{
unsigned long flags;
- BUG_ON(mfp >= MFP_PIN_MAX);
+ BUG_ON(mfp < 0 || mfp >= MFP_PIN_MAX);
spin_lock_irqsave(&mfp_spin_lock, flags);
mfpr_writel(mfp_table[mfp].mfpr_off, val);
diff --git a/arch/arm/plat-s3c24xx/adc.c b/arch/arm/plat-s3c24xx/adc.c
index 4d36b784fb8b..df47322492d5 100644
--- a/arch/arm/plat-s3c24xx/adc.c
+++ b/arch/arm/plat-s3c24xx/adc.c
@@ -189,7 +189,7 @@ int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
err:
return ret;
}
-EXPORT_SYMBOL_GPL(s3c_adc_convert);
+EXPORT_SYMBOL_GPL(s3c_adc_read);
static void s3c_adc_default_select(struct s3c_adc_client *client,
unsigned select)
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 5447e60f3936..4af9dd948793 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -61,6 +61,7 @@ static const char name_s3c2410[] = "S3C2410";
static const char name_s3c2412[] = "S3C2412";
static const char name_s3c2440[] = "S3C2440";
static const char name_s3c2442[] = "S3C2442";
+static const char name_s3c2442b[] = "S3C2442B";
static const char name_s3c2443[] = "S3C2443";
static const char name_s3c2410a[] = "S3C2410A";
static const char name_s3c2440a[] = "S3C2440A";
@@ -112,6 +113,15 @@ static struct cpu_table cpu_ids[] __initdata = {
.name = name_s3c2442
},
{
+ .idcode = 0x32440aab,
+ .idmask = 0xffffffff,
+ .map_io = s3c244x_map_io,
+ .init_clocks = s3c244x_init_clocks,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2442_init,
+ .name = name_s3c2442b
+ },
+ {
.idcode = 0x32412001,
.idmask = 0xffffffff,
.map_io = s3c2412_map_io,
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 196b19123653..f046f8c51084 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -208,14 +208,14 @@ s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
{
unsigned long reload;
- pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
- buf, (unsigned long)buf->data, buf->size);
-
if (buf == NULL) {
dmawarn("buffer is NULL\n");
return -EINVAL;
}
+ pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
+ buf, (unsigned long)buf->data, buf->size);
+
/* check the state of the channel before we do anything */
if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
index 95df059b5a1d..5467470badfd 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -29,6 +29,7 @@
#include <linux/io.h>
#include <mach/hardware.h>
+#include <mach/gpio-fns.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
index efeb025affc7..c776120b99e6 100644
--- a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
+++ b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
@@ -222,7 +222,9 @@ extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
/* S3C2410 and compatible exported functions */
extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
+extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
+#ifdef CONFIG_S3C2410_IOTIMING
extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
struct s3c_iotimings *iot);
@@ -231,8 +233,11 @@ extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
struct s3c_iotimings *iot);
-
-extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
+#else
+#define s3c2410_iotiming_calc NULL
+#define s3c2410_iotiming_get NULL
+#define s3c2410_iotiming_set NULL
+#endif /* CONFIG_S3C2410_IOTIMING */
/* S3C2412 compatible routines */
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
index b6deeef8f663..82ab4aad1bbe 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
@@ -27,6 +27,7 @@ extern void s3c2410_init_clocks(int xtal);
#define s3c2410_init_uarts NULL
#define s3c2410_map_io NULL
#define s3c2410_init NULL
+#define s3c2410a_init NULL
#endif
extern int s3c2410_baseclk_add(void);
diff --git a/arch/arm/plat-s3c64xx/dma.c b/arch/arm/plat-s3c64xx/dma.c
index 266a10745a85..d554b936fcfb 100644
--- a/arch/arm/plat-s3c64xx/dma.c
+++ b/arch/arm/plat-s3c64xx/dma.c
@@ -151,8 +151,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
src = chan->dev_addr;
dst = data;
control0 = PL080_CONTROL_SRC_AHB2;
- control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
- control0 |= 2 << PL080_CONTROL_DWIDTH_SHIFT;
control0 |= PL080_CONTROL_DST_INCR;
break;
@@ -160,8 +158,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
src = data;
dst = chan->dev_addr;
control0 = PL080_CONTROL_DST_AHB2;
- control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
- control0 |= 2 << PL080_CONTROL_SWIDTH_SHIFT;
control0 |= PL080_CONTROL_SRC_INCR;
break;
default:
@@ -173,6 +169,8 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
control1 = size >> chan->hw_width; /* size in no of xfers */
control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */
control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */
+ control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
+ control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
lli->src_addr = src;
lli->dst_addr = dst;
@@ -339,6 +337,7 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
struct s3c64xx_dma_buff *next;
struct s3c64xx_dma_buff *buff;
struct pl080s_lli *lli;
+ unsigned long flags;
int ret;
WARN_ON(!chan);
@@ -366,6 +365,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
s3c64xx_dma_fill_lli(chan, lli, data, size);
+ local_irq_save(flags);
+
if ((next = chan->next) != NULL) {
struct s3c64xx_dma_buff *end = chan->end;
struct pl080s_lli *endlli = end->lli;
@@ -397,6 +398,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
s3c64xx_lli_to_regs(chan, lli);
}
+ local_irq_restore(flags);
+
show_lli(lli);
dbg_showchan(chan);
@@ -560,26 +563,11 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
EXPORT_SYMBOL(s3c2410_dma_free);
-
-static void s3c64xx_dma_tcirq(struct s3c64xx_dmac *dmac, int offs)
-{
- struct s3c2410_dma_chan *chan = dmac->channels + offs;
-
- /* note, we currently do not bother to work out which buffer
- * or buffers have been completed since the last tc-irq. */
-
- if (chan->callback_fn)
- (chan->callback_fn)(chan, chan->curr->pw, 0, S3C2410_RES_OK);
-}
-
-static void s3c64xx_dma_errirq(struct s3c64xx_dmac *dmac, int offs)
-{
- printk(KERN_DEBUG "%s: offs %d\n", __func__, offs);
-}
-
static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
{
struct s3c64xx_dmac *dmac = pw;
+ struct s3c2410_dma_chan *chan;
+ enum s3c2410_dma_buffresult res;
u32 tcstat, errstat;
u32 bit;
int offs;
@@ -588,14 +576,54 @@ static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
errstat = readl(dmac->regs + PL080_ERR_STATUS);
for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
+ struct s3c64xx_dma_buff *buff;
+
+ if (!(errstat & bit) && !(tcstat & bit))
+ continue;
+
+ chan = dmac->channels + offs;
+ res = S3C2410_RES_ERR;
+
if (tcstat & bit) {
writel(bit, dmac->regs + PL080_TC_CLEAR);
- s3c64xx_dma_tcirq(dmac, offs);
+ res = S3C2410_RES_OK;
}
- if (errstat & bit) {
- s3c64xx_dma_errirq(dmac, offs);
+ if (errstat & bit)
writel(bit, dmac->regs + PL080_ERR_CLEAR);
+
+ /* 'next' points to the buffer that is next to the
+ * currently active buffer.
+ * For CIRCULAR queues, 'next' will be same as 'curr'
+ * when 'end' is the active buffer.
+ */
+ buff = chan->curr;
+ while (buff && buff != chan->next
+ && buff->next != chan->next)
+ buff = buff->next;
+
+ if (!buff)
+ BUG();
+
+ if (buff == chan->next)
+ buff = chan->end;
+
+ s3c64xx_dma_bufffdone(chan, buff, res);
+
+ /* Free the node and update curr, if non-circular queue */
+ if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
+ chan->curr = buff->next;
+ s3c64xx_dma_freebuff(buff);
+ }
+
+ /* Update 'next' */
+ buff = chan->next;
+ if (chan->next == chan->end) {
+ chan->next = chan->curr;
+ if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
+ chan->end = NULL;
+ } else {
+ chan->next = buff->next;
}
}
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h b/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
index a8777a755dfa..ff46e7fa957a 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
+++ b/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
@@ -51,8 +51,8 @@
#define S3C6400_CLKDIV0_HCLK_SHIFT (8)
#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4)
#define S3C6400_CLKDIV0_MPLL_SHIFT (4)
-#define S3C6400_CLKDIV0_ARM_MASK (0x3 << 0)
-#define S3C6410_CLKDIV0_ARM_MASK (0x7 << 0)
+#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0)
+#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0)
#define S3C6400_CLKDIV0_ARM_SHIFT (0)
/* CLKDIV1 */
diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c
index 9745852261e0..6ffa21eb1b91 100644
--- a/arch/arm/plat-s3c64xx/s3c6400-clock.c
+++ b/arch/arm/plat-s3c64xx/s3c6400-clock.c
@@ -677,6 +677,9 @@ void __init_or_cpufreq s3c6400_setup_clocks(void)
printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+ /* For now assume the mux always selects the crystal */
+ clk_ext_xtal_mux.parent = xtal_clk;
+
epll = s3c6400_get_epll(xtal);
mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 94be7bb6cb9a..07b976da6174 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Fri Sep 18 21:42:00 2009
+# Last update: Wed Nov 25 22:14:58 2009
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -928,7 +928,7 @@ palmt5 MACH_PALMT5 PALMT5 917
palmtc MACH_PALMTC PALMTC 918
omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919
mxc30030evb MACH_MXC30030EVB MXC30030EVB 920
-rea_2d MACH_REA_2D REA_2D 921
+rea_cpu2 MACH_REA_2D REA_2D 921
eti3e524 MACH_TI3E524 TI3E524 922
ateb9200 MACH_ATEB9200 ATEB9200 923
auckland MACH_AUCKLAND AUCKLAND 924
@@ -2421,3 +2421,118 @@ liberty MACH_LIBERTY LIBERTY 2434
mh355 MACH_MH355 MH355 2435
pc7802 MACH_PC7802 PC7802 2436
gnet_sgc MACH_GNET_SGC GNET_SGC 2437
+einstein15 MACH_EINSTEIN15 EINSTEIN15 2438
+cmpd MACH_CMPD CMPD 2439
+davinci_hase1 MACH_DAVINCI_HASE1 DAVINCI_HASE1 2440
+lgeincitephone MACH_LGEINCITEPHONE LGEINCITEPHONE 2441
+ea313x MACH_EA313X EA313X 2442
+fwbd_39064 MACH_FWBD_39064 FWBD_39064 2443
+fwbd_390128 MACH_FWBD_390128 FWBD_390128 2444
+pelco_moe MACH_PELCO_MOE PELCO_MOE 2445
+minimix27 MACH_MINIMIX27 MINIMIX27 2446
+omap3_thunder MACH_OMAP3_THUNDER OMAP3_THUNDER 2447
+passionc MACH_PASSIONC PASSIONC 2448
+mx27amata MACH_MX27AMATA MX27AMATA 2449
+bgat1 MACH_BGAT1 BGAT1 2450
+buzz MACH_BUZZ BUZZ 2451
+mb9g20 MACH_MB9G20 MB9G20 2452
+yushan MACH_YUSHAN YUSHAN 2453
+lizard MACH_LIZARD LIZARD 2454
+omap3polycom MACH_OMAP3POLYCOM OMAP3POLYCOM 2455
+smdkv210 MACH_SMDKV210 SMDKV210 2456
+bravo MACH_BRAVO BRAVO 2457
+siogentoo1 MACH_SIOGENTOO1 SIOGENTOO1 2458
+siogentoo2 MACH_SIOGENTOO2 SIOGENTOO2 2459
+sm3k MACH_SM3K SM3K 2460
+acer_tempo_f900 MACH_ACER_TEMPO_F900 ACER_TEMPO_F900 2461
+sst61vc010_dev MACH_SST61VC010_DEV SST61VC010_DEV 2462
+glittertind MACH_GLITTERTIND GLITTERTIND 2463
+omap_zoom3 MACH_OMAP_ZOOM3 OMAP_ZOOM3 2464
+omap_3630sdp MACH_OMAP_3630SDP OMAP_3630SDP 2465
+cybook2440 MACH_CYBOOK2440 CYBOOK2440 2466
+torino_s MACH_TORINO_S TORINO_S 2467
+havana MACH_HAVANA HAVANA 2468
+beaumont_11 MACH_BEAUMONT_11 BEAUMONT_11 2469
+vanguard MACH_VANGUARD VANGUARD 2470
+s5pc110_draco MACH_S5PC110_DRACO S5PC110_DRACO 2471
+cartesio_two MACH_CARTESIO_TWO CARTESIO_TWO 2472
+aster MACH_ASTER ASTER 2473
+voguesv210 MACH_VOGUESV210 VOGUESV210 2474
+acm500x MACH_ACM500X ACM500X 2475
+km9260 MACH_KM9260 KM9260 2476
+nideflexg1 MACH_NIDEFLEXG1 NIDEFLEXG1 2477
+ctera_plug_io MACH_CTERA_PLUG_IO CTERA_PLUG_IO 2478
+smartq7 MACH_SMARTQ7 SMARTQ7 2479
+at91sam9g10ek2 MACH_AT91SAM9G10EK2 AT91SAM9G10EK2 2480
+asusp527 MACH_ASUSP527 ASUSP527 2481
+at91sam9g20mpm2 MACH_AT91SAM9G20MPM2 AT91SAM9G20MPM2 2482
+topasa900 MACH_TOPASA900 TOPASA900 2483
+electrum_100 MACH_ELECTRUM_100 ELECTRUM_100 2484
+mx51grb MACH_MX51GRB MX51GRB 2485
+xea300 MACH_XEA300 XEA300 2486
+htcstartrek MACH_HTCSTARTREK HTCSTARTREK 2487
+lima MACH_LIMA LIMA 2488
+csb740 MACH_CSB740 CSB740 2489
+usb_s8815 MACH_USB_S8815 USB_S8815 2490
+watson_efm_plugin MACH_WATSON_EFM_PLUGIN WATSON_EFM_PLUGIN 2491
+milkyway MACH_MILKYWAY MILKYWAY 2492
+g4evm MACH_G4EVM G4EVM 2493
+picomod6 MACH_PICOMOD6 PICOMOD6 2494
+omapl138_hawkboard MACH_OMAPL138_HAWKBOARD OMAPL138_HAWKBOARD 2495
+ip6000 MACH_IP6000 IP6000 2496
+ip6010 MACH_IP6010 IP6010 2497
+utm400 MACH_UTM400 UTM400 2498
+omap3_zybex MACH_OMAP3_ZYBEX OMAP3_ZYBEX 2499
+wireless_space MACH_WIRELESS_SPACE WIRELESS_SPACE 2500
+sx560 MACH_SX560 SX560 2501
+ts41x MACH_TS41X TS41X 2502
+elphel10373 MACH_ELPHEL10373 ELPHEL10373 2503
+rhobot MACH_RHOBOT RHOBOT 2504
+mx51_refresh MACH_MX51_REFRESH MX51_REFRESH 2505
+ls9260 MACH_LS9260 LS9260 2506
+shank MACH_SHANK SHANK 2507
+qsd8x50_st1 MACH_QSD8X50_ST1 QSD8X50_ST1 2508
+at91sam9m10ekes MACH_AT91SAM9M10EKES AT91SAM9M10EKES 2509
+hiram MACH_HIRAM HIRAM 2510
+phy3250 MACH_PHY3250 PHY3250 2511
+ea3250 MACH_EA3250 EA3250 2512
+fdi3250 MACH_FDI3250 FDI3250 2513
+whitestone MACH_WHITESTONE WHITESTONE 2514
+at91sam9263nit MACH_AT91SAM9263NIT AT91SAM9263NIT 2515
+ccmx51 MACH_CCMX51 CCMX51 2516
+ccmx51js MACH_CCMX51JS CCMX51JS 2517
+ccwmx51 MACH_CCWMX51 CCWMX51 2518
+ccwmx51js MACH_CCWMX51JS CCWMX51JS 2519
+mini6410 MACH_MINI6410 MINI6410 2520
+tiny6410 MACH_TINY6410 TINY6410 2521
+nano6410 MACH_NANO6410 NANO6410 2522
+at572d940hfnldb MACH_AT572D940HFNLDB AT572D940HFNLDB 2523
+htcleo MACH_HTCLEO HTCLEO 2524
+avp13 MACH_AVP13 AVP13 2525
+xxsvideod MACH_XXSVIDEOD XXSVIDEOD 2526
+vpnext MACH_VPNEXT VPNEXT 2527
+swarco_itc3 MACH_SWARCO_ITC3 SWARCO_ITC3 2528
+tx51 MACH_TX51 TX51 2529
+dolby_cat1021 MACH_DOLBY_CAT1021 DOLBY_CAT1021 2530
+mx28evk MACH_MX28EVK MX28EVK 2531
+phoenix260 MACH_PHOENIX260 PHOENIX260 2532
+uvaca_stork MACH_UVACA_STORK UVACA_STORK 2533
+smartq5 MACH_SMARTQ5 SMARTQ5 2534
+all3078 MACH_ALL3078 ALL3078 2535
+ctera_2bay_ds MACH_CTERA_2BAY_DS CTERA_2BAY_DS 2536
+siogentoo3 MACH_SIOGENTOO3 SIOGENTOO3 2537
+epb5000 MACH_EPB5000 EPB5000 2538
+hy9263 MACH_HY9263 HY9263 2539
+acer_tempo_m900 MACH_ACER_TEMPO_M900 ACER_TEMPO_M900 2540
+acer_tempo_dx650 MACH_ACER_TEMPO_DX900 ACER_TEMPO_DX900 2541
+acer_tempo_x960 MACH_ACER_TEMPO_X960 ACER_TEMPO_X960 2542
+acer_eten_v900 MACH_ACER_ETEN_V900 ACER_ETEN_V900 2543
+acer_eten_x900 MACH_ACER_ETEN_X900 ACER_ETEN_X900 2544
+bonnell MACH_BONNELL BONNELL 2545
+oht_mx27 MACH_OHT_MX27 OHT_MX27 2546
+htcquartz MACH_HTCQUARTZ HTCQUARTZ 2547
+davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548
+c3ax03 MACH_C3AX03 C3AX03 2549
+mxt_td60 MACH_MXT_TD60 MXT_TD60 2550
+esyx MACH_ESYX ESYX 2551
+bulldog MACH_BULLDOG BULLDOG 2553
diff --git a/arch/avr32/include/asm/bug.h b/arch/avr32/include/asm/bug.h
index 331d45bab18f..2aa373cc61b5 100644
--- a/arch/avr32/include/asm/bug.h
+++ b/arch/avr32/include/asm/bug.h
@@ -52,7 +52,7 @@
#define BUG() \
do { \
_BUG_OR_WARN(0); \
- for (;;); \
+ unreachable(); \
} while (0)
#define WARN_ON(condition) \
diff --git a/arch/avr32/mach-at32ap/include/mach/cpu.h b/arch/avr32/mach-at32ap/include/mach/cpu.h
index 44d0bfa1f409..9c96a130f3a8 100644
--- a/arch/avr32/mach-at32ap/include/mach/cpu.h
+++ b/arch/avr32/mach-at32ap/include/mach/cpu.h
@@ -31,5 +31,8 @@
#define cpu_is_at91sam9263() (0)
#define cpu_is_at91sam9rl() (0)
#define cpu_is_at91cap9() (0)
+#define cpu_is_at91sam9g10() (0)
+#define cpu_is_at91sam9g45() (0)
+#define cpu_is_at91sam9g45es() (0)
#endif /* __ASM_ARCH_CPU_H */
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 1f170216d2f9..3946aff4f414 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -225,8 +225,13 @@ int blackfin_dma_suspend(void)
void blackfin_dma_resume(void)
{
int i;
- for (i = 0; i < MAX_DMA_SUSPEND_CHANNELS; ++i)
- dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map;
+
+ for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
+ dma_ch[i].regs->cfg = 0;
+
+ if (i < MAX_DMA_SUSPEND_CHANNELS)
+ dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map;
+ }
}
#endif
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
index f7b9cdce8239..b52c1f8c4bc0 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
@@ -38,7 +38,7 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
#ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE
d_cache = CPLB_L1_CHBL;
-#ifdef CONFIG_BFIN_EXTMEM_WRITETROUGH
+#ifdef CONFIG_BFIN_EXTMEM_WRITETHROUGH
d_cache |= CPLB_L1_AOW | CPLB_WT;
#endif
#endif
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 430ae39456e8..5cc7e2e9e415 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -151,7 +151,7 @@ void start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_
regs->pc = new_ip;
if (current->mm)
regs->p5 = current->mm->start_data;
-#ifdef CONFIG_SMP
+#ifndef CONFIG_SMP
task_thread_info(current)->l1_task_info.stack_start =
(void *)current->mm->context.stack_start;
task_thread_info(current)->l1_task_info.lowest_sp = (void *)new_sp;
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 0982b5d5af10..56b0ba12175f 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -315,7 +315,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case BFIN_MEM_ACCESS_CORE:
case BFIN_MEM_ACCESS_CORE_ONLY:
copied = access_process_vm(child, addr, &data,
- to_copy, 0);
+ to_copy, 1);
if (copied)
break;
diff --git a/arch/blackfin/mach-bf518/include/mach/anomaly.h b/arch/blackfin/mach-bf518/include/mach/anomaly.h
index e9c65390edd1..2829dd0400f1 100644
--- a/arch/blackfin/mach-bf518/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf518/include/mach/anomaly.h
@@ -1,9 +1,13 @@
/*
- * File: include/asm-blackfin/mach-bf518/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
*
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
*/
/* This file should be up to date with:
@@ -70,6 +74,10 @@
#define ANOMALY_05000461 (1)
/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
#define ANOMALY_05000462 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
/* Anomalies that don't exist on this proc */
#define ANOMALY_05000099 (0)
@@ -133,5 +141,7 @@
#define ANOMALY_05000450 (0)
#define ANOMALY_05000465 (0)
#define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
#endif
diff --git a/arch/blackfin/mach-bf527/include/mach/anomaly.h b/arch/blackfin/mach-bf527/include/mach/anomaly.h
index 3f9052687fa8..02040df8ec80 100644
--- a/arch/blackfin/mach-bf527/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf527/include/mach/anomaly.h
@@ -1,14 +1,18 @@
/*
- * File: include/asm-blackfin/mach-bf527/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
*
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
*/
/* This file should be up to date with:
* - Revision D, 08/14/2009; ADSP-BF526 Blackfin Processor Anomaly List
- * - Revision F, 03/03/2009; ADSP-BF527 Blackfin Processor Anomaly List
+ * - Revision G, 08/25/2009; ADSP-BF527 Blackfin Processor Anomaly List
*/
#ifndef _MACH_ANOMALY_H_
@@ -200,6 +204,10 @@
#define ANOMALY_05000467 (1)
/* PLL Latches Incorrect Settings During Reset */
#define ANOMALY_05000469 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
/* Anomalies that don't exist on this proc */
#define ANOMALY_05000099 (0)
@@ -250,5 +258,7 @@
#define ANOMALY_05000412 (0)
#define ANOMALY_05000447 (0)
#define ANOMALY_05000448 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
#endif
diff --git a/arch/blackfin/mach-bf533/include/mach/anomaly.h b/arch/blackfin/mach-bf533/include/mach/anomaly.h
index cd83db2fb1a1..9b3f7a27714d 100644
--- a/arch/blackfin/mach-bf533/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf533/include/mach/anomaly.h
@@ -1,9 +1,13 @@
/*
- * File: include/asm-blackfin/mach-bf533/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
*
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
*/
/* This file should be up to date with:
@@ -202,6 +206,10 @@
#define ANOMALY_05000443 (1)
/* False Hardware Error when RETI Points to Invalid Memory */
#define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
/* These anomalies have been "phased" out of analog.com anomaly sheets and are
* here to show running on older silicon just isn't feasible.
@@ -349,5 +357,7 @@
#define ANOMALY_05000450 (0)
#define ANOMALY_05000465 (0)
#define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
#endif
diff --git a/arch/blackfin/mach-bf537/include/mach/anomaly.h b/arch/blackfin/mach-bf537/include/mach/anomaly.h
index f091ad2d8ea8..d2c427bc6656 100644
--- a/arch/blackfin/mach-bf537/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf537/include/mach/anomaly.h
@@ -1,9 +1,13 @@
/*
- * File: include/asm-blackfin/mach-bf537/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
*
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
*/
/* This file should be up to date with:
@@ -156,6 +160,10 @@
#define ANOMALY_05000443 (1)
/* False Hardware Error when RETI Points to Invalid Memory */
#define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
/* Anomalies that don't exist on this proc */
#define ANOMALY_05000099 (0)
@@ -202,5 +210,7 @@
#define ANOMALY_05000450 (0)
#define ANOMALY_05000465 (0)
#define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
#endif
diff --git a/arch/blackfin/mach-bf538/include/mach/anomaly.h b/arch/blackfin/mach-bf538/include/mach/anomaly.h
index 26b76083e14c..d882b7e6f59b 100644
--- a/arch/blackfin/mach-bf538/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf538/include/mach/anomaly.h
@@ -1,9 +1,13 @@
/*
- * File: include/asm-blackfin/mach-bf538/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
*
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
*/
/* This file should be up to date with:
@@ -128,6 +132,10 @@
#define ANOMALY_05000443 (1)
/* False Hardware Error when RETI Points to Invalid Memory */
#define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
/* Anomalies that don't exist on this proc */
#define ANOMALY_05000099 (0)
@@ -176,5 +184,7 @@
#define ANOMALY_05000450 (0)
#define ANOMALY_05000465 (0)
#define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
#endif
diff --git a/arch/blackfin/mach-bf548/include/mach/anomaly.h b/arch/blackfin/mach-bf548/include/mach/anomaly.h
index 52b116ae522a..7d08c7524498 100644
--- a/arch/blackfin/mach-bf548/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf548/include/mach/anomaly.h
@@ -1,9 +1,13 @@
/*
- * File: include/asm-blackfin/mach-bf548/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
*
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
*/
/* This file should be up to date with:
@@ -24,6 +28,8 @@
#define ANOMALY_05000119 (1)
/* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */
#define ANOMALY_05000122 (1)
+/* Data Corruption with Cached External Memory and Non-Cached On-Chip L2 Memory */
+#define ANOMALY_05000220 (1)
/* False Hardware Error from an Access in the Shadow of a Conditional Branch */
#define ANOMALY_05000245 (1)
/* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */
@@ -200,6 +206,14 @@
#define ANOMALY_05000466 (1)
/* Possible RX data corruption when control & data EP FIFOs are accessed via the core */
#define ANOMALY_05000467 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* Access to DDR-SDRAM causes system hang under certain PLL/VR settings */
+#define ANOMALY_05000474 (1)
+/* Core Hang With L2/L3 Configured in Writeback Cache Mode */
+#define ANOMALY_05000475 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
/* Anomalies that don't exist on this proc */
#define ANOMALY_05000099 (0)
@@ -215,7 +229,6 @@
#define ANOMALY_05000198 (0)
#define ANOMALY_05000202 (0)
#define ANOMALY_05000215 (0)
-#define ANOMALY_05000220 (0)
#define ANOMALY_05000227 (0)
#define ANOMALY_05000230 (0)
#define ANOMALY_05000231 (0)
diff --git a/arch/blackfin/mach-bf561/atomic.S b/arch/blackfin/mach-bf561/atomic.S
index 0261a5e751b3..f99f174b129f 100644
--- a/arch/blackfin/mach-bf561/atomic.S
+++ b/arch/blackfin/mach-bf561/atomic.S
@@ -19,6 +19,16 @@
\reg\().h = _corelock;
.endm
+.macro safe_testset addr:req, scratch:req
+#if ANOMALY_05000477
+ cli \scratch;
+ testset (\addr);
+ sti \scratch;
+#else
+ testset (\addr);
+#endif
+.endm
+
/*
* r0 = address of atomic data to flush and invalidate (32bit).
*
@@ -33,7 +43,7 @@ ENTRY(_get_core_lock)
cli r0;
coreslot_loadaddr p0;
.Lretry_corelock:
- testset (p0);
+ safe_testset p0, r2;
if cc jump .Ldone_corelock;
SSYNC(r2);
jump .Lretry_corelock
@@ -56,7 +66,7 @@ ENTRY(_get_core_lock_noflush)
cli r0;
coreslot_loadaddr p0;
.Lretry_corelock_noflush:
- testset (p0);
+ safe_testset p0, r2;
if cc jump .Ldone_corelock_noflush;
SSYNC(r2);
jump .Lretry_corelock_noflush
diff --git a/arch/blackfin/mach-bf561/include/mach/anomaly.h b/arch/blackfin/mach-bf561/include/mach/anomaly.h
index 70da495c9665..5ddc981e9937 100644
--- a/arch/blackfin/mach-bf561/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf561/include/mach/anomaly.h
@@ -1,9 +1,13 @@
/*
- * File: include/asm-blackfin/mach-bf561/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
*
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
*/
/* This file should be up to date with:
@@ -213,7 +217,11 @@
/* Disabling Peripherals with DMA Running May Cause DMA System Instability */
#define ANOMALY_05000278 (__SILICON_REVISION__ < 5)
/* False Hardware Error Exception when ISR Context Is Not Restored */
-#define ANOMALY_05000281 (__SILICON_REVISION__ < 5)
+/* Temporarily walk around for bug 5423 till this issue is confirmed by
+ * official anomaly document. It looks 05000281 still exists on bf561
+ * v0.5.
+ */
+#define ANOMALY_05000281 (__SILICON_REVISION__ <= 5)
/* System MMR Write Is Stalled Indefinitely when Killed in a Particular Stage */
#define ANOMALY_05000283 (1)
/* Reads Will Receive Incorrect Data under Certain Conditions */
@@ -280,6 +288,12 @@
#define ANOMALY_05000443 (1)
/* False Hardware Error when RETI Points to Invalid Memory */
#define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* Core Hang With L2/L3 Configured in Writeback Cache Mode */
+#define ANOMALY_05000475 (__SILICON_REVISION__ < 4)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
/* Anomalies that don't exist on this proc */
#define ANOMALY_05000119 (0)
@@ -304,5 +318,6 @@
#define ANOMALY_05000450 (0)
#define ANOMALY_05000465 (0)
#define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
#endif
diff --git a/arch/blackfin/mach-common/arch_checks.c b/arch/blackfin/mach-common/arch_checks.c
index 9dbafcdcf479..f2ca211a76a0 100644
--- a/arch/blackfin/mach-common/arch_checks.c
+++ b/arch/blackfin/mach-common/arch_checks.c
@@ -57,3 +57,8 @@
(!defined(CONFIG_BFIN_EXTMEM_DCACHEABLE) && defined(CONFIG_BFIN_L2_WRITEBACK)))
# error You are exposing Anomaly 220 in this config, either config L2 as Write Through, or make External Memory WB.
#endif
+
+#if ANOMALY_05000475 && \
+ (defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK))
+# error "Anomaly 475 does not allow you to use Write Back cache with L2 or External Memory"
+#endif
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index d98585f3237d..d92b168c8328 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -276,10 +276,9 @@ void smp_send_reschedule(int cpu)
if (cpu_is_offline(cpu))
return;
- msg = kmalloc(sizeof(*msg), GFP_ATOMIC);
+ msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
if (!msg)
return;
- memset(msg, 0, sizeof(msg));
INIT_LIST_HEAD(&msg->list);
msg->type = BFIN_IPI_RESCHEDULE;
@@ -305,10 +304,9 @@ void smp_send_stop(void)
if (cpus_empty(callmap))
return;
- msg = kmalloc(sizeof(*msg), GFP_ATOMIC);
+ msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
if (!msg)
return;
- memset(msg, 0, sizeof(msg));
INIT_LIST_HEAD(&msg->list);
msg->type = BFIN_IPI_CPU_STOP;
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 6b0a2b6fed6a..0974c0ecc594 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -527,7 +527,7 @@ static void do_signal(void)
no_signal:
/* Did we come from a system call? */
- if (__frame->syscallno >= 0) {
+ if (__frame->syscallno != -1) {
/* Restart the system call - no handlers present */
switch (__frame->gr8) {
case -ERESTARTNOHAND:
diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h
index 30bb930e1111..239ecdc9516d 100644
--- a/arch/ia64/include/asm/spinlock.h
+++ b/arch/ia64/include/asm/spinlock.h
@@ -25,61 +25,82 @@
* by atomically noting the tail and incrementing it by one (thus adding
* ourself to the queue and noting our position), then waiting until the head
* becomes equal to the the initial value of the tail.
+ * The pad bits in the middle are used to prevent the next_ticket number
+ * overflowing into the now_serving number.
*
- * 63 32 31 0
+ * 31 17 16 15 14 0
* +----------------------------------------------------+
- * | next_ticket_number | now_serving |
+ * | now_serving | padding | next_ticket |
* +----------------------------------------------------+
*/
-#define TICKET_SHIFT 32
+#define TICKET_SHIFT 17
+#define TICKET_BITS 15
+#define TICKET_MASK ((1 << TICKET_BITS) - 1)
static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
{
- int *p = (int *)&lock->lock, turn, now_serving;
+ int *p = (int *)&lock->lock, ticket, serve;
- now_serving = *p;
- turn = ia64_fetchadd(1, p+1, acq);
+ ticket = ia64_fetchadd(1, p, acq);
- if (turn == now_serving)
+ if (!(((ticket >> TICKET_SHIFT) ^ ticket) & TICKET_MASK))
return;
- do {
+ ia64_invala();
+
+ for (;;) {
+ asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(p) : "memory");
+
+ if (!(((serve >> TICKET_SHIFT) ^ ticket) & TICKET_MASK))
+ return;
cpu_relax();
- } while (ACCESS_ONCE(*p) != turn);
+ }
}
static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
{
- long tmp = ACCESS_ONCE(lock->lock), try;
-
- if (!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1L << TICKET_SHIFT) - 1))) {
- try = tmp + (1L << TICKET_SHIFT);
+ int tmp = ACCESS_ONCE(lock->lock);
- return ia64_cmpxchg(acq, &lock->lock, tmp, try, sizeof (tmp)) == tmp;
- }
+ if (!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK))
+ return ia64_cmpxchg(acq, &lock->lock, tmp, tmp + 1, sizeof (tmp)) == tmp;
return 0;
}
static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
{
- int *p = (int *)&lock->lock;
+ unsigned short *p = (unsigned short *)&lock->lock + 1, tmp;
- (void)ia64_fetchadd(1, p, rel);
+ asm volatile ("ld2.bias %0=[%1]" : "=r"(tmp) : "r"(p));
+ ACCESS_ONCE(*p) = (tmp + 2) & ~1;
+}
+
+static __always_inline void __ticket_spin_unlock_wait(raw_spinlock_t *lock)
+{
+ int *p = (int *)&lock->lock, ticket;
+
+ ia64_invala();
+
+ for (;;) {
+ asm volatile ("ld4.c.nc %0=[%1]" : "=r"(ticket) : "r"(p) : "memory");
+ if (!(((ticket >> TICKET_SHIFT) ^ ticket) & TICKET_MASK))
+ return;
+ cpu_relax();
+ }
}
static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
{
long tmp = ACCESS_ONCE(lock->lock);
- return !!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1L << TICKET_SHIFT) - 1));
+ return !!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK);
}
static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
{
long tmp = ACCESS_ONCE(lock->lock);
- return (((tmp >> TICKET_SHIFT) - tmp) & ((1L << TICKET_SHIFT) - 1)) > 1;
+ return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1;
}
static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
@@ -116,8 +137,7 @@ static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock,
static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
{
- while (__raw_spin_is_locked(lock))
- cpu_relax();
+ __ticket_spin_unlock_wait(lock);
}
#define __raw_read_can_lock(rw) (*(volatile int *)(rw) >= 0)
diff --git a/arch/ia64/include/asm/spinlock_types.h b/arch/ia64/include/asm/spinlock_types.h
index b61d136d9bc2..474e46f1ab4a 100644
--- a/arch/ia64/include/asm/spinlock_types.h
+++ b/arch/ia64/include/asm/spinlock_types.h
@@ -6,7 +6,7 @@
#endif
typedef struct {
- volatile unsigned long lock;
+ volatile unsigned int lock;
} raw_spinlock_t;
#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
diff --git a/arch/ia64/include/asm/swiotlb.h b/arch/ia64/include/asm/swiotlb.h
index dcbaea7ce128..f0acde68aaea 100644
--- a/arch/ia64/include/asm/swiotlb.h
+++ b/arch/ia64/include/asm/swiotlb.h
@@ -4,8 +4,6 @@
#include <linux/dma-mapping.h>
#include <linux/swiotlb.h>
-extern int swiotlb_force;
-
#ifdef CONFIG_SWIOTLB
extern int swiotlb;
extern void pci_swiotlb_init(void);
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index d2877a7bfe2e..496ac7a99488 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -887,6 +887,60 @@ ia64_mca_modify_comm(const struct task_struct *previous_current)
memcpy(current->comm, comm, sizeof(current->comm));
}
+static void
+finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms,
+ unsigned long *nat)
+{
+ const u64 *bank;
+
+ /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use
+ * pmsa_{xip,xpsr,xfs}
+ */
+ if (ia64_psr(regs)->ic) {
+ regs->cr_iip = ms->pmsa_iip;
+ regs->cr_ipsr = ms->pmsa_ipsr;
+ regs->cr_ifs = ms->pmsa_ifs;
+ } else {
+ regs->cr_iip = ms->pmsa_xip;
+ regs->cr_ipsr = ms->pmsa_xpsr;
+ regs->cr_ifs = ms->pmsa_xfs;
+ }
+ regs->pr = ms->pmsa_pr;
+ regs->b0 = ms->pmsa_br0;
+ regs->ar_rsc = ms->pmsa_rsc;
+ copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, &regs->r1, nat);
+ copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, &regs->r2, nat);
+ copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, &regs->r3, nat);
+ copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, &regs->r8, nat);
+ copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, &regs->r9, nat);
+ copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, &regs->r10, nat);
+ copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, &regs->r11, nat);
+ copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, &regs->r12, nat);
+ copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, &regs->r13, nat);
+ copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, &regs->r14, nat);
+ copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, &regs->r15, nat);
+ if (ia64_psr(regs)->bn)
+ bank = ms->pmsa_bank1_gr;
+ else
+ bank = ms->pmsa_bank0_gr;
+ copy_reg(&bank[16-16], ms->pmsa_nat_bits, &regs->r16, nat);
+ copy_reg(&bank[17-16], ms->pmsa_nat_bits, &regs->r17, nat);
+ copy_reg(&bank[18-16], ms->pmsa_nat_bits, &regs->r18, nat);
+ copy_reg(&bank[19-16], ms->pmsa_nat_bits, &regs->r19, nat);
+ copy_reg(&bank[20-16], ms->pmsa_nat_bits, &regs->r20, nat);
+ copy_reg(&bank[21-16], ms->pmsa_nat_bits, &regs->r21, nat);
+ copy_reg(&bank[22-16], ms->pmsa_nat_bits, &regs->r22, nat);
+ copy_reg(&bank[23-16], ms->pmsa_nat_bits, &regs->r23, nat);
+ copy_reg(&bank[24-16], ms->pmsa_nat_bits, &regs->r24, nat);
+ copy_reg(&bank[25-16], ms->pmsa_nat_bits, &regs->r25, nat);
+ copy_reg(&bank[26-16], ms->pmsa_nat_bits, &regs->r26, nat);
+ copy_reg(&bank[27-16], ms->pmsa_nat_bits, &regs->r27, nat);
+ copy_reg(&bank[28-16], ms->pmsa_nat_bits, &regs->r28, nat);
+ copy_reg(&bank[29-16], ms->pmsa_nat_bits, &regs->r29, nat);
+ copy_reg(&bank[30-16], ms->pmsa_nat_bits, &regs->r30, nat);
+ copy_reg(&bank[31-16], ms->pmsa_nat_bits, &regs->r31, nat);
+}
+
/* On entry to this routine, we are running on the per cpu stack, see
* mca_asm.h. The original stack has not been touched by this event. Some of
* the original stack's registers will be in the RBS on this stack. This stack
@@ -921,7 +975,6 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
u64 r12 = ms->pmsa_gr[12-1], r13 = ms->pmsa_gr[13-1];
u64 ar_bspstore = regs->ar_bspstore;
u64 ar_bsp = regs->ar_bspstore + (loadrs >> 16);
- const u64 *bank;
const char *msg;
int cpu = smp_processor_id();
@@ -1024,54 +1077,9 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
p = (char *)r12 - sizeof(*regs);
old_regs = (struct pt_regs *)p;
memcpy(old_regs, regs, sizeof(*regs));
- /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use
- * pmsa_{xip,xpsr,xfs}
- */
- if (ia64_psr(regs)->ic) {
- old_regs->cr_iip = ms->pmsa_iip;
- old_regs->cr_ipsr = ms->pmsa_ipsr;
- old_regs->cr_ifs = ms->pmsa_ifs;
- } else {
- old_regs->cr_iip = ms->pmsa_xip;
- old_regs->cr_ipsr = ms->pmsa_xpsr;
- old_regs->cr_ifs = ms->pmsa_xfs;
- }
- old_regs->pr = ms->pmsa_pr;
- old_regs->b0 = ms->pmsa_br0;
old_regs->loadrs = loadrs;
- old_regs->ar_rsc = ms->pmsa_rsc;
old_unat = old_regs->ar_unat;
- copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, &old_regs->r1, &old_unat);
- copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, &old_regs->r2, &old_unat);
- copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, &old_regs->r3, &old_unat);
- copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, &old_regs->r8, &old_unat);
- copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, &old_regs->r9, &old_unat);
- copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, &old_regs->r10, &old_unat);
- copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, &old_regs->r11, &old_unat);
- copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, &old_regs->r12, &old_unat);
- copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, &old_regs->r13, &old_unat);
- copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, &old_regs->r14, &old_unat);
- copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, &old_regs->r15, &old_unat);
- if (ia64_psr(old_regs)->bn)
- bank = ms->pmsa_bank1_gr;
- else
- bank = ms->pmsa_bank0_gr;
- copy_reg(&bank[16-16], ms->pmsa_nat_bits, &old_regs->r16, &old_unat);
- copy_reg(&bank[17-16], ms->pmsa_nat_bits, &old_regs->r17, &old_unat);
- copy_reg(&bank[18-16], ms->pmsa_nat_bits, &old_regs->r18, &old_unat);
- copy_reg(&bank[19-16], ms->pmsa_nat_bits, &old_regs->r19, &old_unat);
- copy_reg(&bank[20-16], ms->pmsa_nat_bits, &old_regs->r20, &old_unat);
- copy_reg(&bank[21-16], ms->pmsa_nat_bits, &old_regs->r21, &old_unat);
- copy_reg(&bank[22-16], ms->pmsa_nat_bits, &old_regs->r22, &old_unat);
- copy_reg(&bank[23-16], ms->pmsa_nat_bits, &old_regs->r23, &old_unat);
- copy_reg(&bank[24-16], ms->pmsa_nat_bits, &old_regs->r24, &old_unat);
- copy_reg(&bank[25-16], ms->pmsa_nat_bits, &old_regs->r25, &old_unat);
- copy_reg(&bank[26-16], ms->pmsa_nat_bits, &old_regs->r26, &old_unat);
- copy_reg(&bank[27-16], ms->pmsa_nat_bits, &old_regs->r27, &old_unat);
- copy_reg(&bank[28-16], ms->pmsa_nat_bits, &old_regs->r28, &old_unat);
- copy_reg(&bank[29-16], ms->pmsa_nat_bits, &old_regs->r29, &old_unat);
- copy_reg(&bank[30-16], ms->pmsa_nat_bits, &old_regs->r30, &old_unat);
- copy_reg(&bank[31-16], ms->pmsa_nat_bits, &old_regs->r31, &old_unat);
+ finish_pt_regs(old_regs, ms, &old_unat);
/* Next stack a struct switch_stack. mca_asm.S built a partial
* switch_stack, copy it and fill in the blanks using pt_regs and
@@ -1141,6 +1149,8 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
no_mod:
mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n",
smp_processor_id(), type, msg);
+ old_unat = regs->ar_unat;
+ finish_pt_regs(regs, ms, &old_unat);
return previous_current;
}
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index 285aae8431c6..53292abf846c 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -41,7 +41,7 @@ struct dma_map_ops swiotlb_dma_ops = {
void __init swiotlb_dma_init(void)
{
dma_ops = &swiotlb_dma_ops;
- swiotlb_init();
+ swiotlb_init(1);
}
void __init pci_swiotlb_init(void)
@@ -51,7 +51,7 @@ void __init pci_swiotlb_init(void)
swiotlb = 1;
printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
machvec_init("dig");
- swiotlb_init();
+ swiotlb_init(1);
dma_ops = &swiotlb_dma_ops;
#else
panic("Unable to find Intel IOMMU");
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 6db08599ebbc..776dd40397e2 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -60,7 +60,6 @@ dump (const char *str, void *vp, size_t len)
*/
int no_unaligned_warning;
int unaligned_dump_stack;
-static int noprint_warning;
/*
* For M-unit:
@@ -1357,9 +1356,8 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
/* watch for command names containing %s */
printk(KERN_WARNING "%s", buf);
} else {
- if (no_unaligned_warning && !noprint_warning) {
- noprint_warning = 1;
- printk(KERN_WARNING "%s(%d) encountered an "
+ if (no_unaligned_warning) {
+ printk_once(KERN_WARNING "%s(%d) encountered an "
"unaligned exception which required\n"
"kernel assistance, which degrades "
"the performance of the application.\n"
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index f426dc78d959..ee09d261f2e6 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -100,24 +100,36 @@ wrap_mmu_context (struct mm_struct *mm)
* this primitive it can be moved up to a spinaphore.h header.
*/
struct spinaphore {
- atomic_t cur;
+ unsigned long ticket;
+ unsigned long serve;
};
static inline void spinaphore_init(struct spinaphore *ss, int val)
{
- atomic_set(&ss->cur, val);
+ ss->ticket = 0;
+ ss->serve = val;
}
static inline void down_spin(struct spinaphore *ss)
{
- while (unlikely(!atomic_add_unless(&ss->cur, -1, 0)))
- while (atomic_read(&ss->cur) == 0)
- cpu_relax();
+ unsigned long t = ia64_fetchadd(1, &ss->ticket, acq), serve;
+
+ if (time_before(t, ss->serve))
+ return;
+
+ ia64_invala();
+
+ for (;;) {
+ asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
+ if (time_before(t, serve))
+ return;
+ cpu_relax();
+ }
}
static inline void up_spin(struct spinaphore *ss)
{
- atomic_add(1, &ss->cur);
+ ia64_fetchadd(1, &ss->serve, rel);
}
static struct spinaphore ptcg_sem;
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 7de76dd352fe..c0fca2c1c858 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -56,10 +56,13 @@ int raw_pci_read(unsigned int seg, unsigned int bus, unsigned int devfn,
if ((seg | reg) <= 255) {
addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg);
mode = 0;
- } else {
+ } else if (sal_revision >= SAL_VERSION_CODE(3,2)) {
addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg);
mode = 1;
+ } else {
+ return -EINVAL;
}
+
result = ia64_sal_pci_config_read(addr, mode, len, &data);
if (result != 0)
return -EINVAL;
@@ -80,9 +83,11 @@ int raw_pci_write(unsigned int seg, unsigned int bus, unsigned int devfn,
if ((seg | reg) <= 255) {
addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg);
mode = 0;
- } else {
+ } else if (sal_revision >= SAL_VERSION_CODE(3,2)) {
addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg);
mode = 1;
+ } else {
+ return -EINVAL;
}
result = ia64_sal_pci_config_write(addr, mode, len, value);
if (result != 0)
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
index 25831c47c579..308e6595110e 100644
--- a/arch/ia64/sn/kernel/io_common.c
+++ b/arch/ia64/sn/kernel/io_common.c
@@ -119,7 +119,6 @@ sn_pcidev_info_get(struct pci_dev *dev)
* Additionally note that the struct sn_flush_device_war also has to be
* removed from arch/ia64/sn/include/xtalk/hubdev.h
*/
-static u8 war_implemented = 0;
static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
struct sn_flush_device_common *common)
@@ -128,11 +127,8 @@ static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
struct sn_flush_device_war *dev_entry;
struct ia64_sal_retval isrv = {0,0,0,0};
- if (!war_implemented) {
- printk(KERN_WARNING "PROM version < 4.50 -- implementing old "
- "PROM flush WAR\n");
- war_implemented = 1;
- }
+ printk_once(KERN_WARNING
+ "PROM version < 4.50 -- implementing old PROM flush WAR\n");
war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
BUG_ON(!war_list);
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 4c7e74790958..55ac3c4e11d2 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -786,17 +786,18 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg)
break;
case SN_HWPERF_GET_OBJ_NODE:
- if (a.sz != sizeof(u64) || a.arg < 0) {
+ i = a.arg;
+ if (a.sz != sizeof(u64) || i < 0) {
r = -EINVAL;
goto error;
}
if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
- if (a.arg >= nobj) {
+ if (i >= nobj) {
r = -EINVAL;
vfree(objs);
goto error;
}
- if (objs[(i = a.arg)].id != a.arg) {
+ if (objs[i].id != a.arg) {
for (i = 0; i < nobj; i++) {
if (objs[i].id == a.arg)
break;
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index c41234f1b825..3a9319f93e89 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -11,6 +11,9 @@ config M32R
select HAVE_IDE
select HAVE_OPROFILE
select INIT_ALL_POSSIBLE
+ select HAVE_KERNEL_GZIP
+ select HAVE_KERNEL_BZIP2
+ select HAVE_KERNEL_LZMA
config SBUS
bool
diff --git a/arch/m32r/boot/compressed/Makefile b/arch/m32r/boot/compressed/Makefile
index 560484ae35ec..177716b1d613 100644
--- a/arch/m32r/boot/compressed/Makefile
+++ b/arch/m32r/boot/compressed/Makefile
@@ -1,11 +1,11 @@
#
-# linux/arch/sh/boot/compressed/Makefile
+# linux/arch/m32r/boot/compressed/Makefile
#
# create a compressed vmlinux image from the original vmlinux
#
-targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o \
- piggy.o vmlinux.lds
+targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
+ vmlinux.bin.lzma head.o misc.o piggy.o vmlinux.lds
OBJECTS = $(obj)/head.o $(obj)/misc.o
@@ -27,6 +27,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,bzip2)
+
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,lzma)
+
CFLAGS_misc.o += -fpic
ifdef CONFIG_MMU
@@ -37,5 +43,9 @@ endif
OBJCOPYFLAGS += -R .empty_zero_page
-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+suffix_$(CONFIG_KERNEL_GZIP) = gz
+suffix_$(CONFIG_KERNEL_BZIP2) = bz2
+suffix_$(CONFIG_KERNEL_LZMA) = lzma
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
$(call if_changed,ld)
diff --git a/arch/m32r/boot/compressed/misc.c b/arch/m32r/boot/compressed/misc.c
index d394292498c0..370d60881977 100644
--- a/arch/m32r/boot/compressed/misc.c
+++ b/arch/m32r/boot/compressed/misc.c
@@ -9,140 +9,49 @@
* Adapted for SH by Stuart Menefy, Aug 1999
*
* 2003-02-12: Support M32R by Takeo Takahashi
- * This is based on arch/sh/boot/compressed/misc.c.
*/
-#include <linux/string.h>
-
/*
* gzip declarations
*/
-
-#define OF(args) args
#define STATIC static
#undef memset
#undef memcpy
#define memzero(s, n) memset ((s), 0, (n))
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch *inbuf; /* input buffer */
-static uch window[WSIZE]; /* Sliding window buffer */
-
-static unsigned insize = 0; /* valid bytes in inbuf */
-static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
-static unsigned outcnt = 0; /* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
-#define RESERVED 0xC0 /* bit 6,7: reserved */
-
-#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# define Assert(cond,msg) {if(!(cond)) error(msg);}
-# define Trace(x) fprintf x
-# define Tracev(x) {if (verbose) fprintf x ;}
-# define Tracevv(x) {if (verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-static int fill_inbuf(void);
-static void flush_window(void);
static void error(char *m);
-static unsigned char *input_data;
-static int input_len;
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-
#include "m32r_sio.c"
static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr;
-#define HEAP_SIZE 0x10000
-
-#include "../../../../lib/inflate.c"
-
-void* memset(void* s, int c, size_t n)
+#ifdef CONFIG_KERNEL_BZIP2
+static void *memset(void *s, int c, size_t n)
{
- int i;
- char *ss = (char*)s;
+ char *ss = s;
- for (i=0;i<n;i++) ss[i] = c;
+ while (n--)
+ *ss++ = c;
return s;
}
+#endif
-void* memcpy(void* __dest, __const void* __src,
- size_t __n)
-{
- int i;
- char *d = (char *)__dest, *s = (char *)__src;
-
- for (i=0;i<__n;i++) d[i] = s[i];
- return __dest;
-}
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
- if (insize != 0) {
- error("ran out of input data");
- }
-
- inbuf = input_data;
- insize = input_len;
- inptr = 1;
- return inbuf[0];
-}
+#ifdef CONFIG_KERNEL_GZIP
+#define BOOT_HEAP_SIZE 0x10000
+#include "../../../../lib/decompress_inflate.c"
+#endif
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
- ulg c = crc; /* temporary variable */
- unsigned n;
- uch *in, *out, ch;
+#ifdef CONFIG_KERNEL_BZIP2
+#define BOOT_HEAP_SIZE 0x400000
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++) {
- ch = *out++ = *in++;
- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
- }
- crc = c;
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
-}
+#ifdef CONFIG_KERNEL_LZMA
+#define BOOT_HEAP_SIZE 0x10000
+#include "../../../../lib/decompress_unlzma.c"
+#endif
static void error(char *x)
{
@@ -153,20 +62,20 @@ static void error(char *x)
while(1); /* Halt */
}
-/* return decompressed size */
void
decompress_kernel(int mmu_on, unsigned char *zimage_data,
unsigned int zimage_len, unsigned long heap)
{
+ unsigned char *input_data = zimage_data;
+ int input_len = zimage_len;
+ unsigned char *output_data;
+
output_data = (unsigned char *)CONFIG_MEMORY_START + 0x2000
+ (mmu_on ? 0x80000000 : 0);
free_mem_ptr = heap;
- free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
- input_data = zimage_data;
- input_len = zimage_len;
+ free_mem_end_ptr = free_mem_ptr + BOOT_HEAP_SIZE;
- makecrc();
- puts("Uncompressing Linux... ");
- gunzip();
- puts("Ok, booting the kernel.\n");
+ puts("\nDecompressing Linux... ");
+ decompress(input_data, input_len, NULL, NULL, output_data, NULL, error);
+ puts("done.\nBooting the kernel.\n");
}
diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c
index 8a88f1f0a3e2..31cef20b2996 100644
--- a/arch/m32r/kernel/smp.c
+++ b/arch/m32r/kernel/smp.c
@@ -806,7 +806,7 @@ unsigned long send_IPI_mask_phys(cpumask_t physid_mask, int ipi_num,
if (mask & ~physids_coerce(phys_cpu_present_map))
BUG();
- if (ipi_num >= NR_IPIS)
+ if (ipi_num >= NR_IPIS || ipi_num < 0)
BUG();
mask <<= IPI_SHIFT;
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index e7fee0f198d5..9cedcef11575 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -75,7 +75,7 @@ u32 arch_gettimeoffset(void)
count = 0;
count = (latch - count) * TICK_SIZE;
- elapsed_time = (count + latch / 2) / latch;
+ elapsed_time = DIV_ROUND_CLOSEST(count, latch);
/* NOTE: LATCH is equal to the "interval" value (= reload count). */
#else /* CONFIG_SMP */
@@ -93,7 +93,7 @@ u32 arch_gettimeoffset(void)
p_count = count;
count = (latch - count) * TICK_SIZE;
- elapsed_time = (count + latch / 2) / latch;
+ elapsed_time = DIV_ROUND_CLOSEST(count, latch);
/* NOTE: LATCH is equal to the "interval" value (= reload count). */
#endif /* CONFIG_SMP */
#elif defined(CONFIG_CHIP_M32310)
@@ -211,7 +211,7 @@ void __init time_init(void)
bus_clock = boot_cpu_data.bus_clock;
divide = boot_cpu_data.timer_divide;
- latch = (bus_clock/divide + HZ / 2) / HZ;
+ latch = DIV_ROUND_CLOSEST(bus_clock/divide, HZ);
printk("Timer start : latch = %ld\n", latch);
diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S
index 8ceb6181d805..7da94eaa082b 100644
--- a/arch/m32r/kernel/vmlinux.lds.S
+++ b/arch/m32r/kernel/vmlinux.lds.S
@@ -42,6 +42,8 @@ SECTIONS
_etext = .; /* End of text section */
EXCEPTION_TABLE(16)
+ NOTES
+
RODATA
RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
_edata = .; /* End of data section */
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 29dd8489ffec..ecdc19a299b2 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -561,7 +561,7 @@ config HPAPCI
config MVME147_SCC
bool "SCC support for MVME147 serial ports"
- depends on MVME147
+ depends on MVME147 && BROKEN
help
This is the driver for the serial ports on the Motorola MVME147
boards. Everyone using one of these boards should say Y here.
@@ -576,14 +576,14 @@ config SERIAL167
config MVME162_SCC
bool "SCC support for MVME162 serial ports"
- depends on MVME16x
+ depends on MVME16x && BROKEN
help
This is the driver for the serial ports on the Motorola MVME162 and
172 boards. Everyone using one of these boards should say Y here.
config BVME6000_SCC
bool "SCC support for BVME6000 serial ports"
- depends on BVME6000
+ depends on BVME6000 && BROKEN
help
This is the driver for the serial ports on the BVME4000 and BVME6000
boards from BVM Ltd. Everyone using one of these boards should say
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 705a7a9170f3..fd7620f025fa 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1,6 +1,7 @@
config MIPS
bool
default y
+ select HAVE_GENERIC_DMA_COHERENT
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_ARCH_KGDB
@@ -357,7 +358,14 @@ config SGI_IP22
select SWAP_IO_SPACE
select SYS_HAS_CPU_R4X00
select SYS_HAS_CPU_R5000
- select SYS_HAS_EARLY_PRINTK
+ #
+ # Disable EARLY_PRINTK for now since it leads to overwritten prom
+ # memory during early boot on some machines.
+ #
+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+ # for a more details discussion
+ #
+ # select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
@@ -409,7 +417,14 @@ config SGI_IP28
select SGI_HAS_ZILOG
select SWAP_IO_SPACE
select SYS_HAS_CPU_R10000
- select SYS_HAS_EARLY_PRINTK
+ #
+ # Disable EARLY_PRINTK for now since it leads to overwritten prom
+ # memory during early boot on some machines.
+ #
+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+ # for a more details discussion
+ #
+ # select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
help
@@ -1012,9 +1027,9 @@ config BOOT_ELF32
config MIPS_L1_CACHE_SHIFT
int
- default "4" if MACH_DECSTATION || MIKROTIK_RB532
+ default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL
+ default "6" if MIPS_CPU_SCACHE
default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON
- default "4" if PMC_MSP4200_EVAL
default "5"
config HAVE_STD_PC_SERIAL_PORT
@@ -1438,6 +1453,7 @@ choice
config PAGE_SIZE_4KB
bool "4kB"
+ depends on !CPU_LOONGSON2
help
This option select the standard 4kB Linux page size. On some
R3000-family processors this is the only available page size. Using
@@ -1762,7 +1778,7 @@ config SYS_SUPPORTS_SMARTMIPS
config ARCH_FLATMEM_ENABLE
def_bool y
- depends on !NUMA
+ depends on !NUMA && !CPU_LOONGSON2
config ARCH_DISCONTIGMEM_ENABLE
bool
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index c88c821b4c36..d670928afcfd 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -354,6 +354,28 @@ static void au1x_ic1_ack(unsigned int irq_nr)
au_sync();
}
+static void au1x_ic0_maskack(unsigned int irq_nr)
+{
+ unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+
+ au_writel(1 << bit, IC0_WAKECLR);
+ au_writel(1 << bit, IC0_MASKCLR);
+ au_writel(1 << bit, IC0_RISINGCLR);
+ au_writel(1 << bit, IC0_FALLINGCLR);
+ au_sync();
+}
+
+static void au1x_ic1_maskack(unsigned int irq_nr)
+{
+ unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+
+ au_writel(1 << bit, IC1_WAKECLR);
+ au_writel(1 << bit, IC1_MASKCLR);
+ au_writel(1 << bit, IC1_RISINGCLR);
+ au_writel(1 << bit, IC1_FALLINGCLR);
+ au_sync();
+}
+
static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
{
unsigned int bit = irq - AU1000_INTC1_INT_BASE;
@@ -379,25 +401,21 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
/*
* irq_chips for both ICs; this way the mask handlers can be
* as short as possible.
- *
- * NOTE: the ->ack() callback is used by the handle_edge_irq
- * flowhandler only, the ->mask_ack() one by handle_level_irq,
- * so no need for an irq_chip for each type of irq (level/edge).
*/
static struct irq_chip au1x_ic0_chip = {
.name = "Alchemy-IC0",
- .ack = au1x_ic0_ack, /* edge */
+ .ack = au1x_ic0_ack,
.mask = au1x_ic0_mask,
- .mask_ack = au1x_ic0_mask, /* level */
+ .mask_ack = au1x_ic0_maskack,
.unmask = au1x_ic0_unmask,
.set_type = au1x_ic_settype,
};
static struct irq_chip au1x_ic1_chip = {
.name = "Alchemy-IC1",
- .ack = au1x_ic1_ack, /* edge */
+ .ack = au1x_ic1_ack,
.mask = au1x_ic1_mask,
- .mask_ack = au1x_ic1_mask, /* level */
+ .mask_ack = au1x_ic1_maskack,
.unmask = au1x_ic1_unmask,
.set_type = au1x_ic_settype,
.set_wake = au1x_ic1_setwake,
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c
index cc32c69a74ad..45b61c9b82b9 100644
--- a/arch/mips/alchemy/mtx-1/board_setup.c
+++ b/arch/mips/alchemy/mtx-1/board_setup.c
@@ -69,6 +69,7 @@ void __init board_setup(void)
#else
au_writel(0xf, Au1500_PCI_CFG);
#endif
+ board_pci_idsel = mtx1_pci_idsel;
#endif
/* Initialize sys_pinfunc */
@@ -85,8 +86,6 @@ void __init board_setup(void)
alchemy_gpio_direction_output(211, 1); /* green on */
alchemy_gpio_direction_output(212, 0); /* red off */
- board_pci_idsel = mtx1_pci_idsel;
-
printk(KERN_INFO "4G Systems MTX-1 Board\n");
}
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index e2278c04459d..835f3f0319ca 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -503,6 +503,7 @@ static int __init ar7_register_devices(void)
{
u16 chip_id;
int res;
+ u32 *bootcr, val;
#ifdef CONFIG_SERIAL_8250
static struct uart_port uart_port[2];
@@ -595,7 +596,13 @@ static int __init ar7_register_devices(void)
ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
- res = platform_device_register(&ar7_wdt);
+ bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4);
+ val = *bootcr;
+ iounmap(bootcr);
+
+ /* Register watchdog only if enabled in hardware */
+ if (val & AR7_WDT_HW_ENA)
+ res = platform_device_register(&ar7_wdt);
return res;
}
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
index 079e33d52783..fb284c3b2cff 100644
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -100,7 +100,7 @@ static __init void prom_init_console(void)
static __init void prom_init_cmdline(void)
{
- char buf[CL_SIZE];
+ static char buf[CL_SIZE] __initdata;
/* Get the kernel command line from CFE */
if (cfe_getenv("LINUX_CMDLINE", buf, CL_SIZE) >= 0) {
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index c146d1ededed..00064b660809 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,5 +1,5 @@
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
- dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o
+ dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 78e155d21be6..05a35cf5963d 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -24,7 +24,6 @@
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
#include <bcm63xx_dev_pcmcia.h>
-#include <bcm63xx_dev_uart.h>
#include <board_bcm963xx.h>
#define PFX "board_bcm963xx: "
@@ -794,8 +793,6 @@ int __init board_register_devices(void)
{
u32 val;
- bcm63xx_uart_register();
-
if (board.has_pccard)
bcm63xx_pcmcia_register();
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index 6dc43f0483e8..70378bb5e3f9 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpu.h>
+#include <asm/cpu-info.h>
#include <bcm63xx_cpu.h>
#include <bcm63xx_regs.h>
#include <bcm63xx_io.h>
@@ -284,6 +285,7 @@ void __init bcm63xx_cpu_init(void)
{
unsigned int tmp, expected_cpu_id;
struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int cpu = smp_processor_id();
/* soc registers location depends on cpu type */
expected_cpu_id = 0;
@@ -293,6 +295,7 @@ void __init bcm63xx_cpu_init(void)
* BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c
*/
case CPU_BCM3302:
+ __cpu_name[cpu] = "Broadcom BCM6338";
expected_cpu_id = BCM6338_CPU_ID;
bcm63xx_regs_base = bcm96338_regs_base;
bcm63xx_irqs = bcm96338_irqs;
diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c
index 5f3d89c4a988..b0519461ad9b 100644
--- a/arch/mips/bcm63xx/dev-uart.c
+++ b/arch/mips/bcm63xx/dev-uart.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <bcm63xx_cpu.h>
-#include <bcm63xx_dev_uart.h>
static struct resource uart_resources[] = {
{
@@ -39,3 +38,4 @@ int __init bcm63xx_uart_register(void)
uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
return platform_device_register(&bcm63xx_uart_device);
}
+arch_initcall(bcm63xx_uart_register);
diff --git a/arch/mips/bcm63xx/dev-wdt.c b/arch/mips/bcm63xx/dev-wdt.c
new file mode 100644
index 000000000000..3e6c716a4c11
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-wdt.c
@@ -0,0 +1,37 @@
+/*
+ * 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) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+
+static struct resource wdt_resources[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bcm63xx_wdt_device = {
+ .name = "bcm63xx-wdt",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+int __init bcm63xx_wdt_register(void)
+{
+ wdt_resources[0].start = bcm63xx_regset_address(RSET_WDT);
+ wdt_resources[0].end = wdt_resources[0].start;
+ wdt_resources[0].end += RSET_WDT_SIZE - 1;
+
+ return platform_device_register(&bcm63xx_wdt_device);
+}
+arch_initcall(bcm63xx_wdt_register);
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index b18a0ca926fa..d0056598fbfc 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -75,7 +75,9 @@ void bcm63xx_machine_reboot(void)
bcm6348_a1_reboot();
printk(KERN_INFO "triggering watchdog soft-reset...\n");
- bcm_perf_writel(SYS_PLL_SOFT_RESET, PERF_SYS_PLL_CTL_REG);
+ reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
+ reg |= SYS_PLL_SOFT_RESET;
+ bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
while (1)
;
}
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 384f1842bfb1..6f2acf09328d 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -17,6 +17,15 @@ DEFINE_RWLOCK(octeon_irq_ciu0_rwlock);
DEFINE_RWLOCK(octeon_irq_ciu1_rwlock);
DEFINE_SPINLOCK(octeon_irq_msi_lock);
+static int octeon_coreid_for_cpu(int cpu)
+{
+#ifdef CONFIG_SMP
+ return cpu_logical_map(cpu);
+#else
+ return cvmx_get_core_num();
+#endif
+}
+
static void octeon_irq_core_ack(unsigned int irq)
{
unsigned int bit = irq - OCTEON_IRQ_SW0;
@@ -152,11 +161,10 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
unsigned long flags;
uint64_t en0;
-#ifdef CONFIG_SMP
int cpu;
write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
for_each_online_cpu(cpu) {
- int coreid = cpu_logical_map(cpu);
+ int coreid = octeon_coreid_for_cpu(cpu);
en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
en0 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
@@ -167,26 +175,57 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
*/
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
-#else
- int coreid = cvmx_get_core_num();
- local_irq_save(flags);
- en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
- en0 &= ~(1ull << bit);
- cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
- cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
- local_irq_restore(flags);
-#endif
+}
+
+/*
+ * Enable the irq on the current core for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu0_enable_v2(unsigned int irq)
+{
+ int index = cvmx_get_core_num() * 2;
+ u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+}
+
+/*
+ * Disable the irq on the current core for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu0_disable_v2(unsigned int irq)
+{
+ int index = cvmx_get_core_num() * 2;
+ u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+}
+
+/*
+ * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu0_disable_all_v2(unsigned int irq)
+{
+ u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+ int index;
+ int cpu;
+ for_each_online_cpu(cpu) {
+ index = octeon_coreid_for_cpu(cpu) * 2;
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ }
}
#ifdef CONFIG_SMP
static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
{
int cpu;
+ unsigned long flags;
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
- write_lock(&octeon_irq_ciu0_rwlock);
+ write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
for_each_online_cpu(cpu) {
- int coreid = cpu_logical_map(cpu);
+ int coreid = octeon_coreid_for_cpu(cpu);
uint64_t en0 =
cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
if (cpumask_test_cpu(cpu, dest))
@@ -200,11 +239,45 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *
* of them are done.
*/
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
- write_unlock(&octeon_irq_ciu0_rwlock);
+ write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
return 0;
}
+
+/*
+ * Set affinity for the irq for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq,
+ const struct cpumask *dest)
+{
+ int cpu;
+ int index;
+ u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+ for_each_online_cpu(cpu) {
+ index = octeon_coreid_for_cpu(cpu) * 2;
+ if (cpumask_test_cpu(cpu, dest))
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ else
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ }
+ return 0;
+}
+#endif
+
+/*
+ * Newer octeon chips have support for lockless CIU operation.
+ */
+static struct irq_chip octeon_irq_chip_ciu0_v2 = {
+ .name = "CIU0",
+ .enable = octeon_irq_ciu0_enable_v2,
+ .disable = octeon_irq_ciu0_disable_all_v2,
+ .ack = octeon_irq_ciu0_disable_v2,
+ .eoi = octeon_irq_ciu0_enable_v2,
+#ifdef CONFIG_SMP
+ .set_affinity = octeon_irq_ciu0_set_affinity_v2,
#endif
+};
static struct irq_chip octeon_irq_chip_ciu0 = {
.name = "CIU0",
@@ -269,11 +342,10 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
unsigned long flags;
uint64_t en1;
-#ifdef CONFIG_SMP
int cpu;
write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
for_each_online_cpu(cpu) {
- int coreid = cpu_logical_map(cpu);
+ int coreid = octeon_coreid_for_cpu(cpu);
en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
en1 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
@@ -284,26 +356,58 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
*/
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
-#else
- int coreid = cvmx_get_core_num();
- local_irq_save(flags);
- en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
- en1 &= ~(1ull << bit);
- cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
- cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
- local_irq_restore(flags);
-#endif
+}
+
+/*
+ * Enable the irq on the current core for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu1_enable_v2(unsigned int irq)
+{
+ int index = cvmx_get_core_num() * 2 + 1;
+ u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+}
+
+/*
+ * Disable the irq on the current core for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu1_disable_v2(unsigned int irq)
+{
+ int index = cvmx_get_core_num() * 2 + 1;
+ u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+}
+
+/*
+ * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu1_disable_all_v2(unsigned int irq)
+{
+ u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+ int index;
+ int cpu;
+ for_each_online_cpu(cpu) {
+ index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+ }
}
#ifdef CONFIG_SMP
-static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest)
+static int octeon_irq_ciu1_set_affinity(unsigned int irq,
+ const struct cpumask *dest)
{
int cpu;
+ unsigned long flags;
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
- write_lock(&octeon_irq_ciu1_rwlock);
+ write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
for_each_online_cpu(cpu) {
- int coreid = cpu_logical_map(cpu);
+ int coreid = octeon_coreid_for_cpu(cpu);
uint64_t en1 =
cvmx_read_csr(CVMX_CIU_INTX_EN1
(coreid * 2 + 1));
@@ -318,12 +422,46 @@ static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *
* of them are done.
*/
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
- write_unlock(&octeon_irq_ciu1_rwlock);
+ write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
+
+ return 0;
+}
+/*
+ * Set affinity for the irq for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq,
+ const struct cpumask *dest)
+{
+ int cpu;
+ int index;
+ u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+ for_each_online_cpu(cpu) {
+ index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ if (cpumask_test_cpu(cpu, dest))
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ else
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+ }
return 0;
}
#endif
+/*
+ * Newer octeon chips have support for lockless CIU operation.
+ */
+static struct irq_chip octeon_irq_chip_ciu1_v2 = {
+ .name = "CIU0",
+ .enable = octeon_irq_ciu1_enable_v2,
+ .disable = octeon_irq_ciu1_disable_all_v2,
+ .ack = octeon_irq_ciu1_disable_v2,
+ .eoi = octeon_irq_ciu1_enable_v2,
+#ifdef CONFIG_SMP
+ .set_affinity = octeon_irq_ciu1_set_affinity_v2,
+#endif
+};
+
static struct irq_chip octeon_irq_chip_ciu1 = {
.name = "CIU1",
.enable = octeon_irq_ciu1_enable,
@@ -420,6 +558,8 @@ static struct irq_chip octeon_irq_chip_msi = {
void __init arch_init_irq(void)
{
int irq;
+ struct irq_chip *chip0;
+ struct irq_chip *chip1;
#ifdef CONFIG_SMP
/* Set the default affinity to the boot cpu. */
@@ -430,6 +570,16 @@ void __init arch_init_irq(void)
if (NR_IRQS < OCTEON_IRQ_LAST)
pr_err("octeon_irq_init: NR_IRQS is set too low\n");
+ if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) {
+ chip0 = &octeon_irq_chip_ciu0_v2;
+ chip1 = &octeon_irq_chip_ciu1_v2;
+ } else {
+ chip0 = &octeon_irq_chip_ciu0;
+ chip1 = &octeon_irq_chip_ciu1;
+ }
+
/* 0 - 15 reserved for i8259 master and slave controller. */
/* 17 - 23 Mips internal */
@@ -440,14 +590,12 @@ void __init arch_init_irq(void)
/* 24 - 87 CIU_INT_SUM0 */
for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
- set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu0,
- handle_percpu_irq);
+ set_irq_chip_and_handler(irq, chip0, handle_percpu_irq);
}
/* 88 - 151 CIU_INT_SUM1 */
for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_RESERVED151; irq++) {
- set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu1,
- handle_percpu_irq);
+ set_irq_chip_and_handler(irq, chip1, handle_percpu_irq);
}
#ifdef CONFIG_PCI_MSI
@@ -505,14 +653,10 @@ asmlinkage void plat_irq_dispatch(void)
#ifdef CONFIG_HOTPLUG_CPU
static int is_irq_enabled_on_cpu(unsigned int irq, unsigned int cpu)
{
- unsigned int isset;
-#ifdef CONFIG_SMP
- int coreid = cpu_logical_map(cpu);
-#else
- int coreid = cvmx_get_core_num();
-#endif
+ unsigned int isset;
+ int coreid = octeon_coreid_for_cpu(cpu);
int bit = (irq < OCTEON_IRQ_WDOG0) ?
- irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0;
+ irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0;
if (irq < 64) {
isset = (cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)) &
(1ull << bit)) >> bit;
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 32d51a31dc48..c198efdf583e 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -65,11 +65,12 @@ void octeon_send_ipi_single(int cpu, unsigned int action)
cvmx_write_csr(CVMX_CIU_MBOX_SETX(coreid), action);
}
-static inline void octeon_send_ipi_mask(cpumask_t mask, unsigned int action)
+static inline void octeon_send_ipi_mask(const struct cpumask *mask,
+ unsigned int action)
{
unsigned int i;
- for_each_cpu_mask(i, mask)
+ for_each_cpu_mask(i, *mask)
octeon_send_ipi_single(i, action);
}
diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig
index c69813b8488c..6c6a19aebe1f 100644
--- a/arch/mips/configs/rbtx49xx_defconfig
+++ b/arch/mips/configs/rbtx49xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc7
-# Wed Mar 4 23:08:06 2009
+# Linux kernel version: 2.6.32-rc6
+# Sun Nov 8 22:59:47 2009
#
CONFIG_MIPS=y
@@ -9,16 +9,18 @@ CONFIG_MIPS=y
# Machine selection
#
# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
# CONFIG_BASLER_EXCITE is not set
# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX 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_MACH_LOONGSON is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SIM is not set
-# CONFIG_MACH_EMMA is not set
+# CONFIG_NEC_MARKEINS is not set
# CONFIG_MACH_VR41XX is not set
# CONFIG_NXP_STB220 is not set
# CONFIG_NXP_STB225 is not set
@@ -45,6 +47,7 @@ CONFIG_MACH_TX49XX=y
# CONFIG_WR_PPMC is not set
# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
CONFIG_MACH_TXX9=y
CONFIG_TOSHIBA_RBTX4927=y
CONFIG_TOSHIBA_RBTX4938=y
@@ -86,7 +89,6 @@ 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=y
@@ -101,7 +103,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
# CONFIG_CPU_MIPS32_R1 is not set
# CONFIG_CPU_MIPS32_R2 is not set
# CONFIG_CPU_MIPS64_R1 is not set
@@ -137,6 +139,7 @@ CONFIG_32BIT=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_MIPS_MT_DISABLED=y
@@ -154,7 +157,10 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -175,6 +181,7 @@ CONFIG_PREEMPT_NONE=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -194,11 +201,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -209,8 +217,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
@@ -220,25 +232,35 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
# CONFIG_PCSPKR_PLATFORM is not set
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
+CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -246,8 +268,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
#
@@ -274,6 +296,7 @@ CONFIG_PCI_DOMAINS=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_MMU=y
#
@@ -288,6 +311,7 @@ CONFIG_TRAD_SIGNALS=y
#
# Power management options
#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PM is not set
CONFIG_NET=y
@@ -295,7 +319,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -311,6 +334,7 @@ CONFIG_IP_PNP=y
# 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
@@ -336,6 +360,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -347,7 +372,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
-# CONFIG_PHONET is not set
# CONFIG_WIRELESS is not set
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
@@ -365,9 +389,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
@@ -376,9 +400,9 @@ CONFIG_MTD_CMDLINE_PARTS=y
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
-# CONFIG_MTD_BLKDEVS is not set
-# CONFIG_MTD_BLOCK is not set
-# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
@@ -414,16 +438,20 @@ CONFIG_MTD_CFI_UTIL=y
#
# Mapping drivers for chip access
#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_GPIO_ADDR is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
+CONFIG_MTD_RBTX4939=y
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -435,7 +463,15 @@ CONFIG_MTD_PHYSMAP=y
# 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_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_TXX9NDFMC=m
# CONFIG_MTD_ONENAND is not set
#
@@ -471,6 +507,7 @@ CONFIG_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
+CONFIG_IDE_XFER_MODE=y
CONFIG_IDE_TIMINGS=y
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_IDE_GD=y
@@ -534,8 +571,13 @@ CONFIG_BLK_DEV_IDEDMA=y
#
#
-# A new alternative FireWire stack is available with EXPERIMENTAL=y
+# You can enable one or both FireWire driver stacks.
#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
@@ -574,6 +616,8 @@ CONFIG_MII=y
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_SMC91X=y
# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
CONFIG_NE2000=y
@@ -602,18 +646,15 @@ CONFIG_TC35815=y
# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_ATL2 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 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WLAN is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -653,6 +694,7 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_TXX9=y
@@ -666,7 +708,9 @@ 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_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_HW_RANDOM_TX4939=m
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -686,6 +730,10 @@ CONFIG_SPI_TXX9=y
# SPI Protocol Masters
#
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y
@@ -701,17 +749,22 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -740,28 +793,17 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
+# CONFIG_VGA_ARB is not set
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -772,7 +814,42 @@ CONFIG_SSB_POSSIBLE=y
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_SOUND is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC_TXX9ACLC=m
+CONFIG_HAS_TXX9_ACLC=y
+CONFIG_SND_SOC_TXX9ACLC_AC97=m
+CONFIG_SND_SOC_TXX9ACLC_GENERIC=m
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AC97_CODEC=m
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -783,6 +860,8 @@ CONFIG_LEDS_CLASS=y
# LED drivers
#
CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_DAC124S085 is not set
#
# LED Triggers
@@ -792,7 +871,12 @@ CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_IDE_DISK=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
CONFIG_RTC_LIB=y
@@ -820,6 +904,7 @@ CONFIG_RTC_INTF_DEV_UIE_EMUL=y
# CONFIG_RTC_DRV_R9701 is not set
CONFIG_RTC_DRV_RS5C348=y
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -840,8 +925,26 @@ CONFIG_RTC_DRV_DS1742=y
# on-CPU RTC drivers
#
CONFIG_RTC_DRV_TX4939=y
-# CONFIG_DMADEVICES is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_TXX9_DMAC=m
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -853,9 +956,10 @@ CONFIG_RTC_DRV_TX4939=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -866,6 +970,10 @@ CONFIG_INOTIFY_USER=y
CONFIG_GENERIC_ACL=y
#
+# Caches
+#
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -890,7 +998,27 @@ CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_HFSPLUS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY 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_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -922,6 +1050,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_STRIP_ASM_SYMS=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -929,11 +1058,9 @@ CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_CMDLINE=""
@@ -946,6 +1073,7 @@ CONFIG_CMDLINE=""
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
@@ -959,6 +1087,10 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/include/asm/bug.h b/arch/mips/include/asm/bug.h
index 6cf29c26e873..540c98a810d1 100644
--- a/arch/mips/include/asm/bug.h
+++ b/arch/mips/include/asm/bug.h
@@ -11,9 +11,7 @@
static inline void __noreturn BUG(void)
{
__asm__ __volatile__("break %0" : : "i" (BRK_BUG));
- /* Fool GCC into thinking the function doesn't return. */
- while (1)
- ;
+ unreachable();
}
#define HAVE_ARCH_BUG
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
index d16afddb09a9..664ba53dc32a 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -3,6 +3,7 @@
#include <asm/scatterlist.h>
#include <asm/cache.h>
+#include <asm-generic/dma-coherent.h>
void *dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
@@ -73,14 +74,4 @@ extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr);
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction);
-#if 0
-#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-
-extern int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
- dma_addr_t device_addr, size_t size, int flags);
-extern void dma_release_declared_memory(struct device *dev);
-extern void * dma_mark_declared_memory_occupied(struct device *dev,
- dma_addr_t device_addr, size_t size);
-#endif
-
#endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/mips/include/asm/fixmap.h b/arch/mips/include/asm/fixmap.h
index efeddc8db8b1..0b89b83e2055 100644
--- a/arch/mips/include/asm/fixmap.h
+++ b/arch/mips/include/asm/fixmap.h
@@ -48,9 +48,9 @@ enum fixed_addresses {
#define FIX_N_COLOURS 8
FIX_CMAP_BEGIN,
#ifdef CONFIG_MIPS_MT_SMTC
- FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS),
+ FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS * 2),
#else
- FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
+ FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * 2),
#endif
#ifdef CONFIG_HIGHMEM
/* reserved pte's for temporary kernel mappings */
diff --git a/arch/mips/include/asm/gcmpregs.h b/arch/mips/include/asm/gcmpregs.h
index 36fd969d64d6..c0cf76a2ca89 100644
--- a/arch/mips/include/asm/gcmpregs.h
+++ b/arch/mips/include/asm/gcmpregs.h
@@ -19,15 +19,20 @@
#define GCMP_GDB_OFS 0x8000 /* Global Debug Block */
/* Offsets to individual GCMP registers from GCMP base */
-#define GCMPOFS(block, tag, reg) (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS)
+#define GCMPOFS(block, tag, reg) \
+ (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS)
+#define GCMPOFSn(block, tag, reg, n) \
+ (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS(n))
#define GCMPGCBOFS(reg) GCMPOFS(GCB, GCB, reg)
+#define GCMPGCBOFSn(reg, n) GCMPOFSn(GCB, GCB, reg, n)
#define GCMPCLCBOFS(reg) GCMPOFS(CLCB, CCB, reg)
#define GCMPCOCBOFS(reg) GCMPOFS(COCB, CCB, reg)
#define GCMPGDBOFS(reg) GCMPOFS(GDB, GDB, reg)
/* GCMP register access */
#define GCMPGCB(reg) REGP(_gcmp_base, GCMPGCBOFS(reg))
+#define GCMPGCBn(reg, n) REGP(_gcmp_base, GCMPGCBOFSn(reg, n))
#define GCMPCLCB(reg) REGP(_gcmp_base, GCMPCLCBOFS(reg))
#define GCMPCOCB(reg) REGP(_gcmp_base, GCMPCOCBOFS(reg))
#define GCMPGDB(reg) REGP(_gcmp_base, GCMPGDBOFS(reg))
@@ -49,10 +54,10 @@
#define GCMP_GCB_GCMPB_GCMPBASE_MSK GCMPGCBMSK(GCMPB_GCMPBASE, 17)
#define GCMP_GCB_GCMPB_CMDEFTGT_SHF 0
#define GCMP_GCB_GCMPB_CMDEFTGT_MSK GCMPGCBMSK(GCMPB_CMDEFTGT, 2)
-#define GCMP_GCB_GCMPB_CMDEFTGT_MEM 0
-#define GCMP_GCB_GCMPB_CMDEFTGT_MEM1 1
-#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU1 2
-#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU2 3
+#define GCMP_GCB_GCMPB_CMDEFTGT_DISABLED 0
+#define GCMP_GCB_GCMPB_CMDEFTGT_MEM 1
+#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU1 2
+#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU2 3
#define GCMP_GCB_CCMC_OFS 0x0010 /* Global CM Control */
#define GCMP_GCB_GCSRAP_OFS 0x0020 /* Global CSR Access Privilege */
#define GCMP_GCB_GCSRAP_CMACCESS_SHF 0
@@ -115,5 +120,6 @@
#define GCMP_CCB_DBGGROUP_OFS 0x0100 /* DebugBreak Group */
extern int __init gcmp_probe(unsigned long, unsigned long);
-
+extern int __init gcmp_niocu(void);
+extern void __init gcmp_setregion(int, unsigned long, unsigned long, int);
#endif /* _ASM_GCMPREGS_H */
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
index a8f57341f123..9b9436a4d816 100644
--- a/arch/mips/include/asm/gic.h
+++ b/arch/mips/include/asm/gic.h
@@ -12,7 +12,6 @@
#define _ASM_GICREGS_H
#undef GICISBYTELITTLEENDIAN
-#define GICISWORDLITTLEENDIAN
/* Constants */
#define GIC_POL_POS 1
@@ -20,11 +19,7 @@
#define GIC_TRIG_EDGE 1
#define GIC_TRIG_LEVEL 0
-#ifdef CONFIG_SMP
#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
-#else
-#define GIC_NUM_INTRS 32
-#endif
#define MSK(n) ((1 << (n)) - 1)
#define REG32(addr) (*(volatile unsigned int *) (addr))
@@ -70,13 +65,13 @@
#define USM_VISIBLE_SECTION_SIZE 0x10000
/* Register Map for Shared Section */
-#if defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(GICISWORDLITTLEENDIAN)
#define GIC_SH_CONFIG_OFS 0x0000
/* Shared Global Counter */
#define GIC_SH_COUNTER_31_00_OFS 0x0010
#define GIC_SH_COUNTER_63_32_OFS 0x0014
+#define GIC_SH_REVISIONID_OFS 0x0020
/* Interrupt Polarity */
#define GIC_SH_POL_31_0_OFS 0x0100
@@ -164,24 +159,31 @@
(GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4))
#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32))
+/* Convert an interrupt number to a byte offset/bit for multi-word registers */
+#define GIC_INTR_OFS(intr) (((intr) / 32)*4)
+#define GIC_INTR_BIT(intr) ((intr) % 32)
+
/* Polarity : Reset Value is always 0 */
#define GIC_SH_SET_POLARITY_OFS 0x0100
#define GIC_SET_POLARITY(intr, pol) \
- GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + (((intr) / 32) * 4)), (pol) << ((intr) % 32))
+ GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \
+ GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr))
/* Triggering : Reset Value is always 0 */
#define GIC_SH_SET_TRIGGER_OFS 0x0180
#define GIC_SET_TRIGGER(intr, trig) \
- GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + (((intr) / 32) * 4)), (trig) << ((intr) % 32))
+ GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \
+ GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr))
/* Mask manipulation */
#define GIC_SH_SMASK_OFS 0x0380
-#define GIC_SET_INTR_MASK(intr, val) \
- GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + (((intr) / 32) * 4)), ((val) << ((intr) % 32)))
-
+#define GIC_SET_INTR_MASK(intr) \
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \
+ GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
#define GIC_SH_RMASK_OFS 0x0300
-#define GIC_CLR_INTR_MASK(intr, val) \
- GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + (((intr) / 32) * 4)), ((val) << ((intr) % 32)))
+#define GIC_CLR_INTR_MASK(intr) \
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \
+ GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
/* Register Map for Local Section */
#define GIC_VPE_CTL_OFS 0x0000
@@ -219,161 +221,6 @@
#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000
#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004
-#else /* CONFIG_CPU_BIG_ENDIAN */
-
-#define GIC_SH_CONFIG_OFS 0x0000
-
-/* Shared Global Counter */
-#define GIC_SH_COUNTER_31_00_OFS 0x0014
-#define GIC_SH_COUNTER_63_32_OFS 0x0010
-
-/* Interrupt Polarity */
-#define GIC_SH_POL_31_0_OFS 0x0104
-#define GIC_SH_POL_63_32_OFS 0x0100
-#define GIC_SH_POL_95_64_OFS 0x010c
-#define GIC_SH_POL_127_96_OFS 0x0108
-#define GIC_SH_POL_159_128_OFS 0x0114
-#define GIC_SH_POL_191_160_OFS 0x0110
-#define GIC_SH_POL_223_192_OFS 0x011c
-#define GIC_SH_POL_255_224_OFS 0x0118
-
-/* Edge/Level Triggering */
-#define GIC_SH_TRIG_31_0_OFS 0x0184
-#define GIC_SH_TRIG_63_32_OFS 0x0180
-#define GIC_SH_TRIG_95_64_OFS 0x018c
-#define GIC_SH_TRIG_127_96_OFS 0x0188
-#define GIC_SH_TRIG_159_128_OFS 0x0194
-#define GIC_SH_TRIG_191_160_OFS 0x0190
-#define GIC_SH_TRIG_223_192_OFS 0x019c
-#define GIC_SH_TRIG_255_224_OFS 0x0198
-
-/* Dual Edge Triggering */
-#define GIC_SH_DUAL_31_0_OFS 0x0204
-#define GIC_SH_DUAL_63_32_OFS 0x0200
-#define GIC_SH_DUAL_95_64_OFS 0x020c
-#define GIC_SH_DUAL_127_96_OFS 0x0208
-#define GIC_SH_DUAL_159_128_OFS 0x0214
-#define GIC_SH_DUAL_191_160_OFS 0x0210
-#define GIC_SH_DUAL_223_192_OFS 0x021c
-#define GIC_SH_DUAL_255_224_OFS 0x0218
-
-/* Set/Clear corresponding bit in Edge Detect Register */
-#define GIC_SH_WEDGE_OFS 0x0280
-
-/* Reset Mask - Disables Interrupt */
-#define GIC_SH_RMASK_31_0_OFS 0x0304
-#define GIC_SH_RMASK_63_32_OFS 0x0300
-#define GIC_SH_RMASK_95_64_OFS 0x030c
-#define GIC_SH_RMASK_127_96_OFS 0x0308
-#define GIC_SH_RMASK_159_128_OFS 0x0314
-#define GIC_SH_RMASK_191_160_OFS 0x0310
-#define GIC_SH_RMASK_223_192_OFS 0x031c
-#define GIC_SH_RMASK_255_224_OFS 0x0318
-
-/* Set Mask (WO) - Enables Interrupt */
-#define GIC_SH_SMASK_31_0_OFS 0x0384
-#define GIC_SH_SMASK_63_32_OFS 0x0380
-#define GIC_SH_SMASK_95_64_OFS 0x038c
-#define GIC_SH_SMASK_127_96_OFS 0x0388
-#define GIC_SH_SMASK_159_128_OFS 0x0394
-#define GIC_SH_SMASK_191_160_OFS 0x0390
-#define GIC_SH_SMASK_223_192_OFS 0x039c
-#define GIC_SH_SMASK_255_224_OFS 0x0398
-
-/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
-#define GIC_SH_MASK_31_0_OFS 0x0404
-#define GIC_SH_MASK_63_32_OFS 0x0400
-#define GIC_SH_MASK_95_64_OFS 0x040c
-#define GIC_SH_MASK_127_96_OFS 0x0408
-#define GIC_SH_MASK_159_128_OFS 0x0414
-#define GIC_SH_MASK_191_160_OFS 0x0410
-#define GIC_SH_MASK_223_192_OFS 0x041c
-#define GIC_SH_MASK_255_224_OFS 0x0418
-
-/* Pending Global Interrupts (RO) */
-#define GIC_SH_PEND_31_0_OFS 0x0484
-#define GIC_SH_PEND_63_32_OFS 0x0480
-#define GIC_SH_PEND_95_64_OFS 0x048c
-#define GIC_SH_PEND_127_96_OFS 0x0488
-#define GIC_SH_PEND_159_128_OFS 0x0494
-#define GIC_SH_PEND_191_160_OFS 0x0490
-#define GIC_SH_PEND_223_192_OFS 0x049c
-#define GIC_SH_PEND_255_224_OFS 0x0498
-
-#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
-
-/* Maps Interrupt X to a Pin */
-#define GIC_SH_MAP_TO_PIN(intr) \
- (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr))
-
-#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2004
-
-/*
- * Maps Interrupt X to a VPE. This is more complex than the LE case, as
- * odd and even registers need to be transposed. It does work - trust me!
- */
-#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
- (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + \
- (((((vpe) / 32) ^ 1) - 1) * 4))
-#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32))
-
-/* Polarity */
-#define GIC_SH_SET_POLARITY_OFS 0x0100
-#define GIC_SET_POLARITY(intr, pol) \
- GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), (pol) << ((intr) % 32))
-
-/* Triggering */
-#define GIC_SH_SET_TRIGGER_OFS 0x0180
-#define GIC_SET_TRIGGER(intr, trig) \
- GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), (trig) << ((intr) % 32))
-
-/* Mask manipulation */
-#define GIC_SH_SMASK_OFS 0x0380
-#define GIC_SET_INTR_MASK(intr, val) \
- GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32)))
-
-#define GIC_SH_RMASK_OFS 0x0300
-#define GIC_CLR_INTR_MASK(intr, val) \
- GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32)))
-
-/* Register Map for Local Section */
-#define GIC_VPE_CTL_OFS 0x0000
-#define GIC_VPE_PEND_OFS 0x0004
-#define GIC_VPE_MASK_OFS 0x0008
-#define GIC_VPE_RMASK_OFS 0x000c
-#define GIC_VPE_SMASK_OFS 0x0010
-#define GIC_VPE_WD_MAP_OFS 0x0040
-#define GIC_VPE_COMPARE_MAP_OFS 0x0044
-#define GIC_VPE_TIMER_MAP_OFS 0x0048
-#define GIC_VPE_PERFCTR_MAP_OFS 0x0050
-#define GIC_VPE_SWINT0_MAP_OFS 0x0054
-#define GIC_VPE_SWINT1_MAP_OFS 0x0058
-#define GIC_VPE_OTHER_ADDR_OFS 0x0080
-#define GIC_VPE_WD_CONFIG0_OFS 0x0090
-#define GIC_VPE_WD_COUNT0_OFS 0x0094
-#define GIC_VPE_WD_INITIAL0_OFS 0x0098
-#define GIC_VPE_COMPARE_LO_OFS 0x00a4
-#define GIC_VPE_COMPARE_HI_OFS 0x00a0
-
-#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100
-#define GIC_VPE_EIC_SS(intr) \
- (GIC_EIC_SHADOW_SET_BASE + (4 * intr))
-
-#define GIC_VPE_EIC_VEC_BASE 0x0800
-#define GIC_VPE_EIC_VEC(intr) \
- (GIC_VPE_EIC_VEC_BASE + (4 * intr))
-
-#define GIC_VPE_TENABLE_NMI_OFS 0x1000
-#define GIC_VPE_TENABLE_YQ_OFS 0x1004
-#define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080
-#define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084
-
-/* User Mode Visible Section Register Map */
-#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0004
-#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0000
-
-#endif /* !LE */
-
/* Masks */
#define GIC_SH_CONFIG_COUNTSTOP_SHF 28
#define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
@@ -473,12 +320,13 @@ struct gic_intrmask_regs {
* in building ipi_map.
*/
struct gic_intr_map {
- unsigned int intrnum; /* Ext Intr Num */
unsigned int cpunum; /* Directed to this CPU */
unsigned int pin; /* Directed to this Pin */
unsigned int polarity; /* Polarity : +/- */
unsigned int trigtype; /* Trigger : Edge/Levl */
- unsigned int ipiflag; /* Is used for IPI ? */
+ unsigned int flags; /* Misc flags */
+#define GIC_FLAG_IPI 0x01
+#define GIC_FLAG_TRANSPARENT 0x02
};
extern void gic_init(unsigned long gic_base_addr,
diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h
index de71694614de..21cbbc706448 100644
--- a/arch/mips/include/asm/mach-ar7/ar7.h
+++ b/arch/mips/include/asm/mach-ar7/ar7.h
@@ -78,6 +78,9 @@
#define AR7_REF_CLOCK 25000000
#define AR7_XTAL_CLOCK 24000000
+/* DCL */
+#define AR7_WDT_HW_ENA 0x10
+
struct plat_cpmac_data {
int reset_bit;
int power_bit;
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
index feea00148b5d..91595fa89034 100644
--- a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
+++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
@@ -104,6 +104,8 @@ static inline int au1100_gpio2_to_irq(int gpio)
if ((gpio >= 8) && (gpio <= 15))
return MAKE_IRQ(0, 29); /* shared GPIO208_215 */
+
+ return -ENXIO;
}
#ifdef CONFIG_SOC_AU1100
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
deleted file mode 100644
index bf348f573bbc..000000000000
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef BCM63XX_DEV_UART_H_
-#define BCM63XX_DEV_UART_H_
-
-int bcm63xx_uart_register(void);
-
-#endif /* BCM63XX_DEV_UART_H_ */
diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h
index f6837422fe65..09a59bcc1b07 100644
--- a/arch/mips/include/asm/mach-ip27/topology.h
+++ b/arch/mips/include/asm/mach-ip27/topology.h
@@ -44,8 +44,8 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
.busy_factor = 32, \
.imbalance_pct = 125, \
.cache_nice_tries = 1, \
- .flags = SD_LOAD_BALANCE \
- | SD_BALANCE_EXEC \
+ .flags = SD_LOAD_BALANCE | \
+ SD_BALANCE_EXEC, \
.last_balance = jiffies, \
.balance_interval = 1, \
.nr_balance_failed = 0, \
diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
index ce5b6e270e3f..9947e57c91de 100644
--- a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
@@ -29,7 +29,7 @@
#define cpu_has_cache_cdex_p 0
#define cpu_has_cache_cdex_s 0
#define cpu_has_counter 1
-#define cpu_has_dc_aliases 1
+#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_divec 0
#define cpu_has_dsp 0
#define cpu_has_ejtag 0
@@ -54,6 +54,5 @@
#define cpu_has_vce 0
#define cpu_has_vtag_icache 0
#define cpu_has_watch 1
-#define cpu_icache_snoops_remote_store 1
#endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mman.h b/arch/mips/include/asm/mman.h
index a2250f390a29..c892bfb3e2c1 100644
--- a/arch/mips/include/asm/mman.h
+++ b/arch/mips/include/asm/mman.h
@@ -75,6 +75,7 @@
#define MADV_MERGEABLE 12 /* KSM may merge identical pages */
#define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */
+#define MADV_HWPOISON 100 /* poison a page for testing */
/* compatibility flags */
#define MAP_FILE 0
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index d9743536a621..6083db586500 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -16,6 +16,7 @@
#include <linux/smp.h>
#include <linux/slab.h>
#include <asm/cacheflush.h>
+#include <asm/hazards.h>
#include <asm/tlbflush.h>
#ifdef CONFIG_MIPS_MT_SMTC
#include <asm/mipsmtregs.h>
@@ -36,11 +37,13 @@ extern unsigned long pgd_current[];
#ifdef CONFIG_32BIT
#define TLBMISS_HANDLER_SETUP() \
write_c0_context((unsigned long) smp_processor_id() << 25); \
+ back_to_back_c0_hazard(); \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
#endif
#ifdef CONFIG_64BIT
#define TLBMISS_HANDLER_SETUP() \
write_c0_context((unsigned long) smp_processor_id() << 26); \
+ back_to_back_c0_hazard(); \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
#endif
@@ -165,12 +168,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
* having ASID_MASK smaller than the hardware maximum,
* make sure no "soft" bits become "hard"...
*/
- write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK)
- | (cpu_context(cpu, next) & ASID_MASK));
+ write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
+ cpu_asid(cpu, next));
ehb(); /* Make sure it propagates to TCStatus */
evpe(mtflags);
#else
- write_c0_entryhi(cpu_context(cpu, next));
+ write_c0_entryhi(cpu_asid(cpu, next));
#endif /* CONFIG_MIPS_MT_SMTC */
TLBMISS_HANDLER_SETUP_PGD(next->pgd);
@@ -226,11 +229,11 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next)
}
/* See comments for similar code above */
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
- (cpu_context(cpu, next) & ASID_MASK));
+ cpu_asid(cpu, next));
ehb(); /* Make sure it propagates to TCStatus */
evpe(mtflags);
#else
- write_c0_entryhi(cpu_context(cpu, next));
+ write_c0_entryhi(cpu_asid(cpu, next));
#endif /* CONFIG_MIPS_MT_SMTC */
TLBMISS_HANDLER_SETUP_PGD(next->pgd);
diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h
index e600cedda976..50511aac04e9 100644
--- a/arch/mips/include/asm/setup.h
+++ b/arch/mips/include/asm/setup.h
@@ -1,7 +1,7 @@
#ifndef _MIPS_SETUP_H
#define _MIPS_SETUP_H
-#define COMMAND_LINE_SIZE 256
+#define COMMAND_LINE_SIZE 4096
#ifdef __KERNEL__
extern void setup_early_printk(void);
diff --git a/arch/mips/include/asm/smtc_ipi.h b/arch/mips/include/asm/smtc_ipi.h
index 8ce517574340..15278dbd7e79 100644
--- a/arch/mips/include/asm/smtc_ipi.h
+++ b/arch/mips/include/asm/smtc_ipi.h
@@ -45,6 +45,7 @@ struct smtc_ipi_q {
spinlock_t lock;
struct smtc_ipi *tail;
int depth;
+ int resched_flag; /* reschedule already queued */
};
static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
diff --git a/arch/mips/include/asm/spram.h b/arch/mips/include/asm/spram.h
new file mode 100644
index 000000000000..0b89006e4907
--- /dev/null
+++ b/arch/mips/include/asm/spram.h
@@ -0,0 +1,10 @@
+#ifndef _MIPS_SPRAM_H
+#define _MIPS_SPRAM_H
+
+#ifdef CONFIG_CPU_MIPSR2
+extern __init void spram_config(void);
+#else
+static inline void spram_config(void) { };
+#endif /* CONFIG_CPU_MIPSR2 */
+
+#endif /* _MIPS_SPRAM_H */
diff --git a/arch/mips/include/asm/system.h b/arch/mips/include/asm/system.h
index fcf5f98d90cc..83b5509e09e8 100644
--- a/arch/mips/include/asm/system.h
+++ b/arch/mips/include/asm/system.h
@@ -12,6 +12,7 @@
#ifndef _ASM_SYSTEM_H
#define _ASM_SYSTEM_H
+#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/irqflags.h>
@@ -193,10 +194,6 @@ extern __u64 __xchg_u64_unsupported_on_32bit_kernels(volatile __u64 * m, __u64 v
#define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels
#endif
-/* This function doesn't exist, so you'll get a linker error
- if something tries to do an invalid xchg(). */
-extern void __xchg_called_with_bad_pointer(void);
-
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
switch (size) {
@@ -205,11 +202,17 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
case 8:
return __xchg_u64(ptr, x);
}
- __xchg_called_with_bad_pointer();
+
return x;
}
-#define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+#define xchg(ptr, x) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) & ~0xc); \
+ \
+ ((__typeof__(*(ptr))) \
+ __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))); \
+})
extern void set_handler(unsigned long offset, void *addr, unsigned long len);
extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 01cc1630b66c..845da2107ed1 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -86,14 +86,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
#ifdef CONFIG_DEBUG_STACK_USAGE
-#define alloc_thread_info(tsk) \
-({ \
- struct thread_info *ret; \
- \
- ret = kzalloc(THREAD_SIZE, GFP_KERNEL); \
- \
- ret; \
-})
+#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL)
#else
#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
#endif
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index 7fd170d007e7..7bd32d04c2cc 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -134,7 +134,7 @@ static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id)
static struct irqaction r4030_timer_irqaction = {
.handler = r4030_timer_interrupt,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
.name = "R4030 timer",
};
diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c
index e02f79b1eb51..bfea327c636c 100644
--- a/arch/mips/kernel/cevt-bcm1480.c
+++ b/arch/mips/kernel/cevt-bcm1480.c
@@ -144,7 +144,7 @@ void __cpuinit sb1480_clockevent_init(void)
bcm1480_unmask_irq(cpu, irq);
action->handler = sibyte_counter_handler;
- action->flags = IRQF_DISABLED | IRQF_PERCPU;
+ action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER;
action->name = name;
action->dev_id = cd;
diff --git a/arch/mips/kernel/cevt-ds1287.c b/arch/mips/kernel/cevt-ds1287.c
index 6996da4d74a2..00a4da277cbb 100644
--- a/arch/mips/kernel/cevt-ds1287.c
+++ b/arch/mips/kernel/cevt-ds1287.c
@@ -107,7 +107,7 @@ static irqreturn_t ds1287_interrupt(int irq, void *dev_id)
static struct irqaction ds1287_irqaction = {
.handler = ds1287_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "ds1287",
};
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
index 92351e00ae0e..f5d265eb6eae 100644
--- a/arch/mips/kernel/cevt-gt641xx.c
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -113,7 +113,7 @@ static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
static struct irqaction gt641xx_timer0_irqaction = {
.handler = gt641xx_timer0_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "gt641xx_timer0",
};
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 2652362ce047..b469ad05d520 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -83,7 +83,7 @@ out:
struct irqaction c0_compare_irqaction = {
.handler = c0_compare_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "timer",
};
diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c
index ac5903d1b20e..da78eeaea6e8 100644
--- a/arch/mips/kernel/cevt-sb1250.c
+++ b/arch/mips/kernel/cevt-sb1250.c
@@ -143,7 +143,7 @@ void __cpuinit sb1250_clockevent_init(void)
sb1250_unmask_irq(cpu, irq);
action->handler = sibyte_counter_handler;
- action->flags = IRQF_DISABLED | IRQF_PERCPU;
+ action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER;
action->name = name;
action->dev_id = cd;
diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c
index 98bd7de75778..b102e4f1630e 100644
--- a/arch/mips/kernel/cevt-smtc.c
+++ b/arch/mips/kernel/cevt-smtc.c
@@ -173,11 +173,12 @@ void smtc_distribute_timer(int vpe)
unsigned int mtflags;
int cpu;
struct clock_event_device *cd;
- unsigned long nextstamp = 0L;
+ unsigned long nextstamp;
unsigned long reference;
repeat:
+ nextstamp = 0L;
for_each_online_cpu(cpu) {
/*
* Find virtual CPUs within the current VPE who have
diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c
index 0037f21baf0d..218ee6bda935 100644
--- a/arch/mips/kernel/cevt-txx9.c
+++ b/arch/mips/kernel/cevt-txx9.c
@@ -146,7 +146,7 @@ static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
static struct irqaction txx9tmr_irq = {
.handler = txx9tmr_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "txx9tmr",
.dev_id = &txx9_clock_event_device,
};
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index f709657e4dcd..7a51866068a4 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -23,7 +23,7 @@
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/watch.h>
-
+#include <asm/spram.h>
/*
* Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
* the implementation of the "wait" feature differs between CPU families. This
@@ -711,12 +711,6 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c)
mips_probe_watch_registers(c);
}
-#ifdef CONFIG_CPU_MIPSR2
-extern void spram_config(void);
-#else
-static inline void spram_config(void) {}
-#endif
-
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
{
decode_configs(c);
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 531ce7b16124..ea695d9605e9 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -191,6 +191,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
/* Set the SP after an empty pt_regs. */
PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE
PTR_ADDU sp, $28
+ back_to_back_c0_hazard
set_saved_sp sp, t0, t1
PTR_SUBU sp, 4 * SZREG # init stack pointer
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c
index f7d8d5d0ddbf..ed5c441615e4 100644
--- a/arch/mips/kernel/i8253.c
+++ b/arch/mips/kernel/i8253.c
@@ -98,7 +98,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
static struct irqaction irq0 = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
.name = "timer"
};
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index d2072cd38592..b181f2f0ea8e 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -14,38 +14,23 @@
static unsigned long _gic_base;
-static unsigned int _irqbase, _mapsize, numvpes, numintrs;
-static struct gic_intr_map *_intrmap;
+static unsigned int _irqbase;
+static unsigned int gic_irq_flags[GIC_NUM_INTRS];
+#define GIC_IRQ_FLAG_EDGE 0x0001
-static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
+struct gic_pcpu_mask pcpu_masks[NR_CPUS];
static struct gic_pending_regs pending_regs[NR_CPUS];
static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
-#define gic_wedgeb2bok 0 /*
- * Can GIC handle b2b writes to wedge register?
- */
-#if gic_wedgeb2bok == 0
-static DEFINE_SPINLOCK(gic_wedgeb2b_lock);
-#endif
-
void gic_send_ipi(unsigned int intr)
{
-#if gic_wedgeb2bok == 0
- unsigned long flags;
-#endif
pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__,
read_c0_status());
- if (!gic_wedgeb2bok)
- spin_lock_irqsave(&gic_wedgeb2b_lock, flags);
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
- if (!gic_wedgeb2bok) {
- (void) GIC_REG(SHARED, GIC_SH_CONFIG);
- spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags);
- }
}
/* This is Malta specific and needs to be exported */
-static void vpe_local_setup(unsigned int numvpes)
+static void __init vpe_local_setup(unsigned int numvpes)
{
int i;
unsigned long timer_interrupt = 5, perf_interrupt = 5;
@@ -105,44 +90,34 @@ unsigned int gic_get_int(void)
static unsigned int gic_irq_startup(unsigned int irq)
{
- pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
- GIC_SET_INTR_MASK(irq, 1);
+ pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
+ GIC_SET_INTR_MASK(irq);
return 0;
}
static void gic_irq_ack(unsigned int irq)
{
-#if gic_wedgeb2bok == 0
- unsigned long flags;
-#endif
- pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
- GIC_CLR_INTR_MASK(irq, 1);
+ pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
+ GIC_CLR_INTR_MASK(irq);
- if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) {
- if (!gic_wedgeb2bok)
- spin_lock_irqsave(&gic_wedgeb2b_lock, flags);
+ if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE)
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
- if (!gic_wedgeb2bok) {
- (void) GIC_REG(SHARED, GIC_SH_CONFIG);
- spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags);
- }
- }
}
static void gic_mask_irq(unsigned int irq)
{
- pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
- GIC_CLR_INTR_MASK(irq, 1);
+ pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
+ GIC_CLR_INTR_MASK(irq);
}
static void gic_unmask_irq(unsigned int irq)
{
- pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
- GIC_SET_INTR_MASK(irq, 1);
+ pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
+ GIC_SET_INTR_MASK(irq);
}
#ifdef CONFIG_SMP
@@ -155,9 +130,8 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
unsigned long flags;
int i;
- pr_debug(KERN_DEBUG "%s called\n", __func__);
irq -= _irqbase;
-
+ pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq);
cpumask_and(&tmp, cpumask, cpu_online_mask);
if (cpus_empty(tmp))
return -1;
@@ -168,13 +142,6 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
/* Re-route this IRQ */
GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
- /*
- * FIXME: assumption that _intrmap is ordered and has no holes
- */
-
- /* Update the intr_map */
- _intrmap[irq].cpunum = first_cpu(tmp);
-
/* Update the pcpu_masks */
for (i = 0; i < NR_CPUS; i++)
clear_bit(irq, pcpu_masks[i].pcpu_mask);
@@ -201,8 +168,9 @@ static struct irq_chip gic_irq_controller = {
#endif
};
-static void __init setup_intr(unsigned int intr, unsigned int cpu,
- unsigned int pin, unsigned int polarity, unsigned int trigtype)
+static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
+ unsigned int pin, unsigned int polarity, unsigned int trigtype,
+ unsigned int flags)
{
/* Setup Intr to Pin mapping */
if (pin & GIC_MAP_TO_NMI_MSK) {
@@ -227,38 +195,43 @@ static void __init setup_intr(unsigned int intr, unsigned int cpu,
GIC_SET_TRIGGER(intr, trigtype);
/* Init Intr Masks */
- GIC_SET_INTR_MASK(intr, 0);
+ GIC_CLR_INTR_MASK(intr);
+ /* Initialise per-cpu Interrupt software masks */
+ if (flags & GIC_FLAG_IPI)
+ set_bit(intr, pcpu_masks[cpu].pcpu_mask);
+ if (flags & GIC_FLAG_TRANSPARENT)
+ GIC_SET_INTR_MASK(intr);
+ if (trigtype == GIC_TRIG_EDGE)
+ gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE;
}
-static void __init gic_basic_init(void)
+static void __init gic_basic_init(int numintrs, int numvpes,
+ struct gic_intr_map *intrmap, int mapsize)
{
unsigned int i, cpu;
/* Setup defaults */
- for (i = 0; i < GIC_NUM_INTRS; i++) {
+ for (i = 0; i < numintrs; i++) {
GIC_SET_POLARITY(i, GIC_POL_POS);
GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
- GIC_SET_INTR_MASK(i, 0);
+ GIC_CLR_INTR_MASK(i);
+ if (i < GIC_NUM_INTRS)
+ gic_irq_flags[i] = 0;
}
/* Setup specifics */
- for (i = 0; i < _mapsize; i++) {
- cpu = _intrmap[i].cpunum;
+ for (i = 0; i < mapsize; i++) {
+ cpu = intrmap[i].cpunum;
if (cpu == X)
continue;
-
- if (cpu == 0 && i != 0 && _intrmap[i].intrnum == 0 &&
- _intrmap[i].ipiflag == 0)
+ if (cpu == 0 && i != 0 && intrmap[i].flags == 0)
continue;
-
- setup_intr(_intrmap[i].intrnum,
- _intrmap[i].cpunum,
- _intrmap[i].pin,
- _intrmap[i].polarity,
- _intrmap[i].trigtype);
- /* Initialise per-cpu Interrupt software masks */
- if (_intrmap[i].ipiflag)
- set_bit(_intrmap[i].intrnum, pcpu_masks[cpu].pcpu_mask);
+ gic_setup_intr(i,
+ intrmap[i].cpunum,
+ intrmap[i].pin,
+ intrmap[i].polarity,
+ intrmap[i].trigtype,
+ intrmap[i].flags);
}
vpe_local_setup(numvpes);
@@ -273,12 +246,11 @@ void __init gic_init(unsigned long gic_base_addr,
unsigned int irqbase)
{
unsigned int gicconfig;
+ int numvpes, numintrs;
_gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
gic_addrspace_size);
_irqbase = irqbase;
- _intrmap = intr_map;
- _mapsize = intr_map_size;
GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
@@ -290,5 +262,5 @@ void __init gic_init(unsigned long gic_base_addr,
pr_debug("%s called\n", __func__);
- gic_basic_init();
+ gic_basic_init(numintrs, numvpes, intr_map, intr_map_size);
}
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 6242bc68add7..b77fefaff9da 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -428,3 +428,9 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
return do_fork(clone_flags, newsp, &regs, 0,
parent_tidptr, child_tidptr);
}
+
+asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf,
+ size_t len)
+{
+ return sys_lookup_dcookie(merge_64(a0, a1), buf, len);
+}
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 9bbf9775e0bd..14dde4ca932e 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -450,7 +450,7 @@ sys_call_table:
PTR sys_io_submit
PTR sys_io_cancel /* 4245 */
PTR sys_exit_group
- PTR sys_lookup_dcookie
+ PTR sys32_lookup_dcookie
PTR sys_epoll_create
PTR sys_epoll_ctl
PTR sys_epoll_wait /* 4250 */
@@ -505,7 +505,7 @@ sys_call_table:
PTR sys_fchmodat
PTR sys_faccessat /* 4300 */
PTR compat_sys_pselect6
- PTR sys_ppoll
+ PTR compat_sys_ppoll
PTR sys_unshare
PTR sys_splice
PTR sys32_sync_file_range /* 4305 */
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 4d181df44a40..24630fd8ef60 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -75,7 +75,6 @@ unsigned long irq_hwmask[NR_IRQS];
asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
-
/*
* Number of InterProcessor Interrupt (IPI) message buffers to allocate
*/
@@ -388,6 +387,7 @@ void smtc_prepare_cpus(int cpus)
IPIQ[i].head = IPIQ[i].tail = NULL;
spin_lock_init(&IPIQ[i].lock);
IPIQ[i].depth = 0;
+ IPIQ[i].resched_flag = 0; /* No reschedules queued initially */
}
/* cpu_data index starts at zero */
@@ -741,11 +741,24 @@ void smtc_forward_irq(unsigned int irq)
static void smtc_ipi_qdump(void)
{
int i;
+ struct smtc_ipi *temp;
for (i = 0; i < NR_CPUS ;i++) {
- printk("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
+ pr_info("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail,
IPIQ[i].depth);
+ temp = IPIQ[i].head;
+
+ while (temp != IPIQ[i].tail) {
+ pr_debug("%d %d %d: ", temp->type, temp->dest,
+ (int)temp->arg);
+#ifdef SMTC_IPI_DEBUG
+ pr_debug("%u %lu\n", temp->sender, temp->stamp);
+#else
+ pr_debug("\n");
+#endif
+ temp = temp->flink;
+ }
}
}
@@ -784,11 +797,16 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
int mtflags;
unsigned long tcrestart;
extern void r4k_wait_irqoff(void), __pastwait(void);
+ int set_resched_flag = (type == LINUX_SMP_IPI &&
+ action == SMP_RESCHEDULE_YOURSELF);
if (cpu == smp_processor_id()) {
printk("Cannot Send IPI to self!\n");
return;
}
+ if (set_resched_flag && IPIQ[cpu].resched_flag != 0)
+ return; /* There is a reschedule queued already */
+
/* Set up a descriptor, to be delivered either promptly or queued */
pipi = smtc_ipi_dq(&freeIPIq);
if (pipi == NULL) {
@@ -801,6 +819,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
pipi->dest = cpu;
if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
/* If not on same VPE, enqueue and send cross-VPE interrupt */
+ IPIQ[cpu].resched_flag |= set_resched_flag;
smtc_ipi_nq(&IPIQ[cpu], pipi);
LOCK_CORE_PRA();
settc(cpu_data[cpu].tc_id);
@@ -847,6 +866,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
*/
write_tc_c0_tchalt(0);
UNLOCK_CORE_PRA();
+ IPIQ[cpu].resched_flag |= set_resched_flag;
smtc_ipi_nq(&IPIQ[cpu], pipi);
} else {
postdirect:
@@ -996,12 +1016,15 @@ void deferred_smtc_ipi(void)
* already enabled.
*/
local_irq_save(flags);
-
spin_lock(&q->lock);
pipi = __smtc_ipi_dq(q);
spin_unlock(&q->lock);
- if (pipi != NULL)
+ if (pipi != NULL) {
+ if (pipi->type == LINUX_SMP_IPI &&
+ (int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
+ IPIQ[cpu].resched_flag = 0;
ipi_decode(pipi);
+ }
/*
* The use of the __raw_local restore isn't
* as obviously necessary here as in smtc_ipi_replay(),
@@ -1082,6 +1105,9 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm)
* with interrupts off
*/
local_irq_save(flags);
+ if (pipi->type == LINUX_SMP_IPI &&
+ (int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
+ IPIQ[cpu].resched_flag = 0;
ipi_decode(pipi);
local_irq_restore(flags);
}
diff --git a/arch/mips/kernel/spram.c b/arch/mips/kernel/spram.c
index 6ddb507a87ef..1821d12a6410 100644
--- a/arch/mips/kernel/spram.c
+++ b/arch/mips/kernel/spram.c
@@ -13,7 +13,6 @@
#include <linux/ptrace.h>
#include <linux/stddef.h>
-#include <asm/cpu.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
@@ -198,8 +197,7 @@ static __cpuinit void probe_spram(char *type,
offset += 2 * SPRAM_TAG_STRIDE;
}
}
-
-__cpuinit void spram_config(void)
+void __cpuinit spram_config(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
unsigned int config0;
@@ -208,6 +206,7 @@ __cpuinit void spram_config(void)
case CPU_24K:
case CPU_34K:
case CPU_74K:
+ case CPU_1004K:
config0 = read_c0_config();
/* FIXME: addresses are Malta specific */
if (config0 & (1<<24)) {
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 3fe1fcfa2e73..fe0d79805603 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -306,6 +306,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__ (
+ " .set mips3 \n"
" li %[err], 0 \n"
"1: ll %[old], (%[addr]) \n"
" move %[tmp], %[new] \n"
@@ -320,6 +321,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
" "STR(PTR)" 1b, 4b \n"
" "STR(PTR)" 2b, 4b \n"
" .previous \n"
+ " .set mips0 \n"
: [old] "=&r" (old),
[err] "=&r" (err),
[tmp] "=&r" (tmp)
@@ -329,6 +331,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
: "memory");
} else if (cpu_has_llsc) {
__asm__ __volatile__ (
+ " .set mips3 \n"
" li %[err], 0 \n"
"1: ll %[old], (%[addr]) \n"
" move %[tmp], %[new] \n"
@@ -347,6 +350,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
" "STR(PTR)" 1b, 5b \n"
" "STR(PTR)" 2b, 5b \n"
" .previous \n"
+ " .set mips0 \n"
: [old] "=&r" (old),
[err] "=&r" (err),
[tmp] "=&r" (tmp)
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 03092ab2a296..60477529362e 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1116,8 +1116,6 @@ static int vpe_open(struct inode *inode, struct file *filp)
v->shared_ptr = NULL;
v->__start = 0;
- unlock_kernel();
-
return 0;
}
diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c
index f368c735cbd3..b32b4a3e5137 100644
--- a/arch/mips/loongson/common/irq.c
+++ b/arch/mips/loongson/common/irq.c
@@ -55,7 +55,6 @@ void __init arch_init_irq(void)
* int-handler is not on bootstrap
*/
clear_c0_status(ST0_IM | ST0_BEV);
- local_irq_disable();
/* setting irq trigger mode */
set_irq_trigger_mode();
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 890f77927d62..454b53924490 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -163,33 +163,34 @@ static int isBranchInstr(mips_instruction * i)
/*
* In the Linux kernel, we support selection of FPR format on the
- * basis of the Status.FR bit. This does imply that, if a full 32
- * FPRs are desired, there needs to be a flip-flop that can be written
- * to one at that bit position. In any case, O32 MIPS ABI uses
- * only the even FPRs (Status.FR = 0).
+ * basis of the Status.FR bit. If an FPU is not present, the FR bit
+ * is hardwired to zero, which would imply a 32-bit FPU even for
+ * 64-bit CPUs. For 64-bit kernels with no FPU we use TIF_32BIT_REGS
+ * as a proxy for the FR bit so that a 64-bit FPU is emulated. In any
+ * case, for a 32-bit kernel which uses the O32 MIPS ABI, only the
+ * even FPRs are used (Status.FR = 0).
*/
-
-#define CP0_STATUS_FR_SUPPORT
-
-#ifdef CP0_STATUS_FR_SUPPORT
-#define FR_BIT ST0_FR
+static inline int cop1_64bit(struct pt_regs *xcp)
+{
+ if (cpu_has_fpu)
+ return xcp->cp0_status & ST0_FR;
+#ifdef CONFIG_64BIT
+ return !test_thread_flag(TIF_32BIT_REGS);
#else
-#define FR_BIT 0
+ return 0;
#endif
+}
+
+#define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \
+ (int)ctx->fpr[x] : (int)(ctx->fpr[x & ~1] >> 32))
-#define SIFROMREG(si, x) ((si) = \
- (xcp->cp0_status & FR_BIT) || !(x & 1) ? \
- (int)ctx->fpr[x] : \
- (int)(ctx->fpr[x & ~1] >> 32 ))
-#define SITOREG(si, x) (ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)] = \
- (xcp->cp0_status & FR_BIT) || !(x & 1) ? \
+#define SITOREG(si, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = \
+ cop1_64bit(xcp) || !(x & 1) ? \
ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
-#define DIFROMREG(di, x) ((di) = \
- ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)])
-#define DITOREG(di, x) (ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)] \
- = (di))
+#define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)])
+#define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di))
#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
#define SPTOREG(sp, x) SITOREG((sp).bits, x)
diff --git a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c
index 1c555e6c6a9f..d9ae1dbabda7 100644
--- a/arch/mips/math-emu/dp_simple.c
+++ b/arch/mips/math-emu/dp_simple.c
@@ -62,8 +62,6 @@ ieee754dp ieee754dp_neg(ieee754dp x)
return ieee754dp_nanxcpt(y, "neg");
}
- if (ieee754dp_isnan(x)) /* but not infinity */
- return ieee754dp_nanxcpt(x, "neg", x);
return x;
}
@@ -76,15 +74,12 @@ ieee754dp ieee754dp_abs(ieee754dp x)
CLEARCX;
FLUSHXDP;
+ /* Clear sign ALWAYS, irrespective of NaN */
+ DPSIGN(x) = 0;
+
if (xc == IEEE754_CLASS_SNAN) {
- SETCX(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef(), "neg");
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "abs");
}
- if (ieee754dp_isnan(x)) /* but not infinity */
- return ieee754dp_nanxcpt(x, "abs", x);
-
- /* quick fix up */
- DPSIGN(x) = 0;
return x;
}
diff --git a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c
index 770f0f4677cd..3175477d36f6 100644
--- a/arch/mips/math-emu/sp_simple.c
+++ b/arch/mips/math-emu/sp_simple.c
@@ -62,8 +62,6 @@ ieee754sp ieee754sp_neg(ieee754sp x)
return ieee754sp_nanxcpt(y, "neg");
}
- if (ieee754sp_isnan(x)) /* but not infinity */
- return ieee754sp_nanxcpt(x, "neg", x);
return x;
}
@@ -76,15 +74,12 @@ ieee754sp ieee754sp_abs(ieee754sp x)
CLEARCX;
FLUSHXSP;
+ /* Clear sign ALWAYS, irrespective of NaN */
+ SPSIGN(x) = 0;
+
if (xc == IEEE754_CLASS_SNAN) {
- SETCX(IEEE754_INVALID_OPERATION);
return ieee754sp_nanxcpt(ieee754sp_indef(), "abs");
}
- if (ieee754sp_isnan(x)) /* but not infinity */
- return ieee754sp_nanxcpt(x, "abs", x);
-
- /* quick fix up */
- SPSIGN(x) = 0;
return x;
}
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 7e48e76148aa..9367e33fbd18 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -90,6 +90,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
{
void *ret;
+ if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
+ return ret;
+
gfp = massage_gfp_flags(dev, gfp);
ret = (void *) __get_free_pages(gfp, get_order(size));
@@ -122,6 +125,10 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle)
{
unsigned long addr = (unsigned long) vaddr;
+ int order = get_order(size);
+
+ if (dma_release_from_coherent(dev, order, vaddr))
+ return;
plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 15aa1902a788..8d1f4f363049 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -27,6 +27,7 @@
#include <linux/swap.h>
#include <linux/proc_fs.h>
#include <linux/pfn.h>
+#include <linux/hardirq.h>
#include <asm/asm-offsets.h>
#include <asm/bootinfo.h>
@@ -132,7 +133,10 @@ void *kmap_coherent(struct page *page, unsigned long addr)
inc_preempt_count();
idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
#ifdef CONFIG_MIPS_MT_SMTC
- idx += FIX_N_COLOURS * smp_processor_id();
+ idx += FIX_N_COLOURS * smp_processor_id() +
+ (in_interrupt() ? (FIX_N_COLOURS * NR_CPUS) : 0);
+#else
+ idx += in_interrupt() ? FIX_N_COLOURS : 0;
#endif
vaddr = __fix_to_virt(FIX_CMAP_END - idx);
pte = mk_pte(page, PAGE_KERNEL);
diff --git a/arch/mips/mti-malta/malta-amon.c b/arch/mips/mti-malta/malta-amon.c
index df9e526312a2..469d9b0cee6d 100644
--- a/arch/mips/mti-malta/malta-amon.c
+++ b/arch/mips/mti-malta/malta-amon.c
@@ -70,11 +70,12 @@ void amon_cpu_start(int cpu,
launch->sp = sp;
launch->a0 = a0;
- /* Make sure target sees parameters before the go bit */
- smp_mb();
-
+ smp_wmb(); /* Target must see parameters before go */
launch->flags |= LAUNCH_FGO;
+ smp_wmb(); /* Target must see go before we poll */
+
while ((launch->flags & LAUNCH_FGONE) == 0)
;
+ smp_rmb(); /* Target will be updating flags soon */
pr_debug("launch: cpu%d gone!\n", cpu);
}
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index 3e0a9b35ba5c..4c3fca18a171 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -87,7 +87,7 @@ static inline int mips_pcibios_iack(void)
dummy = BONITO_PCIMAP_CFG;
iob(); /* sync */
- irq = readl((u32 *)_pcictrl_bonito_pcicfg);
+ irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg);
iob(); /* sync */
irq &= 0xff;
BONITO_PCIMAP_CFG = 0;
@@ -379,38 +379,43 @@ static msc_irqmap_t __initdata msc_eicirqmap[] = {
static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
-#if defined(CONFIG_MIPS_MT_SMP)
/*
* This GIC specific tabular array defines the association between External
* Interrupts and CPUs/Core Interrupts. The nature of the External
* Interrupts is also defined here - polarity/trigger.
*/
+
+#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
- { GIC_EXT_INTR(0), X, X, X, X, 0 },
- { GIC_EXT_INTR(1), X, X, X, X, 0 },
- { GIC_EXT_INTR(2), X, X, X, X, 0 },
- { GIC_EXT_INTR(3), 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(4), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(5), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(6), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(7), 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(8), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(9), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(10), X, X, X, X, 0 },
- { GIC_EXT_INTR(11), X, X, X, X, 0 },
- { GIC_EXT_INTR(12), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
- { GIC_EXT_INTR(15), X, X, X, X, 0 },
-/* This is the end of the general interrupts now we do IPI ones */
+ { X, X, X, X, 0 },
+ { X, X, X, X, 0 },
+ { X, X, X, X, 0 },
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { X, X, X, X, 0 },
+ { X, X, X, X, 0 },
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { X, X, X, X, 0 },
+ /* The remainder of this table is initialised by fill_ipi_map */
};
-#endif
/*
* GCMP needs to be detected before any SMP initialisation
*/
int __init gcmp_probe(unsigned long addr, unsigned long size)
{
+ if (mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) {
+ gcmp_present = 0;
+ return gcmp_present;
+ }
+
if (gcmp_present >= 0)
return gcmp_present;
@@ -419,20 +424,35 @@ int __init gcmp_probe(unsigned long addr, unsigned long size)
gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR;
if (gcmp_present)
- printk(KERN_DEBUG "GCMP present\n");
+ pr_debug("GCMP present\n");
return gcmp_present;
}
+/* Return the number of IOCU's present */
+int __init gcmp_niocu(void)
+{
+ return gcmp_present ?
+ (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF :
+ 0;
+}
+
+/* Set GCMP region attributes */
+void __init gcmp_setregion(int region, unsigned long base,
+ unsigned long mask, int type)
+{
+ GCMPGCBn(CMxBASE, region) = base;
+ GCMPGCBn(CMxMASK, region) = mask | type;
+}
+
#if defined(CONFIG_MIPS_MT_SMP)
static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
{
int intr = baseintr + cpu;
- gic_intr_map[intr].intrnum = GIC_EXT_INTR(intr);
gic_intr_map[intr].cpunum = cpu;
gic_intr_map[intr].pin = cpupin;
gic_intr_map[intr].polarity = GIC_POL_POS;
gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
- gic_intr_map[intr].ipiflag = 1;
+ gic_intr_map[intr].flags = GIC_FLAG_IPI;
ipi_map[cpu] |= (1 << (cpupin + 2));
}
@@ -447,6 +467,12 @@ static void __init fill_ipi_map(void)
}
#endif
+void __init arch_init_ipiirq(int irq, struct irqaction *action)
+{
+ setup_irq(irq, action);
+ set_irq_handler(irq, handle_percpu_irq);
+}
+
void __init arch_init_irq(void)
{
init_i8259_irqs();
@@ -458,12 +484,17 @@ void __init arch_init_irq(void)
GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK;
gic_present = 1;
} else {
- _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ);
- gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) &
- MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF;
+ if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) {
+ _msc01_biu_base = (unsigned long)
+ ioremap_nocache(MSC01_BIU_REG_BASE,
+ MSC01_BIU_ADDRSPACE_SZ);
+ gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) &
+ MSC01_SC_CFG_GICPRES_MSK) >>
+ MSC01_SC_CFG_GICPRES_SHF;
+ }
}
if (gic_present)
- printk(KERN_DEBUG "GIC present\n");
+ pr_debug("GIC present\n");
switch (mips_revision_sconid) {
case MIPS_REVISION_SCON_SOCIT:
@@ -526,16 +557,16 @@ void __init arch_init_irq(void)
&corehi_irqaction);
}
-#if defined(CONFIG_MIPS_MT_SMP)
if (gic_present) {
/* FIXME */
int i;
-
+#if defined(CONFIG_MIPS_MT_SMP)
gic_call_int_base = GIC_NUM_INTRS - NR_CPUS;
gic_resched_int_base = gic_call_int_base - NR_CPUS;
-
fill_ipi_map();
- gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
+#endif
+ gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
+ ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
if (!gcmp_present) {
/* Enable the GIC */
i = REG(_msc01_biu_base, MSC01_SC_CFG);
@@ -543,7 +574,7 @@ void __init arch_init_irq(void)
(i | (0x1 << MSC01_SC_CFG_GICENA_SHF));
pr_debug("GIC Enabled\n");
}
-
+#if defined(CONFIG_MIPS_MT_SMP)
/* set up ipi interrupts */
if (cpu_has_vint) {
set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch);
@@ -556,16 +587,14 @@ void __init arch_init_irq(void)
write_c0_status(0x1100dc00);
printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status());
for (i = 0; i < NR_CPUS; i++) {
- setup_irq(MIPS_GIC_IRQ_BASE +
- GIC_RESCHED_INT(i), &irq_resched);
- setup_irq(MIPS_GIC_IRQ_BASE +
- GIC_CALL_INT(i), &irq_call);
- set_irq_handler(MIPS_GIC_IRQ_BASE +
- GIC_RESCHED_INT(i), handle_percpu_irq);
- set_irq_handler(MIPS_GIC_IRQ_BASE +
- GIC_CALL_INT(i), handle_percpu_irq);
+ arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
+ GIC_RESCHED_INT(i), &irq_resched);
+ arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
+ GIC_CALL_INT(i), &irq_call);
}
+#endif
} else {
+#if defined(CONFIG_MIPS_MT_SMP)
/* set up ipi interrupts */
if (cpu_has_veic) {
set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch);
@@ -580,14 +609,10 @@ void __init arch_init_irq(void)
cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
}
-
- setup_irq(cpu_ipi_resched_irq, &irq_resched);
- setup_irq(cpu_ipi_call_irq, &irq_call);
-
- set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
- set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
- }
+ arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched);
+ arch_init_ipiirq(cpu_ipi_call_irq, &irq_call);
#endif
+ }
}
void malta_be_init(void)
diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
index 61888ff72c87..9035c64bc5ed 100644
--- a/arch/mips/mti-malta/malta-memory.c
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -54,7 +54,8 @@ static struct prom_pmemblock * __init prom_getmdesc(void)
{
char *memsize_str;
unsigned int memsize;
- char cmdline[CL_SIZE], *ptr;
+ char *ptr;
+ static char cmdline[CL_SIZE] __initdata;
/* otherwise look in the environment */
memsize_str = prom_getenv("memsize");
diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c
index b9743190609a..2fbfa1a8c3a9 100644
--- a/arch/mips/mti-malta/malta-pci.c
+++ b/arch/mips/mti-malta/malta-pci.c
@@ -27,7 +27,7 @@
#include <linux/init.h>
#include <asm/gt64120.h>
-
+#include <asm/gcmpregs.h>
#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/bonito64.h>
#include <asm/mips-boards/msc01_pci.h>
@@ -201,7 +201,11 @@ void __init mips_pcibios_init(void)
msc_mem_resource.start = start & mask;
msc_mem_resource.end = (start & mask) | ~mask;
msc_controller.mem_offset = (start & mask) - (map & mask);
-
+#ifdef CONFIG_MIPS_CMP
+ if (gcmp_niocu())
+ gcmp_setregion(0, start, mask,
+ GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
+#endif
MSC_READ(MSC01_PCI_SC2PIOBASL, start);
MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
@@ -209,7 +213,11 @@ void __init mips_pcibios_init(void)
msc_io_resource.end = (map & mask) | ~mask;
msc_controller.io_offset = 0;
ioport_resource.end = ~mask;
-
+#ifdef CONFIG_MIPS_CMP
+ if (gcmp_niocu())
+ gcmp_setregion(1, start, mask,
+ GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
+#endif
/* If ranges overlap I/O takes precedence. */
start = start & mask;
end = start | ~mask;
@@ -241,3 +249,16 @@ void __init mips_pcibios_init(void)
register_pci_controller(controller);
}
+
+/* Enable PCI 2.1 compatibility in PIIX4 */
+static void __init quirk_dlcsetup(struct pci_dev *dev)
+{
+ u8 odlc, ndlc;
+ (void) pci_read_config_byte(dev, 0x82, &odlc);
+ /* Enable passive releases and delayed transaction */
+ ndlc = odlc | 7;
+ (void) pci_write_config_byte(dev, 0x82, ndlc);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
+ quirk_dlcsetup);
diff --git a/arch/mips/nxp/pnx8550/common/int.c b/arch/mips/nxp/pnx8550/common/int.c
index f080f114a1bf..7aca7d5375e5 100644
--- a/arch/mips/nxp/pnx8550/common/int.c
+++ b/arch/mips/nxp/pnx8550/common/int.c
@@ -172,7 +172,7 @@ static struct irqaction gic_action = {
static struct irqaction timer_action = {
.handler = no_action,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
.name = "Timer",
};
diff --git a/arch/mips/nxp/pnx8550/common/time.c b/arch/mips/nxp/pnx8550/common/time.c
index 18b192784877..8836c6203df0 100644
--- a/arch/mips/nxp/pnx8550/common/time.c
+++ b/arch/mips/nxp/pnx8550/common/time.c
@@ -59,7 +59,7 @@ static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id)
static struct irqaction pnx8xxx_timer_irq = {
.handler = pnx8xxx_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "pnx8xxx_timer",
};
@@ -72,7 +72,7 @@ static irqreturn_t monotonic_interrupt(int irq, void *dev_id)
static struct irqaction monotonic_irqaction = {
.handler = monotonic_interrupt,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
.name = "Monotonic timer",
};
diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c
index deed1d5d4982..575cd1473475 100644
--- a/arch/mips/oprofile/op_model_loongson2.c
+++ b/arch/mips/oprofile/op_model_loongson2.c
@@ -22,7 +22,7 @@
* otherwise, the oprofile tool will not recognize this and complain about
* "cpu_type 'unset' is not valid".
*/
-#define LOONGSON2_CPU_TYPE "mips/godson2"
+#define LOONGSON2_CPU_TYPE "mips/loongson2"
#define LOONGSON2_COUNTER1_EVENT(event) ((event & 0x0f) << 5)
#define LOONGSON2_COUNTER2_EVENT(event) ((event & 0x0f) << 9)
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index 9f40e1ff9b4f..041fc1afc3f4 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -110,7 +110,6 @@ static struct korina_device korina_dev0_data = {
static struct platform_device korina_dev0 = {
.id = -1,
.name = "korina",
- .dev.driver_data = &korina_dev0_data,
.resource = korina_dev0_res,
.num_resources = ARRAY_SIZE(korina_dev0_res),
};
@@ -332,6 +331,8 @@ static int __init plat_setup_devices(void)
/* set the uart clock to the current cpu frequency */
rb532_uart_res[0].uartclk = idt_cpu_freq;
+ dev_set_drvdata(&korina_dev0.dev, &korina_dev0_data);
+
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
}
diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c
index 46ca24dbcc2d..ad5bd1097974 100644
--- a/arch/mips/rb532/prom.c
+++ b/arch/mips/rb532/prom.c
@@ -69,7 +69,7 @@ static inline unsigned long tag2ul(char *arg, const char *tag)
void __init prom_setup_cmdline(void)
{
- char cmd_line[CL_SIZE];
+ static char cmd_line[CL_SIZE] __initdata;
char *cp, *board;
int prom_argc;
char **prom_argv, **prom_envp;
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index 6d0e59ffba2e..d6802d6d1f82 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -105,7 +105,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
struct irqaction hub_rt_irqaction = {
.handler = hub_rt_counter_handler,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "hub-rt",
};
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index 62df6a598e0a..f3b60e671207 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -67,7 +67,7 @@ static irqreturn_t a20r_interrupt(int irq, void *dev_id)
static struct irqaction a20r_irqaction = {
.handler = a20r_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "a20r-timer",
};
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index c860810722c0..d66802edebb2 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -85,7 +85,7 @@ int txx9_ccfg_toeon __initdata = 1;
struct clk *clk_get(struct device *dev, const char *id)
{
if (!strcmp(id, "spi-baseclk"))
- return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 4);
+ return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 2);
if (!strcmp(id, "imbus_clk"))
return (struct clk *)((unsigned long)txx9_gbus_clock / 2);
return ERR_PTR(-ENOENT);
@@ -160,7 +160,7 @@ static void __init prom_init_cmdline(void)
int argc;
int *argv32;
int i; /* Always ignore the "-c" at argv[0] */
- char builtin[CL_SIZE];
+ static char builtin[CL_SIZE] __initdata;
if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) {
/*
@@ -315,7 +315,7 @@ static inline void txx9_cache_fixup(void)
static void __init preprocess_cmdline(void)
{
- char cmdline[CL_SIZE];
+ static char cmdline[CL_SIZE] __initdata;
char *s;
strcpy(cmdline, arcs_cmdline);
@@ -817,7 +817,8 @@ void __init txx9_iocled_init(unsigned long baseaddr,
out_pdev:
platform_device_put(pdev);
out_gpio:
- gpio_remove(&iocled->chip);
+ if (gpiochip_remove(&iocled->chip))
+ return;
out_unmap:
iounmap(iocled->mmioaddr);
out_free:
diff --git a/arch/parisc/include/asm/fcntl.h b/arch/parisc/include/asm/fcntl.h
index 5f39d5597ced..1e1c824764ee 100644
--- a/arch/parisc/include/asm/fcntl.h
+++ b/arch/parisc/include/asm/fcntl.h
@@ -28,8 +28,6 @@
#define F_SETOWN 12 /* for sockets. */
#define F_SETSIG 13 /* for sockets. */
#define F_GETSIG 14 /* for sockets. */
-#define F_GETOWN_EX 15
-#define F_SETOWN_EX 16
/* for posix fcntl() and lockf() */
#define F_RDLCK 01
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 69dad5a850a8..a36799e85693 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -28,7 +28,7 @@
#define dbg(x...)
#endif
-#define KERNEL_START (KERNEL_BINARY_TEXT_START - 0x1000)
+#define KERNEL_START (KERNEL_BINARY_TEXT_START)
extern struct unwind_table_entry __start___unwind[];
extern struct unwind_table_entry __stop___unwind[];
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index fda4baa059b5..9dab4a4e09f7 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -78,9 +78,6 @@ SECTIONS
*/
. = ALIGN(PAGE_SIZE);
data_start = .;
- EXCEPTION_TABLE(16)
-
- NOTES
/* unwind info */
.PARISC.unwind : {
@@ -89,6 +86,9 @@ SECTIONS
__stop___unwind = .;
}
+ EXCEPTION_TABLE(16)
+ NOTES
+
/* Data */
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 10a0a5488a44..2ba14e77296c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -414,6 +414,10 @@ config ARCH_SPARSEMEM_DEFAULT
config ARCH_POPULATES_NODE_MAP
def_bool y
+config SYS_SUPPORTS_HUGETLBFS
+ def_bool y
+ depends on PPC_BOOK3S_64
+
source "mm/Kconfig"
config ARCH_MEMORY_PROBE
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 3b1005185390..bf3382f1904d 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -46,7 +46,7 @@ config DEBUG_STACK_USAGE
config HCALL_STATS
bool "Hypervisor call instrumentation"
- depends on PPC_PSERIES && DEBUG_FS
+ depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS
help
Adds code to keep track of the number of hypervisor calls made and
the amount of time spent in hypervisor calls. Wall time spent in
diff --git a/arch/powerpc/boot/addRamDisk.c b/arch/powerpc/boot/addRamDisk.c
index c02a99952be7..893f446cbd22 100644
--- a/arch/powerpc/boot/addRamDisk.c
+++ b/arch/powerpc/boot/addRamDisk.c
@@ -58,7 +58,7 @@ static int check_elf64(void *p, int size, struct addr_range *r)
return 64;
}
-void get4k(FILE *file, char *buf )
+static void get4k(FILE *file, char *buf )
{
unsigned j;
unsigned num = fread(buf, 1, 4096, file);
@@ -66,12 +66,12 @@ void get4k(FILE *file, char *buf )
buf[j] = 0;
}
-void put4k(FILE *file, char *buf )
+static void put4k(FILE *file, char *buf )
{
fwrite(buf, 1, 4096, file);
}
-void death(const char *msg, FILE *fdesc, const char *fname)
+static void death(const char *msg, FILE *fdesc, const char *fname)
{
fprintf(stderr, msg);
fclose(fdesc);
diff --git a/arch/powerpc/boot/dts/cm5200.dts b/arch/powerpc/boot/dts/cm5200.dts
index cee8080aa245..dd3860846f15 100644
--- a/arch/powerpc/boot/dts/cm5200.dts
+++ b/arch/powerpc/boot/dts/cm5200.dts
@@ -210,7 +210,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- fsl5200-clocking;
};
sram@8000 {
diff --git a/arch/powerpc/boot/dts/digsy_mtc.dts b/arch/powerpc/boot/dts/digsy_mtc.dts
index 4c36186ef946..8e9be6bfe23e 100644
--- a/arch/powerpc/boot/dts/digsy_mtc.dts
+++ b/arch/powerpc/boot/dts/digsy_mtc.dts
@@ -199,7 +199,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
- fsl5200-clocking;
rtc@50 {
compatible = "at,24c08";
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index de30b3f9eb26..82ff2b13bc37 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -247,7 +247,6 @@
compatible = "fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
- fsl5200-clocking;
};
i2c@3d40 {
@@ -256,7 +255,6 @@
compatible = "fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- fsl5200-clocking;
};
sram@8000 {
compatible = "fsl,mpc5200-sram";
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index d13cb11ce623..e45a63be3a86 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -251,7 +251,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
- fsl5200-clocking;
};
i2c@3d40 {
@@ -260,7 +259,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- fsl5200-clocking;
};
sram@8000 {
diff --git a/arch/powerpc/boot/dts/media5200.dts b/arch/powerpc/boot/dts/media5200.dts
index e297d8b41875..0c3902bc5b6a 100644
--- a/arch/powerpc/boot/dts/media5200.dts
+++ b/arch/powerpc/boot/dts/media5200.dts
@@ -223,7 +223,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
- fsl5200-clocking;
};
i2c@3d40 {
@@ -232,7 +231,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- fsl5200-clocking;
};
sram@8000 {
diff --git a/arch/powerpc/boot/dts/motionpro.dts b/arch/powerpc/boot/dts/motionpro.dts
index 7be8ca038676..6ca4fc144a33 100644
--- a/arch/powerpc/boot/dts/motionpro.dts
+++ b/arch/powerpc/boot/dts/motionpro.dts
@@ -222,7 +222,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- fsl5200-clocking;
rtc@68 {
compatible = "dallas,ds1339";
diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts
index c2b8dbfab79e..c353dac33416 100644
--- a/arch/powerpc/boot/dts/mpc5121ads.dts
+++ b/arch/powerpc/boot/dts/mpc5121ads.dts
@@ -209,7 +209,6 @@
reg = <0x1700 0x20>;
interrupts = <9 0x8>;
interrupt-parent = < &ipic >;
- fsl5200-clocking;
};
i2c@1720 {
@@ -220,7 +219,6 @@
reg = <0x1720 0x20>;
interrupts = <10 0x8>;
interrupt-parent = < &ipic >;
- fsl5200-clocking;
};
i2c@1740 {
@@ -231,7 +229,6 @@
reg = <0x1740 0x20>;
interrupts = <11 0x8>;
interrupt-parent = < &ipic >;
- fsl5200-clocking;
};
i2ccontrol@1760 {
diff --git a/arch/powerpc/boot/dts/mpc8377_wlan.dts b/arch/powerpc/boot/dts/mpc8377_wlan.dts
index 9a603695723b..9ea783056969 100644
--- a/arch/powerpc/boot/dts/mpc8377_wlan.dts
+++ b/arch/powerpc/boot/dts/mpc8377_wlan.dts
@@ -67,7 +67,7 @@
device-width = <1>;
partition@0 {
- reg = <0 0x8000>;
+ reg = <0 0x80000>;
label = "u-boot";
read-only;
};
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
index 06332d61830a..1e3ec8f059bf 100644
--- a/arch/powerpc/boot/dts/mpc8569mds.dts
+++ b/arch/powerpc/boot/dts/mpc8569mds.dts
@@ -487,8 +487,8 @@
&qe_pio_f 5 0 /* USBTN */
&qe_pio_f 6 0 /* USBRP */
&qe_pio_f 8 0 /* USBRN */
- &bcsr17 6 0 /* SPEED */
- &bcsr17 5 1>; /* POWER */
+ &bcsr17 1 0 /* SPEED */
+ &bcsr17 2 0>; /* POWER */
};
enet0: ucc@2000 {
diff --git a/arch/powerpc/boot/dts/mucmc52.dts b/arch/powerpc/boot/dts/mucmc52.dts
new file mode 100644
index 000000000000..b72a7581d798
--- /dev/null
+++ b/arch/powerpc/boot/dts/mucmc52.dts
@@ -0,0 +1,332 @@
+/*
+ * Manroland mucmc52 board Device Tree Source
+ *
+ * Copyright (C) 2009 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ * Copyright 2006-2007 Secret Lab Technologies Ltd.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "manroland,mucmc52";
+ compatible = "manroland,mucmc52";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,5200@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>; // from bootloader
+ bus-frequency = <0>; // from bootloader
+ clock-frequency = <0>; // from bootloader
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x04000000>; // 64MB
+ };
+
+ soc5200@f0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc5200b-immr";
+ ranges = <0 0xf0000000 0x0000c000>;
+ reg = <0xf0000000 0x00000100>;
+ bus-frequency = <0>; // from bootloader
+ system-frequency = <0>; // from bootloader
+
+ cdm@200 {
+ compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+ reg = <0x200 0x38>;
+ };
+
+ mpc5200_pic: interrupt-controller@500 {
+ // 5200 interrupts are encoded into two levels;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+ reg = <0x500 0x80>;
+ };
+
+ gpt0: timer@600 { // GPT 0 in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x600 0x10>;
+ interrupts = <1 9 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt1: timer@610 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x610 0x10>;
+ interrupts = <1 10 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt2: timer@620 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x620 0x10>;
+ interrupts = <1 11 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt3: timer@630 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x630 0x10>;
+ interrupts = <1 12 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio_simple: gpio@b00 {
+ compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+ reg = <0xb00 0x40>;
+ interrupts = <1 7 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio_wkup: gpio@c00 {
+ compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+ reg = <0xc00 0x40>;
+ interrupts = <1 8 0 0 3 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ dma-controller@1200 {
+ compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+ reg = <0x1200 0x80>;
+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
+ 3 4 0 3 5 0 3 6 0 3 7 0
+ 3 8 0 3 9 0 3 10 0 3 11 0
+ 3 12 0 3 13 0 3 14 0 3 15 0>;
+ };
+
+ xlb@1f00 {
+ compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+ reg = <0x1f00 0x100>;
+ };
+
+ serial@2000 { /* PSC1 in UART mode */
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ reg = <0x2000 0x100>;
+ interrupts = <2 1 0>;
+ };
+
+ serial@2200 { /* PSC2 in UART mode */
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ reg = <0x2200 0x100>;
+ interrupts = <2 2 0>;
+ };
+
+ serial@2c00 { /* PSC6 in UART mode */
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ reg = <0x2c00 0x100>;
+ interrupts = <2 4 0>;
+ };
+
+ ethernet@3000 {
+ compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+ reg = <0x3000 0x400>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <2 5 0>;
+ phy-handle = <&phy0>;
+ };
+
+ mdio@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
+ interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
+
+ phy0: ethernet-phy@0 {
+ compatible = "intel,lxt971";
+ reg = <0>;
+ };
+ };
+
+ ata@3a00 {
+ compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+ reg = <0x3a00 0x100>;
+ interrupts = <2 7 0>;
+ };
+
+ i2c@3d40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d40 0x40>;
+ interrupts = <2 16 0>;
+ hwmon@2c {
+ compatible = "ad,adm9240";
+ reg = <0x2c>;
+ };
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ sram@8000 {
+ compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+ reg = <0x8000 0x4000>;
+ };
+ };
+
+ pci@f0000d00 {
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
+ reg = <0xf0000d00 0x100>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x10 */
+ 0x8000 0 0 1 &mpc5200_pic 0 3 3
+ 0x8000 0 0 2 &mpc5200_pic 0 3 3
+ 0x8000 0 0 3 &mpc5200_pic 0 2 3
+ 0x8000 0 0 4 &mpc5200_pic 0 1 3
+ >;
+ clock-frequency = <0>; // From boot loader
+ interrupts = <2 8 0 2 9 0 2 10 0>;
+ bus-range = <0 0>;
+ ranges = <0x42000000 0 0x60000000 0x60000000 0 0x10000000
+ 0x02000000 0 0x90000000 0x90000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
+ };
+
+ localbus {
+ compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
+
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ ranges = <0 0 0xff800000 0x00800000
+ 1 0 0x80000000 0x00800000
+ 3 0 0x80000000 0x00800000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x00800000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+ partition@0 {
+ label = "DTS";
+ reg = <0x0 0x00100000>;
+ };
+ partition@100000 {
+ label = "Kernel";
+ reg = <0x100000 0x00200000>;
+ };
+ partition@300000 {
+ label = "RootFS";
+ reg = <0x00300000 0x00200000>;
+ };
+ partition@500000 {
+ label = "user";
+ reg = <0x00500000 0x00200000>;
+ };
+ partition@700000 {
+ label = "U-Boot";
+ reg = <0x00700000 0x00040000>;
+ };
+ partition@740000 {
+ label = "Env";
+ reg = <0x00740000 0x00020000>;
+ };
+ partition@760000 {
+ label = "red. Env";
+ reg = <0x00760000 0x00020000>;
+ };
+ partition@780000 {
+ label = "reserve";
+ reg = <0x00780000 0x00080000>;
+ };
+ };
+
+ simple100: gpio-controller-100@3,600100 {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x00600100 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ simple104: gpio-controller-104@3,600104 {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x00600104 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ simple200: gpio-controller-200@3,600200 {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x00600200 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ simple201: gpio-controller-201@3,600201 {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x00600201 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ simple202: gpio-controller-202@3,600202 {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x00600202 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ simple203: gpio-controller-203@3,600203 {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x00600203 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ simple204: gpio-controller-204@3,600204 {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x00600204 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ simple206: gpio-controller-206@3,600206 {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x00600206 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ simple207: gpio-controller-207@3,600207 {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x00600207 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ simple20f: gpio-controller-20f@3,60020f {
+ compatible = "manroland,mucmc52-aux-gpio";
+ reg = <3 0x0060020f 0x1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ };
+};
diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts
index 30bfdc04c6df..8a4ec30b21ae 100644
--- a/arch/powerpc/boot/dts/pcm030.dts
+++ b/arch/powerpc/boot/dts/pcm030.dts
@@ -244,7 +244,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
- fsl5200-clocking;
};
i2c@3d40 {
@@ -253,7 +252,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- fsl5200-clocking;
rtc@51 {
compatible = "nxp,pcf8563";
reg = <0x51>;
diff --git a/arch/powerpc/boot/dts/pcm032.dts b/arch/powerpc/boot/dts/pcm032.dts
index 030042678392..85d857a5d46e 100644
--- a/arch/powerpc/boot/dts/pcm032.dts
+++ b/arch/powerpc/boot/dts/pcm032.dts
@@ -244,7 +244,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
- fsl5200-clocking;
};
i2c@3d40 {
@@ -253,7 +252,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- fsl5200-clocking;
rtc@51 {
compatible = "nxp,pcf8563";
reg = <0x51>;
diff --git a/arch/powerpc/boot/dts/sbc8548.dts b/arch/powerpc/boot/dts/sbc8548.dts
index 9eefe00ed253..94a332251710 100644
--- a/arch/powerpc/boot/dts/sbc8548.dts
+++ b/arch/powerpc/boot/dts/sbc8548.dts
@@ -26,8 +26,7 @@
serial0 = &serial0;
serial1 = &serial1;
pci0 = &pci0;
- /* pci1 doesn't have a corresponding physical connector */
- pci2 = &pci2;
+ pci1 = &pci1;
};
cpus {
@@ -381,7 +380,7 @@
bus-range = <0 0>;
ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x10000000
0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00800000>;
- clock-frequency = <66666666>;
+ clock-frequency = <66000000>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
@@ -390,7 +389,7 @@
device_type = "pci";
};
- pci2: pcie@e000a000 {
+ pci1: pcie@e000a000 {
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
@@ -403,9 +402,9 @@
interrupt-parent = <&mpic>;
interrupts = <0x1a 0x2>;
bus-range = <0x0 0xff>;
- ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x08000000>;
- clock-frequency = <33333333>;
+ ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0xe2800000 0x0 0x08000000>;
+ clock-frequency = <33000000>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
@@ -419,11 +418,11 @@
device_type = "pci";
ranges = <0x02000000 0x0 0xa0000000
0x02000000 0x0 0xa0000000
- 0x0 0x20000000
+ 0x0 0x10000000
0x01000000 0x0 0x00000000
0x01000000 0x0 0x00000000
- 0x0 0x08000000>;
+ 0x0 0x00800000>;
};
};
};
diff --git a/arch/powerpc/boot/dts/tqm5200.dts b/arch/powerpc/boot/dts/tqm5200.dts
index c9590b58b7b0..1db07f6cf133 100644
--- a/arch/powerpc/boot/dts/tqm5200.dts
+++ b/arch/powerpc/boot/dts/tqm5200.dts
@@ -160,7 +160,6 @@
compatible = "fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- fsl5200-clocking;
rtc@68 {
compatible = "dallas,ds1307";
diff --git a/arch/powerpc/boot/dts/uc101.dts b/arch/powerpc/boot/dts/uc101.dts
new file mode 100644
index 000000000000..019264c62904
--- /dev/null
+++ b/arch/powerpc/boot/dts/uc101.dts
@@ -0,0 +1,284 @@
+/*
+ * Manroland uc101 board Device Tree Source
+ *
+ * Copyright (C) 2009 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ * Copyright 2006-2007 Secret Lab Technologies Ltd.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "manroland,uc101";
+ compatible = "manroland,uc101";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,5200@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>; // from bootloader
+ bus-frequency = <0>; // from bootloader
+ clock-frequency = <0>; // from bootloader
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x04000000>; // 64MB
+ };
+
+ soc5200@f0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc5200b-immr";
+ ranges = <0 0xf0000000 0x0000c000>;
+ reg = <0xf0000000 0x00000100>;
+ bus-frequency = <0>; // from bootloader
+ system-frequency = <0>; // from bootloader
+
+ cdm@200 {
+ compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+ reg = <0x200 0x38>;
+ };
+
+ mpc5200_pic: interrupt-controller@500 {
+ // 5200 interrupts are encoded into two levels;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+ reg = <0x500 0x80>;
+ };
+
+ gpt0: timer@600 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x600 0x10>;
+ interrupts = <1 9 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt1: timer@610 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x610 0x10>;
+ interrupts = <1 10 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt2: timer@620 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x620 0x10>;
+ interrupts = <1 11 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt3: timer@630 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x630 0x10>;
+ interrupts = <1 12 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt4: timer@640 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x640 0x10>;
+ interrupts = <1 13 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt5: timer@650 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x650 0x10>;
+ interrupts = <1 14 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt6: timer@660 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x660 0x10>;
+ interrupts = <1 15 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt7: timer@670 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x670 0x10>;
+ interrupts = <1 16 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio_simple: gpio@b00 {
+ compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+ reg = <0xb00 0x40>;
+ interrupts = <1 7 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio_wkup: gpio@c00 {
+ compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+ reg = <0xc00 0x40>;
+ interrupts = <1 8 0 0 3 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ dma-controller@1200 {
+ compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+ reg = <0x1200 0x80>;
+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
+ 3 4 0 3 5 0 3 6 0 3 7 0
+ 3 8 0 3 9 0 3 10 0 3 11 0
+ 3 12 0 3 13 0 3 14 0 3 15 0>;
+ };
+
+ xlb@1f00 {
+ compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+ reg = <0x1f00 0x100>;
+ };
+
+ serial@2000 { /* PSC1 in UART mode */
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ reg = <0x2000 0x100>;
+ interrupts = <2 1 0>;
+ };
+
+ serial@2200 { /* PSC2 in UART mode */
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ reg = <0x2200 0x100>;
+ interrupts = <2 2 0>;
+ };
+
+ serial@2c00 { /* PSC6 in UART mode */
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ reg = <0x2c00 0x100>;
+ interrupts = <2 4 0>;
+ };
+
+ ethernet@3000 {
+ compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+ reg = <0x3000 0x400>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <2 5 0>;
+ phy-handle = <&phy0>;
+ };
+
+ mdio@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
+ interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
+
+ phy0: ethernet-phy@0 {
+ compatible = "intel,lxt971";
+ reg = <0>;
+ };
+ };
+
+ ata@3a00 {
+ compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+ reg = <0x3a00 0x100>;
+ interrupts = <2 7 0>;
+ };
+
+ i2c@3d40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d40 0x40>;
+ interrupts = <2 16 0>;
+ fsl,preserve-clocking;
+ clock-frequency = <400000>;
+
+ hwmon@2c {
+ compatible = "ad,adm9240";
+ reg = <0x2c>;
+ };
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ sram@8000 {
+ compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+ reg = <0x8000 0x4000>;
+ };
+ };
+
+ localbus {
+ compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
+
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ ranges = <0 0 0xff800000 0x00800000
+ 1 0 0x80000000 0x00800000
+ 3 0 0x80000000 0x00800000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x00800000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+
+ partition@0 {
+ label = "DTS";
+ reg = <0x0 0x00100000>;
+ };
+ partition@100000 {
+ label = "Kernel";
+ reg = <0x100000 0x00200000>;
+ };
+ partition@300000 {
+ label = "RootFS";
+ reg = <0x00300000 0x00200000>;
+ };
+ partition@500000 {
+ label = "user";
+ reg = <0x00500000 0x00200000>;
+ };
+ partition@700000 {
+ label = "U-Boot";
+ reg = <0x00700000 0x00040000>;
+ };
+ partition@740000 {
+ label = "Env";
+ reg = <0x00740000 0x00010000>;
+ };
+ partition@750000 {
+ label = "red. Env";
+ reg = <0x00750000 0x00010000>;
+ };
+ partition@760000 {
+ label = "reserve";
+ reg = <0x00760000 0x000a0000>;
+ };
+ };
+
+ };
+};
diff --git a/arch/powerpc/configs/52xx/cm5200_defconfig b/arch/powerpc/configs/52xx/cm5200_defconfig
index 3838b77b8116..0396ce7bffc6 100644
--- a/arch/powerpc/configs/52xx/cm5200_defconfig
+++ b/arch/powerpc/configs/52xx/cm5200_defconfig
@@ -1,25 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:47:44 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:22 2009
#
# CONFIG_PPC64 is not set
#
# Processor support
#
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
CONFIG_PPC_FPU=y
# CONFIG_ALTIVEC is not set
CONFIG_PPC_STD_MMU=y
CONFIG_PPC_STD_MMU_32=y
# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
# CONFIG_SMP is not set
CONFIG_PPC32=y
CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=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
@@ -52,11 +56,13 @@ CONFIG_OF=y
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
CONFIG_DEFAULT_UIMAGE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -77,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -105,7 +112,6 @@ CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -118,6 +124,13 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
CONFIG_COMPAT_BRK=y
@@ -125,14 +138,19 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
@@ -140,7 +158,7 @@ CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -219,11 +237,13 @@ CONFIG_BINFMT_ELF=y
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -239,9 +259,10 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
# CONFIG_PPC_64K_PAGES is not set
@@ -252,6 +273,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_EXTRA_TARGETS=""
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_RUNTIME is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y
@@ -328,6 +350,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -342,6 +365,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -367,6 +391,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -457,6 +482,7 @@ CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_UBI is not set
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
@@ -495,10 +521,6 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
@@ -519,7 +541,6 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_MD is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -558,14 +579,14 @@ CONFIG_NET_ETHERNET=y
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
CONFIG_FEC_MPC52xx=y
CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -636,6 +657,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -646,6 +668,7 @@ CONFIG_I2C_HELPER_AUTO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
+# CONFIG_I2C_DESIGNWARE is not set
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
@@ -666,23 +689,23 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -713,25 +736,12 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -775,11 +785,12 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_SOC=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
# CONFIG_USB_OHCI_LITTLE_ENDIAN is not set
@@ -866,6 +877,10 @@ CONFIG_USB_STORAGE=y
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -885,10 +900,13 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -959,12 +977,12 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_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=y
+# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
@@ -1064,6 +1082,7 @@ CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
#
# Kernel hacking
@@ -1073,6 +1092,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1090,10 +1110,14 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK 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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1105,11 +1129,12 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -1118,23 +1143,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1159,7 +1186,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1200,11 +1226,13 @@ CONFIG_CRYPTO_PCBC=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/52xx/lite5200b_defconfig b/arch/powerpc/configs/52xx/lite5200b_defconfig
index 29b0f34488f5..f5c07fd72239 100644
--- a/arch/powerpc/configs/52xx/lite5200b_defconfig
+++ b/arch/powerpc/configs/52xx/lite5200b_defconfig
@@ -1,25 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:48:04 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:24 2009
#
# CONFIG_PPC64 is not set
#
# Processor support
#
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
CONFIG_PPC_FPU=y
# CONFIG_ALTIVEC is not set
CONFIG_PPC_STD_MMU=y
CONFIG_PPC_STD_MMU_32=y
# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
# CONFIG_SMP is not set
CONFIG_PPC32=y
CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=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
@@ -52,12 +56,14 @@ CONFIG_OF=y
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
CONFIG_DEFAULT_UIMAGE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -78,11 +84,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -106,7 +113,6 @@ CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -119,6 +125,13 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
@@ -127,14 +140,19 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
@@ -147,7 +165,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -228,11 +246,13 @@ CONFIG_BINFMT_ELF=y
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -248,9 +268,10 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
# CONFIG_PPC_64K_PAGES is not set
@@ -264,6 +285,7 @@ CONFIG_PM=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y
@@ -348,6 +370,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -362,6 +385,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -387,6 +411,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -397,6 +422,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_MTD is not set
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
@@ -431,7 +457,9 @@ CONFIG_MISC_DEVICES=y
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -454,10 +482,6 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_BLK_DEV_SR 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 is not set
# CONFIG_SCSI_LOGGING is not set
@@ -475,6 +499,8 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -483,6 +509,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
@@ -502,7 +529,6 @@ 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
@@ -514,11 +540,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -540,6 +569,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -568,6 +598,7 @@ CONFIG_PATA_MPC52xx=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -586,14 +617,17 @@ CONFIG_PATA_MPC52xx=y
#
#
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
#
# 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_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -640,9 +674,12 @@ CONFIG_NET_ETHERNET=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
CONFIG_FEC_MPC52xx=y
CONFIG_FEC_MPC52xx_MDIO=y
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -661,6 +698,8 @@ CONFIG_NETDEV_1000=y
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
@@ -686,10 +725,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -759,6 +795,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -787,6 +824,7 @@ CONFIG_I2C_HELPER_AUTO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
+# CONFIG_I2C_DESIGNWARE is not set
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
@@ -812,23 +850,23 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -847,30 +885,18 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -913,6 +939,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -932,10 +962,13 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -992,12 +1025,12 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_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=y
+# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
@@ -1041,6 +1074,7 @@ CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
#
# Kernel hacking
@@ -1050,6 +1084,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1067,10 +1102,14 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK 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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1082,11 +1121,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -1095,23 +1135,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1136,7 +1178,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1178,11 +1219,13 @@ CONFIG_CRYPTO_CBC=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig
index 07b6b266ea95..4f77a1bdc8f9 100644
--- a/arch/powerpc/configs/52xx/motionpro_defconfig
+++ b/arch/powerpc/configs/52xx/motionpro_defconfig
@@ -1,25 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:48:22 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:22 2009
#
# CONFIG_PPC64 is not set
#
# Processor support
#
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
CONFIG_PPC_FPU=y
# CONFIG_ALTIVEC is not set
CONFIG_PPC_STD_MMU=y
CONFIG_PPC_STD_MMU_32=y
# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
# CONFIG_SMP is not set
CONFIG_PPC32=y
CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=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
@@ -52,11 +56,13 @@ CONFIG_OF=y
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
CONFIG_DEFAULT_UIMAGE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -77,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -105,7 +112,6 @@ CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -118,6 +124,13 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
CONFIG_COMPAT_BRK=y
@@ -125,14 +138,19 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
@@ -140,7 +158,7 @@ CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -220,11 +238,13 @@ CONFIG_BINFMT_ELF=y
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -240,9 +260,10 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
# CONFIG_PPC_64K_PAGES is not set
@@ -253,6 +274,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_EXTRA_TARGETS=""
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_RUNTIME is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y
@@ -329,6 +351,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -343,6 +366,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -368,6 +392,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -458,6 +483,7 @@ CONFIG_MTD_ROM=y
# CONFIG_MTD_UBI is not set
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
@@ -483,6 +509,7 @@ CONFIG_MISC_DEVICES=y
#
# CONFIG_EEPROM_AT24 is not set
CONFIG_EEPROM_LEGACY=y
+# CONFIG_EEPROM_MAX6875 is not set
# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -506,10 +533,6 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
@@ -532,6 +555,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
CONFIG_ATA_SFF=y
# CONFIG_SATA_MV is not set
@@ -540,7 +564,6 @@ CONFIG_PATA_MPC52xx=y
# CONFIG_MD is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -579,14 +602,14 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
CONFIG_FEC_MPC52xx=y
CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -647,6 +670,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -657,6 +681,7 @@ CONFIG_I2C_HELPER_AUTO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
+# CONFIG_I2C_DESIGNWARE is not set
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
@@ -676,22 +701,28 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -738,6 +769,8 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
@@ -747,9 +780,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -775,25 +806,12 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -817,7 +835,7 @@ CONFIG_LEDS_CLASS=y
#
# LED drivers
#
-# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_BD2802 is not set
@@ -866,6 +884,7 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
#
# SPI RTC drivers
@@ -893,6 +912,10 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -912,10 +935,13 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -986,12 +1012,12 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_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=y
+# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
@@ -1091,6 +1117,7 @@ CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
#
# Kernel hacking
@@ -1100,6 +1127,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1117,10 +1145,14 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK 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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1132,11 +1164,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -1145,23 +1178,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1186,7 +1221,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1227,11 +1261,13 @@ CONFIG_CRYPTO_PCBC=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/52xx/pcm030_defconfig b/arch/powerpc/configs/52xx/pcm030_defconfig
index afb1a3d1ef0a..f9168c1a2fa5 100644
--- a/arch/powerpc/configs/52xx/pcm030_defconfig
+++ b/arch/powerpc/configs/52xx/pcm030_defconfig
@@ -1,25 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:48:42 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:25 2009
#
# CONFIG_PPC64 is not set
#
# Processor support
#
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
CONFIG_PPC_FPU=y
# CONFIG_ALTIVEC is not set
CONFIG_PPC_STD_MMU=y
CONFIG_PPC_STD_MMU_32=y
# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
# CONFIG_SMP is not set
CONFIG_PPC32=y
CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=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
@@ -52,11 +56,13 @@ CONFIG_OF=y
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
CONFIG_DEFAULT_UIMAGE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -79,11 +85,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -105,7 +112,6 @@ CONFIG_EMBEDDED=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -118,6 +124,13 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_PCI_QUIRKS=y
CONFIG_COMPAT_BRK=y
@@ -125,7 +138,6 @@ 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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -133,7 +145,13 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
@@ -146,7 +164,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -227,11 +245,13 @@ CONFIG_BINFMT_ELF=y
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -247,9 +267,10 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
# CONFIG_PPC_64K_PAGES is not set
@@ -336,6 +357,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -350,6 +372,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -375,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -382,9 +406,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_OF_PARTS is not set
@@ -467,6 +491,7 @@ CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_UBI is not set
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
# CONFIG_BLK_DEV is not set
# CONFIG_MISC_DEVICES is not set
@@ -492,10 +517,6 @@ CONFIG_BLK_DEV_SD=m
# CONFIG_BLK_DEV_SR 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 is not set
# CONFIG_SCSI_LOGGING is not set
@@ -515,6 +536,7 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=m
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -536,6 +558,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -564,6 +587,7 @@ CONFIG_PATA_MPC52xx=m
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -582,14 +606,17 @@ CONFIG_PATA_MPC52xx=m
#
#
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
#
# 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_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -636,16 +663,16 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
CONFIG_FEC_MPC52xx=y
CONFIG_FEC_MPC52xx_MDIO=y
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -722,6 +749,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -750,6 +778,7 @@ CONFIG_I2C_HELPER_AUTO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
+# CONFIG_I2C_DESIGNWARE is not set
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
@@ -776,23 +805,23 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -811,30 +840,18 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -871,15 +888,17 @@ CONFIG_USB_DEVICEFS=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
# CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=m
# CONFIG_USB_OHCI_HCD_PPC_SOC is not set
-CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
# CONFIG_USB_OHCI_HCD_PCI is not set
CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -995,6 +1014,7 @@ CONFIG_RTC_DRV_PCF8563=m
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
#
# SPI RTC drivers
@@ -1022,6 +1042,10 @@ CONFIG_RTC_DRV_PCF8563=m
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -1041,12 +1065,16 @@ CONFIG_FS_MBCACHE=m
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
@@ -1114,7 +1142,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1201,6 +1228,7 @@ CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
#
# Kernel hacking
@@ -1210,6 +1238,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1223,23 +1252,12 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_IRQSTACKS is not set
# CONFIG_BOOTX_TEXT is not set
diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig
index 8585c7c12861..75c835c2ae66 100644
--- a/arch/powerpc/configs/52xx/tqm5200_defconfig
+++ b/arch/powerpc/configs/52xx/tqm5200_defconfig
@@ -1,25 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:48:57 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:23 2009
#
# CONFIG_PPC64 is not set
#
# Processor support
#
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
CONFIG_PPC_FPU=y
# CONFIG_ALTIVEC is not set
CONFIG_PPC_STD_MMU=y
CONFIG_PPC_STD_MMU_32=y
# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
# CONFIG_SMP is not set
CONFIG_PPC32=y
CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=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
@@ -52,11 +56,13 @@ CONFIG_OF=y
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
CONFIG_DEFAULT_UIMAGE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -77,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -105,7 +112,6 @@ CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -118,6 +124,13 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
CONFIG_COMPAT_BRK=y
@@ -125,14 +138,19 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
@@ -145,7 +163,7 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -225,11 +243,13 @@ CONFIG_BINFMT_ELF=y
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -245,9 +265,10 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
# CONFIG_PPC_64K_PAGES is not set
@@ -258,6 +279,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_EXTRA_TARGETS=""
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_RUNTIME is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y
@@ -334,6 +356,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -348,6 +371,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -373,6 +397,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -382,9 +407,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_OF_PARTS is not set
@@ -464,6 +489,7 @@ CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_UBI is not set
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
@@ -502,10 +528,6 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
@@ -529,6 +551,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
CONFIG_ATA_SFF=y
# CONFIG_SATA_MV is not set
@@ -538,7 +561,6 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -577,14 +599,14 @@ CONFIG_NET_ETHERNET=y
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
CONFIG_FEC_MPC52xx=y
CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -654,6 +676,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -664,6 +687,7 @@ CONFIG_I2C_HELPER_AUTO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
+# CONFIG_I2C_DESIGNWARE is not set
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
@@ -685,22 +709,28 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -747,6 +777,8 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
@@ -756,9 +788,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -789,25 +819,12 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -851,11 +868,12 @@ CONFIG_USB_MON=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_SOC=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
# CONFIG_USB_OHCI_LITTLE_ENDIAN is not set
@@ -969,6 +987,7 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
#
# SPI RTC drivers
@@ -996,6 +1015,10 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -1015,10 +1038,13 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1089,12 +1115,12 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_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=y
+# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
@@ -1194,6 +1220,7 @@ CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
#
# Kernel hacking
@@ -1203,6 +1230,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1220,10 +1248,14 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK 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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1235,11 +1267,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -1248,23 +1281,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1289,7 +1324,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1331,11 +1365,13 @@ CONFIG_CRYPTO_PCBC=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/asp8347_defconfig b/arch/powerpc/configs/83xx/asp8347_defconfig
index a2df0635b6de..466f09ac3153 100644
--- a/arch/powerpc/configs/83xx/asp8347_defconfig
+++ b/arch/powerpc/configs/83xx/asp8347_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:02 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:20 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -85,11 +86,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -125,28 +127,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -257,6 +260,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -274,6 +278,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -369,6 +374,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -398,6 +404,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -405,7 +412,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -418,6 +424,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -425,9 +432,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
@@ -628,7 +635,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -658,10 +667,7 @@ CONFIG_GIANFAR=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -760,6 +766,7 @@ CONFIG_LEGACY_PTY_COUNT=256
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -814,9 +821,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -834,6 +838,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -883,6 +892,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -894,7 +904,6 @@ CONFIG_HWMON=y
# 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_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
@@ -934,6 +943,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -944,6 +954,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -990,6 +1001,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
@@ -1045,6 +1057,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
@@ -1146,6 +1159,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1215,7 +1229,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1327,6 +1340,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1344,6 +1358,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1365,7 +1380,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1407,11 +1421,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/kmeter1_defconfig b/arch/powerpc/configs/83xx/kmeter1_defconfig
index 93ebd443a18f..6694fb73cd99 100644
--- a/arch/powerpc/configs/83xx/kmeter1_defconfig
+++ b/arch/powerpc/configs/83xx/kmeter1_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:03 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:21 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -86,11 +87,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_GROUP_SCHED is not set
@@ -119,20 +121,19 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -140,6 +141,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -250,6 +253,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -267,6 +271,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -348,6 +353,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
CONFIG_STP=m
@@ -396,9 +402,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
@@ -565,18 +571,16 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
CONFIG_FSL_PQ_MDIO=y
# CONFIG_GIANFAR is not set
CONFIG_UCC_GETH=y
-# CONFIG_UGETH_MAGIC_PACKET is not set
# CONFIG_UGETH_TX_ON_DEMAND is not set
# CONFIG_MV643XX_ETH is not set
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -663,6 +667,7 @@ CONFIG_HW_RANDOM=y
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -693,9 +698,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -713,7 +715,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -732,6 +733,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -784,6 +786,7 @@ CONFIG_UIO=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
@@ -854,7 +857,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -926,6 +928,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -942,6 +945,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
diff --git a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
index ff33a7db2eab..86df19f041a4 100644
--- a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:04 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:22 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,28 +126,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -256,6 +259,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +277,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -369,6 +374,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -398,6 +404,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -405,7 +412,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -418,6 +424,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -427,9 +434,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
CONFIG_MTD_OF_PARTS=y
@@ -488,6 +495,7 @@ CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -605,6 +613,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -643,7 +652,9 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -741,9 +752,11 @@ CONFIG_E100=y
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -791,10 +804,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -896,6 +906,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -950,9 +961,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -984,6 +992,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADCXX is not set
@@ -1036,6 +1049,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1048,9 +1062,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1088,8 +1100,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
@@ -1099,6 +1113,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1112,7 +1127,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1164,6 +1178,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1255,6 +1270,7 @@ CONFIG_USB_GADGET_SELECTED=y
# CONFIG_USB_GADGET_LH7A40X is not set
# CONFIG_USB_GADGET_OMAP is not set
# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
# CONFIG_USB_GADGET_PXA27X is not set
# CONFIG_USB_GADGET_S3C_HSOTG is not set
# CONFIG_USB_GADGET_IMX is not set
@@ -1273,6 +1289,7 @@ CONFIG_USB_GADGET_DUALSPEED=y
# CONFIG_USB_AUDIO is not set
CONFIG_USB_ETH=y
CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
# CONFIG_USB_GADGETFS is not set
# CONFIG_USB_FILE_STORAGE is not set
# CONFIG_USB_G_SERIAL is not set
@@ -1334,6 +1351,7 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1384,6 +1402,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1453,7 +1472,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1569,6 +1587,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1586,6 +1605,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1604,10 +1624,12 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1630,10 +1652,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1660,7 +1682,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1702,11 +1723,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
index 76237d466702..7bf71d577033 100644
--- a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:05 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:23 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,28 +126,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -256,6 +259,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +277,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -369,6 +374,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -398,6 +404,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -405,7 +412,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -418,6 +424,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -427,9 +434,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_OF_PARTS is not set
@@ -488,6 +495,7 @@ CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -605,6 +613,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -644,11 +653,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -671,6 +683,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -698,6 +711,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -802,9 +816,11 @@ CONFIG_E100=y
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -852,10 +868,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -957,6 +970,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -1011,9 +1025,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1045,6 +1056,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADCXX is not set
@@ -1097,6 +1113,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1109,9 +1126,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1149,8 +1164,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
@@ -1160,6 +1177,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1173,7 +1191,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1225,6 +1242,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1316,6 +1334,7 @@ CONFIG_USB_GADGET_SELECTED=y
# CONFIG_USB_GADGET_LH7A40X is not set
# CONFIG_USB_GADGET_OMAP is not set
# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
# CONFIG_USB_GADGET_PXA27X is not set
# CONFIG_USB_GADGET_S3C_HSOTG is not set
# CONFIG_USB_GADGET_IMX is not set
@@ -1334,6 +1353,7 @@ CONFIG_USB_GADGET_DUALSPEED=y
# CONFIG_USB_AUDIO is not set
CONFIG_USB_ETH=y
CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
# CONFIG_USB_GADGETFS is not set
# CONFIG_USB_FILE_STORAGE is not set
# CONFIG_USB_G_SERIAL is not set
@@ -1395,6 +1415,7 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1445,6 +1466,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1514,7 +1536,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1630,6 +1651,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1647,6 +1669,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1665,10 +1688,12 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1691,10 +1716,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1721,7 +1746,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1763,11 +1787,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig
index e0e36a113409..7def83518a6c 100644
--- a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig
+++ b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:06 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:24 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,28 +126,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -257,6 +260,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -274,6 +278,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -369,6 +374,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -398,6 +404,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -405,7 +412,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -418,6 +424,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -504,6 +511,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -542,7 +550,9 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -612,7 +622,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -635,7 +647,6 @@ CONFIG_NETDEV_1000=y
CONFIG_FSL_PQ_MDIO=y
# CONFIG_GIANFAR is not set
CONFIG_UCC_GETH=y
-# CONFIG_UGETH_MAGIC_PACKET is not set
# CONFIG_UGETH_TX_ON_DEMAND is not set
# CONFIG_MV643XX_ETH is not set
# CONFIG_QLA3XXX is not set
@@ -663,10 +674,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -759,6 +767,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -812,9 +821,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -832,6 +838,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -881,6 +892,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -892,9 +904,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -927,6 +937,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -937,6 +948,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -950,7 +962,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1070,6 +1081,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1128,7 +1140,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1202,6 +1213,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1219,6 +1231,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1240,7 +1253,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1282,11 +1294,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
index 4f27d4548223..b398b9b2b635 100644
--- a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:07 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:24 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,28 +126,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -257,6 +260,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -274,6 +278,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -369,6 +374,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -398,6 +404,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -405,7 +412,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -418,6 +424,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -507,6 +514,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -545,7 +553,9 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -617,7 +627,9 @@ CONFIG_MII=y
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -640,7 +652,6 @@ CONFIG_E1000=y
CONFIG_FSL_PQ_MDIO=y
# CONFIG_GIANFAR is not set
CONFIG_UCC_GETH=y
-# CONFIG_UGETH_MAGIC_PACKET is not set
# CONFIG_UGETH_TX_ON_DEMAND is not set
# CONFIG_MV643XX_ETH is not set
# CONFIG_QLA3XXX is not set
@@ -668,10 +679,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -776,6 +784,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -830,9 +839,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -863,6 +869,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADCXX is not set
@@ -915,6 +926,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -927,9 +939,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -967,8 +977,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
@@ -978,6 +990,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -991,7 +1004,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1043,6 +1055,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1146,6 +1159,8 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
# CONFIG_MMC_SDHCI is not set
# CONFIG_MMC_WBSD is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
# CONFIG_MMC_TIFM_SD is not set
CONFIG_MMC_SPI=y
# CONFIG_MMC_CB710 is not set
@@ -1186,6 +1201,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1247,7 +1263,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1365,6 +1380,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1382,6 +1398,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1403,7 +1420,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1445,11 +1461,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
index 648dac0c9d8d..f67317e1934c 100644
--- a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
+++ b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:07 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:25 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,28 +126,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -256,6 +259,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +277,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -368,6 +373,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -397,6 +403,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -404,7 +411,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -417,6 +423,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -424,9 +431,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
# CONFIG_MTD_PARTITIONS is not set
-# CONFIG_MTD_TESTS is not set
#
# User Modules And Translation Layers
@@ -483,6 +490,7 @@ CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -637,6 +645,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -676,11 +685,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -703,6 +715,7 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -730,6 +743,7 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -845,10 +859,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -930,6 +941,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -984,9 +996,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-CONFIG_SENSORS_PCF8574=y
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1017,7 +1026,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1055,8 +1063,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
@@ -1066,6 +1076,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1111,6 +1122,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
@@ -1238,6 +1250,7 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1288,6 +1301,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1350,7 +1364,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1465,6 +1478,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1482,6 +1496,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1503,7 +1518,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1545,11 +1559,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
index bf6deb831dc3..a668110c10f6 100644
--- a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
+++ b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:08 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:26 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,28 +126,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -256,6 +259,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +277,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -368,6 +373,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -397,6 +403,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -404,7 +411,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -417,6 +423,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -424,9 +431,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
# CONFIG_MTD_PARTITIONS is not set
-# CONFIG_MTD_TESTS is not set
#
# User Modules And Translation Layers
@@ -483,6 +490,7 @@ CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -589,6 +597,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -627,7 +636,9 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -725,10 +736,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -810,6 +818,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -864,9 +873,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-CONFIG_SENSORS_PCF8574=y
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -897,7 +903,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -935,8 +940,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
@@ -946,6 +953,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -991,6 +999,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
@@ -1059,6 +1068,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
@@ -1117,6 +1127,7 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1167,6 +1178,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1229,7 +1241,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1344,6 +1355,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1361,6 +1373,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1382,7 +1395,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1424,11 +1436,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig
index 3236c47712c2..c4e92ba5c38b 100644
--- a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig
+++ b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:09 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:27 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,28 +126,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -256,6 +259,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +277,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -368,6 +373,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -397,6 +403,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -404,7 +411,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -417,6 +423,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -556,9 +563,11 @@ CONFIG_E100=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -606,10 +615,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -699,6 +705,7 @@ CONFIG_LEGACY_PTY_COUNT=256
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -752,9 +759,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -772,6 +776,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -821,6 +830,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -832,9 +842,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -867,6 +875,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -877,6 +886,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -890,7 +900,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1010,6 +1019,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1068,7 +1078,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1140,6 +1149,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1157,6 +1167,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1178,7 +1189,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1220,11 +1230,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig
index 8c5299d74813..4f434b1492fa 100644
--- a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig
+++ b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:10 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:28 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,28 +126,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -255,6 +258,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -272,6 +276,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -367,6 +372,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -396,6 +402,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -403,7 +410,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -416,6 +422,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -423,9 +430,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_OF_PARTS is not set
@@ -585,6 +592,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -623,7 +631,9 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -693,7 +703,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -716,7 +728,6 @@ CONFIG_NETDEV_1000=y
CONFIG_FSL_PQ_MDIO=y
# CONFIG_GIANFAR is not set
CONFIG_UCC_GETH=y
-# CONFIG_UGETH_MAGIC_PACKET is not set
# CONFIG_UGETH_TX_ON_DEMAND is not set
# CONFIG_MV643XX_ETH is not set
# CONFIG_QLA3XXX is not set
@@ -744,10 +755,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -840,6 +848,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -893,9 +902,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -913,6 +919,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -962,6 +973,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -973,9 +985,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1008,6 +1018,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1018,6 +1029,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1031,7 +1043,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1151,6 +1162,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1210,7 +1222,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1284,6 +1295,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1301,6 +1313,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1322,7 +1335,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1364,11 +1376,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
index ff31667a890b..b52ec0861679 100644
--- a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
+++ b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:12 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:30 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -85,11 +86,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -125,28 +127,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -255,6 +258,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -272,6 +276,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -369,6 +374,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -398,6 +404,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -405,7 +412,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -418,6 +424,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -427,9 +434,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_OF_PARTS is not set
@@ -493,6 +500,7 @@ CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -639,7 +647,6 @@ CONFIG_NETDEV_1000=y
CONFIG_FSL_PQ_MDIO=y
# CONFIG_GIANFAR is not set
CONFIG_UCC_GETH=y
-# CONFIG_UGETH_MAGIC_PACKET is not set
# CONFIG_UGETH_TX_ON_DEMAND is not set
# CONFIG_MV643XX_ETH is not set
# CONFIG_QLA3XXX is not set
@@ -649,10 +656,7 @@ CONFIG_UCC_GETH=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -750,6 +754,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -804,9 +809,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -853,17 +855,22 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -897,8 +904,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
@@ -908,6 +917,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -992,7 +1002,6 @@ CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1038,6 +1047,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1107,7 +1117,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1183,6 +1192,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1200,6 +1210,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1232,7 +1243,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1274,11 +1284,13 @@ CONFIG_CRYPTO_CBC=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig
index e285ec0fe958..730061574f96 100644
--- a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig
+++ b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:11 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:29 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -125,21 +127,20 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -147,6 +148,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -256,6 +259,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +277,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -368,6 +373,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -397,6 +403,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -404,7 +411,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -417,6 +423,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -503,6 +510,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -542,11 +550,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -569,6 +580,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -596,6 +608,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -672,7 +685,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -720,10 +735,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -816,6 +828,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -869,9 +882,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -889,6 +899,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -938,6 +953,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -949,9 +965,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -984,6 +998,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -994,6 +1009,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1007,7 +1023,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1072,6 +1087,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1130,7 +1146,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1206,6 +1221,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1221,6 +1237,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1242,7 +1259,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1284,11 +1300,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
index 1ab3e4cd3018..9e9158a5b190 100644
--- a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:13 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:30 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -125,21 +127,20 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -147,6 +148,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -256,6 +259,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +277,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -363,6 +368,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -392,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -399,7 +406,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -412,6 +418,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -498,6 +505,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -537,11 +545,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -564,6 +575,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -591,6 +603,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -610,6 +623,7 @@ CONFIG_MD_RAID1=y
# CONFIG_MD_RAID10 is not set
CONFIG_MD_RAID456=y
CONFIG_MD_RAID6_PQ=y
+# CONFIG_ASYNC_RAID6_TEST is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
# CONFIG_BLK_DEV_DM is not set
@@ -678,7 +692,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -708,10 +724,7 @@ CONFIG_GIANFAR=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -813,6 +826,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -867,9 +881,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -887,6 +898,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -936,6 +952,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -947,9 +964,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -987,6 +1002,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -997,6 +1013,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1010,7 +1027,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1033,6 +1049,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1085,6 +1102,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
@@ -1142,6 +1160,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
@@ -1188,6 +1207,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1246,7 +1266,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1361,6 +1380,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1376,6 +1396,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1396,12 +1417,13 @@ CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
+CONFIG_ASYNC_PQ=y
+CONFIG_ASYNC_RAID6_RECOV=y
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1443,11 +1465,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/83xx/sbc834x_defconfig b/arch/powerpc/configs/83xx/sbc834x_defconfig
index 3a68f861b1bd..6b399154970f 100644
--- a/arch/powerpc/configs/83xx/sbc834x_defconfig
+++ b/arch/powerpc/configs/83xx/sbc834x_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc5
-# Tue Aug 11 19:57:51 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:31 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,27 +126,28 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -254,6 +257,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -271,6 +275,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -366,6 +371,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -395,6 +401,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -402,7 +409,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -415,6 +421,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -422,9 +429,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
@@ -651,7 +658,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -681,10 +690,7 @@ CONFIG_GIANFAR=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -786,6 +792,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -840,9 +847,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -860,6 +864,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -909,6 +918,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -920,9 +930,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -960,6 +968,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -970,6 +979,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -983,7 +993,6 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1035,6 +1044,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
@@ -1148,6 +1158,7 @@ CONFIG_JBD=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1207,7 +1218,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1306,6 +1316,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1321,6 +1332,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1342,7 +1354,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1384,11 +1395,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/ksi8560_defconfig b/arch/powerpc/configs/85xx/ksi8560_defconfig
index ff04e1028f5e..a5bde8da462c 100644
--- a/arch/powerpc/configs/85xx/ksi8560_defconfig
+++ b/arch/powerpc/configs/85xx/ksi8560_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:14 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:32 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -85,11 +87,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_GROUP_SCHED is not set
@@ -123,28 +126,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -188,6 +192,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
CONFIG_KSI8560=y
# CONFIG_XES_MPC85xx is not set
@@ -243,6 +248,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -260,6 +266,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -348,6 +355,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -377,6 +385,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -384,7 +393,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -397,6 +405,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -582,6 +591,8 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_SCC is not set
CONFIG_FS_ENET_HAS_FCC=y
@@ -591,10 +602,7 @@ CONFIG_FSL_PQ_MDIO=y
CONFIG_GIANFAR=y
# CONFIG_MV643XX_ETH is not set
CONFIG_NETDEV_10000=y
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -704,10 +712,19 @@ CONFIG_GPIOLIB=y
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_IT87 is not set
@@ -719,9 +736,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -755,7 +770,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -818,6 +832,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -877,7 +892,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -945,6 +959,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -962,6 +977,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -981,10 +997,12 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1008,10 +1026,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1039,7 +1057,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1070,11 +1087,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
index fb10cc83702e..c10e26f8763f 100644
--- a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
+++ b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:15 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:33 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +86,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -126,27 +129,28 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -189,6 +193,7 @@ CONFIG_MPC8540_ADS=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -244,6 +249,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -261,6 +267,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -349,6 +356,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -378,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -385,7 +394,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -398,6 +406,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -483,15 +492,14 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
CONFIG_FSL_PQ_MDIO=y
CONFIG_GIANFAR=y
# CONFIG_MV643XX_ETH is not set
CONFIG_NETDEV_10000=y
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -588,6 +596,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_IT87 is not set
@@ -598,9 +611,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -634,7 +645,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -696,6 +706,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -754,7 +765,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -822,6 +832,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -839,6 +850,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -857,10 +869,12 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -883,10 +897,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -912,7 +926,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -943,11 +956,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
index 5c8ce6978825..8d9f0a4b5205 100644
--- a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
+++ b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:16 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:34 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -85,11 +87,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -127,29 +130,30 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -192,6 +196,7 @@ CONFIG_MPC8560_ADS=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -247,6 +252,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -264,6 +270,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -361,6 +368,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -390,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -397,7 +406,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -410,6 +418,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -530,7 +539,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_SCC is not set
CONFIG_FS_ENET_HAS_FCC=y
@@ -582,10 +593,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -698,14 +706,24 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
@@ -721,9 +739,7 @@ CONFIG_HWMON=y
# 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 is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -746,6 +762,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -759,7 +776,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -824,6 +840,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -882,7 +899,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -950,6 +966,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -967,6 +984,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -985,10 +1003,12 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1011,10 +1031,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1040,7 +1060,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1071,11 +1090,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
index 158e63e8607f..9b63e258dac6 100644
--- a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
+++ b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:17 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:35 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +86,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -126,28 +129,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -190,6 +194,7 @@ CONFIG_MPC85xx_CDS=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -245,6 +250,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -262,6 +268,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -359,6 +366,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -388,6 +396,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -395,7 +404,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -408,6 +416,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -582,7 +591,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -630,10 +641,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -737,6 +745,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
@@ -751,9 +764,7 @@ CONFIG_HWMON=y
# 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 is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -776,6 +787,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -789,7 +801,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -854,6 +865,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -912,7 +924,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -980,6 +991,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -997,6 +1009,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1015,10 +1028,12 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1041,10 +1056,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1070,7 +1085,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1101,11 +1115,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/sbc8548_defconfig b/arch/powerpc/configs/85xx/sbc8548_defconfig
index 2726fca1d694..1b2356830173 100644
--- a/arch/powerpc/configs/85xx/sbc8548_defconfig
+++ b/arch/powerpc/configs/85xx/sbc8548_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:18 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:36 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +86,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -125,27 +128,28 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -188,6 +192,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -242,6 +247,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -259,6 +265,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -355,6 +362,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -384,6 +392,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -391,7 +400,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -404,6 +412,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -521,7 +530,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -569,10 +580,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -676,6 +684,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
@@ -690,9 +703,7 @@ CONFIG_HWMON=y
# 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 is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -715,6 +726,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -758,6 +770,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -816,7 +829,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -872,6 +884,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -887,6 +900,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -907,7 +921,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -938,11 +951,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/sbc8560_defconfig b/arch/powerpc/configs/85xx/sbc8560_defconfig
index b0c469823b02..959d0281431b 100644
--- a/arch/powerpc/configs/85xx/sbc8560_defconfig
+++ b/arch/powerpc/configs/85xx/sbc8560_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:19 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:37 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +86,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -126,26 +129,27 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -188,6 +192,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -242,6 +247,7 @@ CONFIG_BINFMT_MISC=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -259,6 +265,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -347,6 +354,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -376,6 +384,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -383,7 +392,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -396,6 +404,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -481,15 +490,14 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
CONFIG_FSL_PQ_MDIO=y
CONFIG_GIANFAR=y
# CONFIG_MV643XX_ETH is not set
CONFIG_NETDEV_10000=y
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -584,6 +592,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_IT87 is not set
@@ -594,9 +607,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -630,7 +641,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -721,6 +731,7 @@ CONFIG_RTC_DRV_M48T59=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -779,7 +790,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -847,6 +857,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -863,6 +874,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -881,10 +893,12 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -907,10 +921,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -947,7 +961,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -978,11 +991,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/socrates_defconfig b/arch/powerpc/configs/85xx/socrates_defconfig
index 04c85dada845..7f5ec35bf199 100644
--- a/arch/powerpc/configs/85xx/socrates_defconfig
+++ b/arch/powerpc/configs/85xx/socrates_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:19 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:37 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +86,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=16
CONFIG_GROUP_SCHED=y
@@ -124,28 +127,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -193,6 +197,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
CONFIG_SOCRATES=y
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -247,6 +252,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -264,6 +270,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -358,6 +365,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -396,6 +404,7 @@ CONFIG_CAN_BCM=y
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -403,7 +412,6 @@ CONFIG_WIRELESS=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -421,9 +429,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
@@ -482,6 +490,7 @@ CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -668,7 +677,9 @@ CONFIG_MII=y
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -698,10 +709,7 @@ CONFIG_GIANFAR=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -765,6 +773,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_INEXIO is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
@@ -774,7 +783,6 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_TOUCHSCREEN_W90X900 is not set
# CONFIG_INPUT_MISC is not set
#
@@ -834,6 +842,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -888,9 +897,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -921,6 +927,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
+CONFIG_HWMON_DEBUG_CHIP=y
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADCXX is not set
@@ -973,6 +984,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -985,9 +997,7 @@ CONFIG_SENSORS_W83781D=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_SENSORS_LIS3_SPI is not set
-CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1006,8 +1016,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
@@ -1017,6 +1029,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1112,7 +1125,6 @@ CONFIG_FONT_8x16=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1135,6 +1147,7 @@ CONFIG_USB_HID=y
# CONFIG_HID_EZKEY is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LOGITECH is not set
# CONFIG_HID_MICROSOFT is not set
@@ -1184,6 +1197,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1319,6 +1333,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1369,6 +1384,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1438,7 +1454,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1552,6 +1567,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1569,6 +1585,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1589,7 +1606,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1621,11 +1637,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/stx_gp3_defconfig b/arch/powerpc/configs/85xx/stx_gp3_defconfig
index e7e81d6769fe..c8327e88a987 100644
--- a/arch/powerpc/configs/85xx/stx_gp3_defconfig
+++ b/arch/powerpc/configs/85xx/stx_gp3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:20 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:38 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -85,11 +87,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -127,22 +130,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -150,7 +152,9 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -197,6 +201,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -252,6 +257,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -269,6 +275,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -426,6 +433,7 @@ CONFIG_IP_NF_FILTER=m
# CONFIG_IP_NF_ARPTABLES is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -455,6 +463,7 @@ CONFIG_NET_PKTGEN=y
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -462,7 +471,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -475,6 +483,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -622,6 +631,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -662,7 +672,9 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -732,8 +744,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_NET_POCKET is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_FS_ENET is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
@@ -782,10 +796,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -827,11 +838,15 @@ CONFIG_INPUT_EVDEV=m
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
@@ -842,6 +857,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_APPLETOUCH is not set
@@ -909,6 +925,7 @@ CONFIG_HW_RANDOM=m
CONFIG_DEVPORT=y
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=m
@@ -967,9 +984,6 @@ CONFIG_I2C_ALGOBIT=m
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1003,14 +1017,24 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1061,6 +1085,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1072,9 +1097,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1092,6 +1115,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_TPS65010 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1102,6 +1126,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
CONFIG_AGP=m
+CONFIG_VGA_ARB=y
CONFIG_DRM=m
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
@@ -1125,7 +1150,6 @@ CONFIG_SOUND=m
# CONFIG_SOUND_PRIME is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1190,6 +1214,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1254,7 +1279,6 @@ CONFIG_CRAMFS=m
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1352,6 +1376,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1369,6 +1394,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1388,10 +1414,12 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1414,10 +1442,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1443,7 +1471,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1475,11 +1502,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/tqm8540_defconfig b/arch/powerpc/configs/85xx/tqm8540_defconfig
index 2c407523aad2..82563703d5e3 100644
--- a/arch/powerpc/configs/85xx/tqm8540_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8540_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:21 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:39 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +86,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -124,28 +127,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -188,6 +192,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -243,6 +248,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -260,6 +266,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -354,6 +361,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -383,6 +391,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -390,7 +399,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -677,9 +685,11 @@ CONFIG_E100=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -727,10 +737,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -824,6 +831,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -876,9 +884,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -896,6 +901,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+CONFIG_HWMON_DEBUG_CHIP=y
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -945,6 +955,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -956,9 +967,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -977,6 +986,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -987,6 +997,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1000,7 +1011,6 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1065,6 +1075,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1134,7 +1145,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1203,6 +1213,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1220,6 +1231,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1240,7 +1252,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1271,11 +1282,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/tqm8541_defconfig b/arch/powerpc/configs/85xx/tqm8541_defconfig
index 845731dc51c6..91d85d733827 100644
--- a/arch/powerpc/configs/85xx/tqm8541_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8541_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:22 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:40 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -85,11 +87,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -125,29 +128,30 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -190,6 +194,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -246,6 +251,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -263,6 +269,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -357,6 +364,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -386,6 +394,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -393,7 +402,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -681,9 +689,11 @@ CONFIG_E100=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_FS_ENET is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
@@ -732,10 +742,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -831,6 +838,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -886,9 +894,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -921,14 +926,24 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+CONFIG_HWMON_DEBUG_CHIP=y
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -979,6 +994,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -990,9 +1006,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1012,6 +1026,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1022,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1035,7 +1051,6 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1100,6 +1115,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1169,7 +1185,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1238,6 +1253,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1255,6 +1271,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1275,7 +1292,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1306,11 +1322,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/tqm8548_defconfig b/arch/powerpc/configs/85xx/tqm8548_defconfig
index 4f228a905274..debe268f43d1 100644
--- a/arch/powerpc/configs/85xx/tqm8548_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8548_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:23 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:41 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +86,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -126,22 +129,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -149,6 +151,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -196,6 +200,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -252,6 +257,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -269,6 +275,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -371,6 +378,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -411,6 +419,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -420,9 +429,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
CONFIG_MTD_OF_PARTS=y
@@ -630,7 +639,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -678,10 +689,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -772,6 +780,7 @@ CONFIG_LEGACY_PTY_COUNT=256
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -825,9 +834,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -845,6 +851,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -894,6 +905,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -905,9 +917,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -926,6 +936,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -936,6 +947,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -949,7 +961,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1042,6 +1053,7 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1111,7 +1123,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1180,6 +1191,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1197,6 +1209,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1216,10 +1229,12 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1242,10 +1257,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1271,7 +1286,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1303,11 +1317,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/tqm8555_defconfig b/arch/powerpc/configs/85xx/tqm8555_defconfig
index 9196724bebc7..74515501f5b7 100644
--- a/arch/powerpc/configs/85xx/tqm8555_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8555_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:24 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:42 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -85,11 +87,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -125,29 +128,30 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -190,6 +194,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -246,6 +251,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -263,6 +269,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -357,6 +364,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -386,6 +394,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -393,7 +402,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -681,9 +689,11 @@ CONFIG_E100=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_FS_ENET is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
@@ -732,10 +742,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -831,6 +838,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -886,9 +894,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -921,14 +926,24 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+CONFIG_HWMON_DEBUG_CHIP=y
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -979,6 +994,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -990,9 +1006,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1012,6 +1026,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1022,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1035,7 +1051,6 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1100,6 +1115,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1169,7 +1185,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1238,6 +1253,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1255,6 +1271,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1275,7 +1292,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1306,11 +1322,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/tqm8560_defconfig b/arch/powerpc/configs/85xx/tqm8560_defconfig
index 2e49a6e9faf2..631d92b4d4e6 100644
--- a/arch/powerpc/configs/85xx/tqm8560_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8560_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:25 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:43 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -85,11 +87,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -125,29 +128,30 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -190,6 +194,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
@@ -246,6 +251,7 @@ CONFIG_MATH_EMULATION=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -263,6 +269,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -357,6 +364,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -386,6 +394,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -393,7 +402,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -681,9 +689,11 @@ CONFIG_E100=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_FS_ENET is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
@@ -732,10 +742,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -831,6 +838,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -886,9 +894,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -921,14 +926,24 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+CONFIG_HWMON_DEBUG_CHIP=y
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -979,6 +994,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -990,9 +1006,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1012,6 +1026,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1022,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1035,7 +1051,6 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1100,6 +1115,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1169,7 +1185,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1238,6 +1253,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1255,6 +1271,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1275,7 +1292,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1306,11 +1322,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
index 1025da2bf069..52acbac0c4fe 100644
--- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
+++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:25 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:44 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_SMP=y
@@ -37,6 +38,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -89,11 +91,12 @@ CONFIG_AUDIT=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -128,22 +131,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -151,7 +153,9 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -201,6 +205,7 @@ CONFIG_MPC85xx=y
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
+# CONFIG_MPC85xx_RDB is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
CONFIG_XES_MPC85xx=y
@@ -256,6 +261,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +279,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -405,6 +412,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -446,6 +454,7 @@ CONFIG_FIB_RULES=y
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -457,9 +466,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -635,6 +644,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -674,11 +684,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SIL24 is not set
@@ -701,6 +714,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_ALI=y
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -728,6 +742,7 @@ CONFIG_PATA_ALI=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -804,7 +819,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -834,10 +851,7 @@ CONFIG_GIANFAR=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -951,6 +965,7 @@ CONFIG_NVRAM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -1006,8 +1021,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1041,14 +1054,24 @@ CONFIG_GPIO_PCA953X=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1099,6 +1122,7 @@ CONFIG_SENSORS_LM90=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1110,9 +1134,7 @@ CONFIG_SENSORS_LM90=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1151,6 +1173,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1161,6 +1184,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1181,7 +1205,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1204,6 +1227,7 @@ CONFIG_USB_HID=y
# CONFIG_HID_EZKEY is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LOGITECH is not set
# CONFIG_HID_MICROSOFT is not set
@@ -1249,6 +1273,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_ISP1760_HCD=y
+# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
@@ -1466,6 +1491,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1541,7 +1567,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1658,6 +1683,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1675,6 +1701,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1694,10 +1721,12 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1720,10 +1749,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1749,7 +1778,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1790,11 +1818,13 @@ CONFIG_CRYPTO_WORKQUEUE=y
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
index 527ad1a5e802..28980738776c 100644
--- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
+++ b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:31 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:49 2009
#
# CONFIG_PPC64 is not set
@@ -36,6 +36,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -88,11 +89,12 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -130,21 +132,20 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -152,12 +153,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
#
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -256,6 +259,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_IRQ_ALL_CPUS=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +277,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -417,6 +422,7 @@ CONFIG_IPV6_TUNNEL=m
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -458,6 +464,7 @@ CONFIG_FIB_RULES=y
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -467,9 +474,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
CONFIG_MTD_OF_PARTS=y
@@ -680,6 +687,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -719,12 +727,15 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -747,6 +758,7 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -775,6 +787,7 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_PCMCIA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -851,7 +864,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -881,10 +896,7 @@ CONFIG_GIANFAR=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -1016,6 +1028,7 @@ CONFIG_NVRAM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -1071,9 +1084,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
CONFIG_DS1682=y
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1106,14 +1116,24 @@ CONFIG_GPIO_SYSFS=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1164,6 +1184,7 @@ CONFIG_SENSORS_LM92=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1175,9 +1196,7 @@ CONFIG_SENSORS_LM92=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1217,6 +1236,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1227,6 +1247,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1247,7 +1268,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1270,6 +1290,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1322,6 +1343,7 @@ CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1397,6 +1419,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
@@ -1501,6 +1524,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1576,7 +1600,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1682,6 +1705,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1697,6 +1721,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1718,7 +1743,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=m
@@ -1761,11 +1785,13 @@ CONFIG_CRYPTO_CBC=y
#
CONFIG_CRYPTO_HMAC=m
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
index cd338d493bed..e199d1cacbaf 100644
--- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig
+++ b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:29 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:47 2009
#
# CONFIG_PPC64 is not set
@@ -36,6 +36,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -88,11 +89,12 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -130,21 +132,20 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -152,12 +153,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
#
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -256,6 +259,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_IRQ_ALL_CPUS=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -273,6 +277,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -417,6 +422,7 @@ CONFIG_IPV6_TUNNEL=m
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -458,6 +464,7 @@ CONFIG_FIB_RULES=y
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -467,9 +474,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
CONFIG_MTD_OF_PARTS=y
@@ -680,6 +687,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -719,12 +727,15 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
CONFIG_SATA_SIL24=y
@@ -796,7 +807,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -826,10 +839,7 @@ CONFIG_GIANFAR=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -961,6 +971,7 @@ CONFIG_NVRAM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -1016,9 +1027,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
CONFIG_DS1682=y
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1051,14 +1059,24 @@ CONFIG_GPIO_SYSFS=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1109,6 +1127,7 @@ CONFIG_SENSORS_LM92=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1120,9 +1139,7 @@ CONFIG_SENSORS_LM92=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1162,6 +1179,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1172,6 +1190,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1192,7 +1211,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1215,6 +1233,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1267,6 +1286,7 @@ CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1342,6 +1362,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
@@ -1446,6 +1467,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1521,7 +1543,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1627,6 +1648,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1642,6 +1664,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1663,7 +1686,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=m
@@ -1706,11 +1728,13 @@ CONFIG_CRYPTO_CBC=y
#
CONFIG_CRYPTO_HMAC=m
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
index ba47883f4aa0..3b0fbfb28efd 100644
--- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig
+++ b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:30 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:48 2009
#
# CONFIG_PPC64 is not set
@@ -36,6 +36,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -88,11 +89,12 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -131,21 +133,20 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -153,12 +154,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
#
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -257,6 +260,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_IRQ_ALL_CPUS=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -274,6 +278,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -503,6 +508,7 @@ CONFIG_IP_SCTP=m
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_RDS is not set
CONFIG_TIPC=m
# CONFIG_TIPC_ADVANCED is not set
# CONFIG_TIPC_DEBUG is not set
@@ -582,6 +588,7 @@ CONFIG_NET_PKTGEN=m
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -589,7 +596,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -602,6 +608,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -611,9 +618,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_OF_PARTS is not set
@@ -780,6 +787,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -819,11 +827,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -846,6 +857,7 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -873,6 +885,7 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -949,7 +962,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -979,10 +994,7 @@ CONFIG_GIANFAR=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -1120,6 +1132,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -1175,9 +1188,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
CONFIG_DS1682=y
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1211,14 +1221,24 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1269,6 +1289,7 @@ CONFIG_SENSORS_LM92=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1280,9 +1301,7 @@ CONFIG_SENSORS_LM92=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1322,6 +1341,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1332,6 +1352,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1352,7 +1373,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1375,6 +1395,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1427,6 +1448,7 @@ CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1502,6 +1524,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_ATM is not set
@@ -1607,6 +1630,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1669,7 +1693,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1775,6 +1798,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1791,6 +1815,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
@@ -1810,10 +1835,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1837,10 +1864,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1872,7 +1899,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=m
@@ -1915,11 +1941,13 @@ CONFIG_CRYPTO_PCBC=m
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
index a61f183f7186..de4d52504fe4 100644
--- a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
+++ b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:27 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:45 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -83,11 +84,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -126,22 +128,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -149,6 +150,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -251,6 +254,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -268,6 +272,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -385,6 +390,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -414,6 +420,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -421,7 +428,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -434,6 +440,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -445,9 +452,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_OF_PARTS is not set
@@ -662,6 +669,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -701,11 +709,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SIL24 is not set
@@ -728,6 +739,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_ALI=y
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -755,6 +767,7 @@ CONFIG_PATA_ALI=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -818,14 +831,13 @@ CONFIG_ULI526X=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -929,6 +941,7 @@ CONFIG_UNIX98_PTYS=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
@@ -982,9 +995,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1002,7 +1012,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1021,6 +1030,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1031,6 +1041,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1107,6 +1118,7 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_LOGO is not set
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
@@ -1209,7 +1221,6 @@ CONFIG_SND_SOC_CS4270_VD33_ERRATA=y
# CONFIG_SOUND_PRIME is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1329,6 +1340,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
@@ -1388,7 +1400,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1505,6 +1516,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1522,6 +1534,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1541,10 +1554,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1567,10 +1582,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1597,7 +1612,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1629,11 +1643,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
index 7016ce732605..754a79ba74a9 100644
--- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
+++ b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:28 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:46 2009
#
# CONFIG_PPC64 is not set
@@ -36,6 +36,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -87,11 +88,12 @@ CONFIG_AUDIT=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -130,22 +132,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -153,7 +154,9 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -251,13 +254,13 @@ CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
CONFIG_IOMMU_HELPER=y
CONFIG_SWIOTLB=y
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
# CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -275,6 +278,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -404,6 +408,7 @@ CONFIG_IP_SCTP=m
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -434,6 +439,7 @@ CONFIG_SCTP_HMAC_MD5=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -441,7 +447,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -454,6 +459,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -546,6 +552,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -585,11 +592,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SIL24 is not set
@@ -612,6 +622,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_ALI=y
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -639,6 +650,7 @@ CONFIG_PATA_ALI=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -715,7 +727,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -763,10 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -880,6 +891,7 @@ CONFIG_NVRAM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
@@ -934,9 +946,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -954,7 +963,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -973,6 +981,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -983,6 +992,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1002,6 +1012,7 @@ CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
@@ -1105,7 +1116,6 @@ CONFIG_SND_USB=y
CONFIG_AC97_BUS=y
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1128,6 +1138,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1180,6 +1191,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
@@ -1358,6 +1370,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1428,7 +1441,6 @@ CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_UFS_DEBUG is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1546,6 +1558,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1563,6 +1576,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1582,10 +1596,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1608,10 +1624,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1638,7 +1654,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1680,11 +1695,13 @@ CONFIG_CRYPTO_PCBC=m
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/86xx/sbc8641d_defconfig b/arch/powerpc/configs/86xx/sbc8641d_defconfig
index f5ca2e0cd402..89991f157ae8 100644
--- a/arch/powerpc/configs/86xx/sbc8641d_defconfig
+++ b/arch/powerpc/configs/86xx/sbc8641d_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:26 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:45 2009
#
# CONFIG_PPC64 is not set
@@ -36,6 +36,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -87,11 +88,12 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -130,21 +132,20 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -152,13 +153,15 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -257,6 +260,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_IRQ_ALL_CPUS=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -274,6 +278,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -502,6 +507,7 @@ CONFIG_IP_SCTP=m
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_RDS is not set
CONFIG_TIPC=m
# CONFIG_TIPC_ADVANCED is not set
# CONFIG_TIPC_DEBUG is not set
@@ -581,6 +587,7 @@ CONFIG_NET_PKTGEN=m
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -588,7 +595,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -601,6 +607,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -610,9 +617,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_OF_PARTS is not set
@@ -833,7 +840,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -863,10 +872,7 @@ CONFIG_GIANFAR=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -996,6 +1002,7 @@ CONFIG_HW_RANDOM=m
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -1049,9 +1056,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1069,6 +1073,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1118,6 +1127,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1129,9 +1139,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1164,6 +1172,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1174,6 +1183,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1194,7 +1204,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -1274,6 +1283,7 @@ CONFIG_OCFS2_DEBUG_MASKLOG=y
# CONFIG_OCFS2_DEBUG_FS is not set
# CONFIG_OCFS2_FS_POSIX_ACL is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1343,7 +1353,6 @@ CONFIG_ROMFS_BACKED_BY_BLOCK=y
CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1451,6 +1460,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -1467,6 +1477,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
@@ -1486,10 +1497,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1514,10 +1527,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1550,7 +1563,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=m
@@ -1593,11 +1605,13 @@ CONFIG_CRYPTO_PCBC=m
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/powerpc/configs/adder875_defconfig b/arch/powerpc/configs/adder875_defconfig
index aece6bb5f733..052cf134e018 100644
--- a/arch/powerpc/configs/adder875_defconfig
+++ b/arch/powerpc/configs/adder875_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:47 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:04 2009
#
# CONFIG_PPC64 is not set
@@ -16,6 +16,7 @@ CONFIG_PPC_8xx=y
# CONFIG_E200 is not set
CONFIG_8xx=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_NOT_COHERENT_CACHE=y
CONFIG_PPC32=y
@@ -29,6 +30,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -78,11 +80,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -116,28 +119,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -235,10 +239,10 @@ CONFIG_BINFMT_ELF=y
# CONFIG_8XX_MINIMAL_FPEMU is not set
# CONFIG_IOMMU_HELPER is not set
# CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -256,6 +260,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -338,6 +343,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -367,6 +373,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -374,7 +381,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -387,6 +393,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -530,16 +537,15 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_SCC is not set
CONFIG_FS_ENET_HAS_FEC=y
CONFIG_FS_ENET_MDIO_FEC=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -580,6 +586,7 @@ CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
@@ -590,6 +597,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_VSXXXAA is not set
@@ -716,6 +724,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
@@ -775,7 +784,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -847,6 +855,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -864,6 +873,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
@@ -880,10 +890,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -906,10 +918,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig
index 8105360d53f4..0fb65a85dfdf 100644
--- a/arch/powerpc/configs/c2k_defconfig
+++ b/arch/powerpc/configs/c2k_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:48 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:05 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_PPC_STD_MMU=y
CONFIG_PPC_STD_MMU_32=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_PPC_HAVE_PMU_SUPPORT=y
+CONFIG_PPC_PERF_CTRS=y
# CONFIG_SMP is not set
CONFIG_NOT_COHERENT_CACHE=y
CONFIG_CHECK_CACHE_COHERENCY=y
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -88,11 +90,12 @@ CONFIG_AUDIT_TREE=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_GROUP_SCHED=y
@@ -135,23 +138,24 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
-CONFIG_MARKERS=y
CONFIG_OPROFILE=m
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
@@ -161,12 +165,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -275,12 +281,12 @@ CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
# CONFIG_IOMMU_HELPER is not set
# CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -298,6 +304,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -309,6 +316,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_EXTRA_TARGETS=""
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_RUNTIME is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y
@@ -674,10 +682,12 @@ CONFIG_BT_HCIBCM203X=m
# CONFIG_BT_HCIBPA10X is not set
CONFIG_BT_HCIBFUSB=m
CONFIG_BT_HCIVHCI=m
+# CONFIG_BT_MRVL is not set
# CONFIG_AF_RXRPC is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
@@ -686,7 +696,6 @@ CONFIG_WIRELESS_EXT_SYSFS=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -699,6 +708,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -710,9 +720,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=m
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
CONFIG_MTD_OF_PARTS=y
@@ -763,6 +773,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_GPIO_ADDR is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
@@ -857,6 +868,7 @@ CONFIG_SCSI_SRP_ATTRS=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
CONFIG_BLK_DEV_3W_XXXX_RAID=m
CONFIG_SCSI_3W_9XXX=m
CONFIG_SCSI_ACARD=m
@@ -912,7 +924,9 @@ CONFIG_SCSI_LPFC=m
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -982,7 +996,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -1010,10 +1026,7 @@ CONFIG_MV643XX_ETH=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -1145,6 +1158,7 @@ CONFIG_MAX_RAW_DEVS=8192
CONFIG_DEVPORT=y
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_HELPER_AUTO=y
@@ -1200,9 +1214,6 @@ CONFIG_I2C_MV64XXX=m
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-CONFIG_SENSORS_PCF8574=m
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1220,6 +1231,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=m
CONFIG_HWMON_VID=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
CONFIG_SENSORS_ADM1021=m
@@ -1269,6 +1285,7 @@ CONFIG_SENSORS_SMSC47B397=m
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
CONFIG_SENSORS_VIA686A=m
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1280,7 +1297,6 @@ CONFIG_SENSORS_W83L785TS=m
# CONFIG_SENSORS_W83L786NG is not set
CONFIG_SENSORS_W83627HF=m
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1317,6 +1333,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1327,6 +1344,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1378,6 +1396,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1588,6 +1607,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1668,7 +1688,6 @@ CONFIG_VXFS_FS=m
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1770,7 +1789,7 @@ CONFIG_BINARY_PRINTF=y
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=m
CONFIG_CRC_T10DIF=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
@@ -1797,6 +1816,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -1814,6 +1834,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
@@ -1834,11 +1855,13 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
@@ -1852,6 +1875,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
@@ -1869,6 +1893,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1899,6 +1924,7 @@ CONFIG_SECURITY_NETWORK=y
# CONFIG_SECURITY_NETWORK_XFRM is not set
# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_LSM_MMAP_MIN_ADDR=65536
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
@@ -1913,7 +1939,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=m
@@ -1956,11 +1981,13 @@ CONFIG_CRYPTO_ECB=m
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/powerpc/configs/ep8248e_defconfig b/arch/powerpc/configs/ep8248e_defconfig
index 0aa5b43ffeb2..ef5edc7203f5 100644
--- a/arch/powerpc/configs/ep8248e_defconfig
+++ b/arch/powerpc/configs/ep8248e_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:49 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:06 2009
#
# CONFIG_PPC64 is not set
@@ -34,6 +34,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -82,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -116,28 +118,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -150,6 +153,7 @@ CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
# CONFIG_BLK_DEV_INTEGRITY is not set
#
@@ -233,6 +237,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_FLATMEM=y
@@ -246,6 +251,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -394,6 +400,7 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_BT is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -401,7 +408,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
@@ -413,6 +419,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -600,7 +607,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_SCC is not set
CONFIG_FS_ENET_HAS_FCC=y
@@ -648,10 +657,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -736,15 +742,19 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -767,6 +777,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -968,6 +979,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -998,10 +1010,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1024,6 +1038,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1052,7 +1067,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1094,6 +1108,7 @@ CONFIG_CRYPTO_PCBC=y
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/ep88xc_defconfig b/arch/powerpc/configs/ep88xc_defconfig
index 2c292e25cc01..73ef9be41280 100644
--- a/arch/powerpc/configs/ep88xc_defconfig
+++ b/arch/powerpc/configs/ep88xc_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:49 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:07 2009
#
# CONFIG_PPC64 is not set
@@ -16,6 +16,7 @@ CONFIG_PPC_8xx=y
# CONFIG_E200 is not set
CONFIG_8xx=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_NOT_COHERENT_CACHE=y
CONFIG_PPC32=y
@@ -29,6 +30,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -77,11 +79,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -115,28 +118,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -234,10 +238,10 @@ CONFIG_BINFMT_ELF=y
CONFIG_8XX_MINIMAL_FPEMU=y
# CONFIG_IOMMU_HELPER is not set
# CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -255,6 +259,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -337,6 +342,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -366,6 +372,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -373,7 +380,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -386,6 +392,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -529,16 +536,15 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_SCC is not set
CONFIG_FS_ENET_HAS_FEC=y
CONFIG_FS_ENET_MDIO_FEC=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -611,7 +617,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -672,6 +677,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
@@ -731,7 +737,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -803,6 +808,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -820,6 +826,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
@@ -836,10 +843,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -861,10 +870,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig
index 45671e7dd2c7..63c3e8de8f16 100644
--- a/arch/powerpc/configs/linkstation_defconfig
+++ b/arch/powerpc/configs/linkstation_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:50 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:08 2009
#
# CONFIG_PPC64 is not set
@@ -34,6 +34,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -83,11 +84,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -131,22 +133,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_COMPAT_BRK is not set
# 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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -154,11 +155,13 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
#
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -258,6 +261,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -275,6 +279,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -482,6 +487,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -511,6 +517,7 @@ CONFIG_IP_NF_ARP_MANGLE=m
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
@@ -519,7 +526,6 @@ CONFIG_WIRELESS_EXT_SYSFS=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -532,6 +538,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -543,9 +550,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
@@ -711,6 +718,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -750,11 +758,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -777,6 +788,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -804,6 +816,7 @@ CONFIG_PATA_IT821X=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -870,7 +883,9 @@ CONFIG_TULIP_MMIO=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -918,10 +933,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -1043,6 +1055,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -1097,9 +1110,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1117,6 +1127,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1166,6 +1181,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1177,9 +1193,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1198,6 +1212,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1208,6 +1223,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1227,7 +1243,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=m
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1271,6 +1286,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1500,6 +1516,7 @@ CONFIG_XFS_FS=m
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1567,7 +1584,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1681,6 +1697,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1698,6 +1715,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1716,10 +1734,12 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1742,6 +1762,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1771,7 +1792,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1813,11 +1833,13 @@ CONFIG_CRYPTO_PCBC=m
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig
index 30b68bfacebf..520b04a0def9 100644
--- a/arch/powerpc/configs/mgcoge_defconfig
+++ b/arch/powerpc/configs/mgcoge_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc5
-# Fri Aug 7 08:19:15 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:09 2009
#
# CONFIG_PPC64 is not set
@@ -34,6 +34,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -84,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -123,28 +125,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -247,6 +250,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_FLATMEM=y
@@ -260,6 +264,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -390,6 +395,7 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_BT is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -397,7 +403,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
@@ -409,6 +414,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -608,7 +614,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
CONFIG_FS_ENET_HAS_SCC=y
CONFIG_FS_ENET_HAS_FCC=y
@@ -616,10 +624,7 @@ CONFIG_FS_ENET_MDIO_FCC=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -685,6 +690,7 @@ CONFIG_HW_RANDOM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -740,7 +746,6 @@ CONFIG_I2C_CPM=y
#
# Miscellaneous I2C Chip support
#
-# CONFIG_PCF8575 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -771,15 +776,19 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -799,6 +808,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -809,6 +819,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1022,6 +1033,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -1052,10 +1064,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1079,6 +1093,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1109,7 +1124,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1151,6 +1165,7 @@ CONFIG_CRYPTO_PCBC=y
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/mgsuvd_defconfig b/arch/powerpc/configs/mgsuvd_defconfig
index 1ae85a3b2942..43c3c4fcdce3 100644
--- a/arch/powerpc/configs/mgsuvd_defconfig
+++ b/arch/powerpc/configs/mgsuvd_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:52 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:10 2009
#
# CONFIG_PPC64 is not set
@@ -16,6 +16,7 @@ CONFIG_PPC_8xx=y
# CONFIG_E200 is not set
CONFIG_8xx=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_NOT_COHERENT_CACHE=y
CONFIG_PPC32=y
@@ -29,6 +30,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -76,11 +78,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_GROUP_SCHED=y
@@ -117,27 +120,28 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -237,10 +241,10 @@ CONFIG_BINFMT_ELF=y
CONFIG_MATH_EMULATION=y
# CONFIG_IOMMU_HELPER is not set
# CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -258,6 +262,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -344,6 +349,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -373,6 +379,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -380,7 +387,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -553,16 +559,15 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
CONFIG_FS_ENET_HAS_SCC=y
# CONFIG_FS_ENET_HAS_FEC is not set
# CONFIG_FS_ENET_MDIO_FEC is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -635,7 +640,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -707,6 +711,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -776,7 +781,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -851,6 +855,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -865,6 +870,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -887,7 +893,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -918,11 +923,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig
index aaa4416660e9..523d5fe18c0e 100644
--- a/arch/powerpc/configs/mpc5200_defconfig
+++ b/arch/powerpc/configs/mpc5200_defconfig
@@ -1,25 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Mon Apr 20 11:06:25 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:21 2009
#
# CONFIG_PPC64 is not set
#
# Processor support
#
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
CONFIG_PPC_FPU=y
# CONFIG_ALTIVEC is not set
CONFIG_PPC_STD_MMU=y
CONFIG_PPC_STD_MMU_32=y
# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
# CONFIG_SMP is not set
CONFIG_PPC32=y
CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=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_GENERIC_GPIO=y
# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
@@ -53,12 +57,14 @@ CONFIG_OF=y
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
CONFIG_DEFAULT_UIMAGE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -79,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_GROUP_SCHED is not set
@@ -103,7 +110,6 @@ CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -116,6 +122,13 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
@@ -124,14 +137,19 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
@@ -144,7 +162,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -205,7 +223,7 @@ CONFIG_RTAS_PROC=y
CONFIG_PPC_BESTCOMM=y
CONFIG_PPC_BESTCOMM_ATA=y
CONFIG_PPC_BESTCOMM_FEC=y
-# CONFIG_SIMPLE_GPIO is not set
+CONFIG_SIMPLE_GPIO=y
#
# Kernel options
@@ -229,11 +247,13 @@ CONFIG_BINFMT_ELF=y
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -249,9 +269,10 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
# CONFIG_PPC_64K_PAGES is not set
@@ -265,6 +286,7 @@ CONFIG_PM=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y
@@ -349,6 +371,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -363,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -388,6 +412,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -397,9 +422,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
@@ -458,6 +483,7 @@ CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -493,6 +519,7 @@ CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
CONFIG_OF_SPI=y
+CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
@@ -529,7 +556,9 @@ CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_AT24=y
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -552,10 +581,6 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
@@ -572,6 +597,8 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -580,6 +607,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
@@ -599,7 +627,6 @@ 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
@@ -611,11 +638,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -637,6 +667,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -665,6 +696,7 @@ CONFIG_PATA_MPC52xx=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -684,14 +716,17 @@ CONFIG_PATA_PLATFORM=y
#
#
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
#
# 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_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -739,16 +774,17 @@ CONFIG_NET_ETHERNET=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
CONFIG_FEC_MPC52xx=y
CONFIG_FEC_MPC52xx_MDIO=y
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -854,6 +890,7 @@ CONFIG_LEGACY_PTY_COUNT=256
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y
@@ -883,6 +920,7 @@ CONFIG_I2C_ALGOBIT=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
+# CONFIG_I2C_DESIGNWARE is not set
# CONFIG_I2C_GPIO is not set
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
@@ -910,10 +948,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -935,6 +969,11 @@ CONFIG_SPI_MPC52xx_PSC=m
#
CONFIG_SPI_SPIDEV=m
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y
@@ -957,16 +996,27 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADCXX is not set
@@ -1019,6 +1069,8 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1031,9 +1083,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1073,31 +1123,20 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
CONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
@@ -1167,6 +1206,7 @@ CONFIG_FB_RADEON_BACKLIGHT=y
# CONFIG_FB_BROADSHEET is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_LMS283GF05 is not set
# CONFIG_LCD_LTV350QV is not set
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_TDO24M is not set
@@ -1198,7 +1238,6 @@ CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1217,10 +1256,11 @@ CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
# CONFIG_HID_CHICONY is not set
CONFIG_HID_CYPRESS=y
-# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_DRAGONRISE is not set
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LOGITECH is not set
# CONFIG_HID_MICROSOFT is not set
@@ -1231,10 +1271,11 @@ CONFIG_HID_EZKEY=y
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SONY is not set
# CONFIG_HID_SUNPLUS is not set
-# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
# CONFIG_HID_TOPSEED is not set
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1261,15 +1302,17 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
# CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_SOC=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_HCD_PCI=y
CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -1400,6 +1443,7 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
#
# SPI RTC drivers
@@ -1411,6 +1455,7 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1434,6 +1479,10 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -1453,10 +1502,13 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1533,12 +1585,12 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_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=y
+# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
@@ -1624,6 +1676,7 @@ CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
#
# Kernel hacking
@@ -1633,6 +1686,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1650,10 +1704,14 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK 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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1665,11 +1723,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -1678,23 +1737,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1719,7 +1780,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1761,11 +1821,13 @@ CONFIG_CRYPTO_CBC=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig
index f23428c3b34e..d8b364a45944 100644
--- a/arch/powerpc/configs/mpc7448_hpc2_defconfig
+++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:53 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:10 2009
#
# CONFIG_PPC64 is not set
@@ -34,6 +34,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -82,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -123,28 +125,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -241,6 +244,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -258,6 +262,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -350,6 +355,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -379,6 +385,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -386,7 +393,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -399,6 +405,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -478,6 +485,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -517,11 +525,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -543,6 +554,7 @@ CONFIG_SATA_MV=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -570,6 +582,7 @@ CONFIG_SATA_MV=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -666,9 +679,11 @@ CONFIG_8139TOO=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -715,10 +730,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -822,6 +834,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
@@ -836,9 +853,7 @@ CONFIG_HWMON=y
# 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 is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -861,6 +876,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -874,7 +890,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -939,6 +954,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -997,7 +1013,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1069,6 +1084,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1086,6 +1102,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1107,7 +1124,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1138,11 +1154,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/mpc8272_ads_defconfig b/arch/powerpc/configs/mpc8272_ads_defconfig
index 02716f72db6f..00fad81b6fce 100644
--- a/arch/powerpc/configs/mpc8272_ads_defconfig
+++ b/arch/powerpc/configs/mpc8272_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:54 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:11 2009
#
# CONFIG_PPC64 is not set
@@ -34,6 +34,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -82,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -116,29 +118,30 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -151,6 +154,7 @@ CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
# CONFIG_BLK_DEV_INTEGRITY is not set
#
@@ -236,6 +240,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_FLATMEM=y
@@ -249,6 +254,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -397,6 +403,7 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_BT is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -404,7 +411,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
@@ -416,6 +422,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -477,7 +484,6 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_PHYSMAP_OF=y
-# CONFIG_MTD_SBC8240 is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
@@ -604,7 +610,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_SCC is not set
CONFIG_FS_ENET_HAS_FCC=y
@@ -652,10 +660,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -704,6 +709,7 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_KEYBOARD_MATRIX is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
@@ -714,6 +720,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_VSXXXAA is not set
@@ -793,15 +800,19 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -824,6 +835,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1032,6 +1044,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1067,10 +1080,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1093,6 +1108,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1121,7 +1137,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1163,6 +1178,7 @@ CONFIG_CRYPTO_PCBC=y
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig
index 4a96cb6925b4..64dff21516cb 100644
--- a/arch/powerpc/configs/mpc83xx_defconfig
+++ b/arch/powerpc/configs/mpc83xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:55 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:12 2009
#
# CONFIG_PPC64 is not set
@@ -35,6 +35,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -86,11 +87,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -127,21 +129,20 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -149,6 +150,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -263,6 +266,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -280,6 +284,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -343,7 +348,8 @@ 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 is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
@@ -358,7 +364,7 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_ESP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
@@ -377,6 +383,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -406,6 +413,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -413,7 +421,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -426,6 +433,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -433,9 +441,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
CONFIG_MTD_OF_PARTS=y
@@ -608,6 +616,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -647,11 +656,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -674,6 +686,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -701,6 +714,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -777,7 +791,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -800,7 +816,6 @@ CONFIG_NETDEV_1000=y
CONFIG_FSL_PQ_MDIO=y
CONFIG_GIANFAR=y
CONFIG_UCC_GETH=y
-# CONFIG_UGETH_MAGIC_PACKET is not set
# CONFIG_UGETH_TX_ON_DEMAND is not set
# CONFIG_MV643XX_ETH is not set
# CONFIG_QLA3XXX is not set
@@ -828,10 +843,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -935,6 +947,7 @@ CONFIG_GEN_RTC=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -990,9 +1003,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1025,14 +1035,24 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1083,6 +1103,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1094,9 +1115,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1135,6 +1154,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1145,6 +1165,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1158,7 +1179,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1181,6 +1201,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1233,6 +1254,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_FHCI_HCD is not set
@@ -1291,6 +1313,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
@@ -1338,6 +1361,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1397,7 +1421,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1514,6 +1537,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1529,6 +1553,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1550,7 +1575,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
@@ -1591,13 +1615,15 @@ CONFIG_CRYPTO_PCBC=m
#
# Hash modes
#
-# CONFIG_CRYPTO_HMAC is not set
+CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1605,16 +1631,16 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
#
# Ciphers
#
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index ee6acc6557f8..a12e7ba87a43 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:55 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:25:20 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
# CONFIG_SMP is not set
@@ -36,6 +37,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -88,11 +90,12 @@ CONFIG_AUDIT=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -131,22 +134,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -154,7 +156,9 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -189,6 +193,7 @@ CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_FREEZER is not set
+CONFIG_PPC_MSI_BITMAP=y
#
# Platform support
@@ -206,7 +211,7 @@ CONFIG_MPC85xx_DS=y
CONFIG_MPC85xx_RDB=y
CONFIG_SOCRATES=y
CONFIG_KSI8560=y
-# CONFIG_XES_MPC85xx is not set
+CONFIG_XES_MPC85xx=y
CONFIG_STX_GP3=y
CONFIG_TQM8540=y
CONFIG_TQM8541=y
@@ -259,10 +264,10 @@ CONFIG_BINFMT_MISC=m
CONFIG_MATH_EMULATION=y
CONFIG_IOMMU_HELPER=y
CONFIG_SWIOTLB=y
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -280,6 +285,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -307,7 +313,7 @@ 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_MSI=y
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
@@ -315,7 +321,8 @@ CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
CONFIG_HAS_RAPIDIO=y
-# CONFIG_RAPIDIO is not set
+CONFIG_RAPIDIO=y
+CONFIG_RAPIDIO_DISC_TIMEOUT=30
#
# Advanced setup
@@ -345,7 +352,7 @@ CONFIG_XFRM_USER=y
# 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=y
# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -369,12 +376,12 @@ CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_ESP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
@@ -411,6 +418,7 @@ CONFIG_IP_SCTP=m
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -441,6 +449,7 @@ CONFIG_SCTP_HMAC_MD5=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -448,7 +457,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -461,6 +469,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -554,6 +563,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -593,11 +603,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SIL24 is not set
@@ -620,6 +633,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_ALI=y
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -647,6 +661,7 @@ CONFIG_PATA_ALI=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -723,7 +738,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
CONFIG_FS_ENET_HAS_SCC=y
CONFIG_FS_ENET_HAS_FCC=y
@@ -750,7 +767,6 @@ CONFIG_NETDEV_1000=y
CONFIG_FSL_PQ_MDIO=y
CONFIG_GIANFAR=y
CONFIG_UCC_GETH=y
-# CONFIG_UGETH_MAGIC_PACKET is not set
# CONFIG_UGETH_TX_ON_DEMAND is not set
# CONFIG_MV643XX_ETH is not set
# CONFIG_QLA3XXX is not set
@@ -778,10 +794,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -798,6 +811,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
+# CONFIG_RIONET is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
@@ -898,6 +912,7 @@ CONFIG_NVRAM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
@@ -955,9 +970,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -991,15 +1003,19 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1020,6 +1036,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1030,6 +1047,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1049,6 +1067,7 @@ CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
@@ -1152,7 +1171,6 @@ CONFIG_SND_USB=y
CONFIG_AC97_BUS=y
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1175,6 +1193,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1227,6 +1246,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
@@ -1241,7 +1261,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_WHCI_HCD is not set
# CONFIG_USB_HWA_HCD is not set
-# CONFIG_USB_MUSB_HDRC is not set
#
# USB Device Class drivers
@@ -1429,6 +1448,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1499,7 +1519,6 @@ CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_UFS_DEBUG is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1620,6 +1639,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -1637,6 +1657,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1656,10 +1677,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1683,10 +1706,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1714,7 +1737,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
@@ -1757,11 +1779,13 @@ CONFIG_CRYPTO_PCBC=m
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1769,16 +1793,16 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
-CONFIG_CRYPTO_SHA1=m
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
#
# Ciphers
#
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index db082ce5a1c5..cd70b4a4ce01 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:56 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:26:01 2009
#
# CONFIG_PPC64 is not set
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
# CONFIG_PHYS_64BIT is not set
CONFIG_SPE=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_SMP=y
@@ -37,6 +38,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -89,11 +91,12 @@ CONFIG_AUDIT=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -132,22 +135,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -155,8 +157,10 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -192,6 +196,7 @@ CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_FREEZER is not set
+CONFIG_PPC_MSI_BITMAP=y
#
# Platform support
@@ -206,9 +211,10 @@ CONFIG_MPC85xx_CDS=y
CONFIG_MPC85xx_MDS=y
CONFIG_MPC8536_DS=y
CONFIG_MPC85xx_DS=y
+CONFIG_MPC85xx_RDB=y
CONFIG_SOCRATES=y
CONFIG_KSI8560=y
-# CONFIG_XES_MPC85xx is not set
+CONFIG_XES_MPC85xx=y
CONFIG_STX_GP3=y
CONFIG_TQM8540=y
CONFIG_TQM8541=y
@@ -261,11 +267,11 @@ CONFIG_BINFMT_MISC=m
CONFIG_MATH_EMULATION=y
CONFIG_IOMMU_HELPER=y
CONFIG_SWIOTLB=y
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -283,6 +289,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -310,7 +317,7 @@ 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_MSI=y
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
@@ -318,7 +325,8 @@ CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
CONFIG_HAS_RAPIDIO=y
-# CONFIG_RAPIDIO is not set
+CONFIG_RAPIDIO=y
+CONFIG_RAPIDIO_DISC_TIMEOUT=30
#
# Advanced setup
@@ -348,7 +356,7 @@ CONFIG_XFRM_USER=y
# 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=y
# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -372,12 +380,12 @@ CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_ESP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
@@ -414,6 +422,7 @@ CONFIG_IP_SCTP=m
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -444,6 +453,7 @@ CONFIG_SCTP_HMAC_MD5=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -451,7 +461,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -464,6 +473,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -557,6 +567,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -596,11 +607,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SIL24 is not set
@@ -623,6 +637,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_ALI=y
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -650,6 +665,7 @@ CONFIG_PATA_ALI=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -726,7 +742,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
CONFIG_FS_ENET_HAS_SCC=y
CONFIG_FS_ENET_HAS_FCC=y
@@ -753,7 +771,6 @@ CONFIG_NETDEV_1000=y
CONFIG_FSL_PQ_MDIO=y
CONFIG_GIANFAR=y
CONFIG_UCC_GETH=y
-# CONFIG_UGETH_MAGIC_PACKET is not set
# CONFIG_UGETH_TX_ON_DEMAND is not set
# CONFIG_MV643XX_ETH is not set
# CONFIG_QLA3XXX is not set
@@ -781,10 +798,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -801,6 +815,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
+# CONFIG_RIONET is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
@@ -901,6 +916,7 @@ CONFIG_NVRAM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
@@ -958,9 +974,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -994,15 +1007,19 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1023,6 +1040,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1033,6 +1051,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1052,6 +1071,7 @@ CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
@@ -1155,7 +1175,6 @@ CONFIG_SND_USB=y
CONFIG_AC97_BUS=y
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1178,6 +1197,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1230,6 +1250,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
@@ -1244,7 +1265,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_WHCI_HCD is not set
# CONFIG_USB_HWA_HCD is not set
-# CONFIG_USB_MUSB_HDRC is not set
#
# USB Device Class drivers
@@ -1432,6 +1452,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1502,7 +1523,6 @@ CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_UFS_DEBUG is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1623,6 +1643,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -1640,6 +1661,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1659,10 +1681,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1686,10 +1710,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1717,7 +1741,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
@@ -1760,11 +1783,13 @@ CONFIG_CRYPTO_PCBC=m
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1772,16 +1797,16 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
-CONFIG_CRYPTO_SHA1=m
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
#
# Ciphers
#
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
diff --git a/arch/powerpc/configs/mpc866_ads_defconfig b/arch/powerpc/configs/mpc866_ads_defconfig
index 6809b61ed3de..40d6f0568ca5 100644
--- a/arch/powerpc/configs/mpc866_ads_defconfig
+++ b/arch/powerpc/configs/mpc866_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:57 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:15 2009
#
# CONFIG_PPC64 is not set
@@ -16,6 +16,7 @@ CONFIG_PPC_8xx=y
# CONFIG_E200 is not set
CONFIG_8xx=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_NOT_COHERENT_CACHE=y
CONFIG_PPC32=y
@@ -29,6 +30,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -76,11 +78,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -113,28 +116,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -233,10 +237,10 @@ CONFIG_BINFMT_ELF=y
CONFIG_MATH_EMULATION=y
# CONFIG_IOMMU_HELPER is not set
# CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -254,6 +258,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -340,6 +345,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -369,6 +375,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -376,7 +383,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -467,6 +473,8 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
CONFIG_FS_ENET_HAS_SCC=y
CONFIG_FS_ENET_HAS_FEC=y
@@ -476,10 +484,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_GIANFAR is not set
# CONFIG_MV643XX_ETH is not set
CONFIG_NETDEV_10000=y
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -520,6 +525,7 @@ CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
@@ -530,6 +536,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_VSXXXAA is not set
@@ -595,6 +602,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_IT87 is not set
@@ -605,9 +617,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -641,7 +651,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -705,6 +714,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -763,7 +773,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -836,6 +845,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -851,6 +861,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -871,7 +882,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -902,11 +912,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/mpc86xx_defconfig b/arch/powerpc/configs/mpc86xx_defconfig
index 0e8684a3138d..5b3abb42ae30 100644
--- a/arch/powerpc/configs/mpc86xx_defconfig
+++ b/arch/powerpc/configs/mpc86xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:58 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:16 2009
#
# CONFIG_PPC64 is not set
@@ -36,6 +36,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -88,11 +89,12 @@ CONFIG_AUDIT=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -131,22 +133,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_EFFICIENT_UNALIGNED_ACCESS=y
@@ -154,7 +155,9 @@ CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -253,13 +256,13 @@ CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
CONFIG_IOMMU_HELPER=y
CONFIG_SWIOTLB=y
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
# CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -277,6 +280,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -406,6 +410,7 @@ CONFIG_IP_SCTP=m
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -436,6 +441,7 @@ CONFIG_SCTP_HMAC_MD5=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -443,7 +449,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -456,6 +461,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -549,6 +555,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -588,11 +595,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SIL24 is not set
@@ -615,6 +625,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_ALI=y
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -642,6 +653,7 @@ CONFIG_PATA_ALI=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -718,7 +730,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -766,10 +780,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -883,6 +894,7 @@ CONFIG_NVRAM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
@@ -938,9 +950,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -974,15 +983,19 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1003,6 +1016,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1013,6 +1027,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1032,6 +1047,7 @@ CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
@@ -1135,7 +1151,6 @@ CONFIG_SND_USB=y
CONFIG_AC97_BUS=y
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1158,6 +1173,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1210,6 +1226,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
@@ -1389,6 +1406,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1459,7 +1477,6 @@ CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_UFS_DEBUG is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1577,6 +1594,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1594,6 +1612,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1613,10 +1632,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1639,10 +1660,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
@@ -1669,7 +1690,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1711,11 +1731,13 @@ CONFIG_CRYPTO_PCBC=m
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig
index dbe8e869a827..1da3488a603d 100644
--- a/arch/powerpc/configs/mpc885_ads_defconfig
+++ b/arch/powerpc/configs/mpc885_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:59 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:17 2009
#
# CONFIG_PPC64 is not set
@@ -16,6 +16,7 @@ CONFIG_PPC_8xx=y
# CONFIG_E200 is not set
CONFIG_8xx=y
CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_NOT_COHERENT_CACHE=y
CONFIG_PPC32=y
@@ -29,6 +30,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -77,11 +79,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -115,28 +118,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -241,10 +245,10 @@ CONFIG_BINFMT_ELF=y
CONFIG_8XX_MINIMAL_FPEMU=y
# CONFIG_IOMMU_HELPER is not set
# CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -262,6 +266,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -344,6 +349,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -373,6 +379,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -380,7 +387,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -393,6 +399,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -540,16 +547,15 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_SCC is not set
CONFIG_FS_ENET_HAS_FEC=y
CONFIG_FS_ENET_MDIO_FEC=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -622,7 +628,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -683,6 +688,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
@@ -742,7 +748,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -814,6 +819,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -831,6 +837,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
@@ -847,10 +854,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -872,10 +881,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig
index 4f8681cc8d77..20ba0cfff8ba 100644
--- a/arch/powerpc/configs/pasemi_defconfig
+++ b/arch/powerpc/configs/pasemi_defconfig
@@ -1,49 +1,58 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc3
-# Tue May 27 16:08:06 2008
+# Linux kernel version: 2.6.32-rc3
+# Tue Oct 6 10:27:18 2009
#
CONFIG_PPC64=y
#
# Processor support
#
+CONFIG_PPC_BOOK3S_64=y
+# CONFIG_PPC_BOOK3E_64 is not set
+CONFIG_PPC_BOOK3S=y
CONFIG_POWER4_ONLY=y
CONFIG_POWER4=y
# CONFIG_TUNE_CELL is not set
CONFIG_PPC_FPU=y
CONFIG_ALTIVEC=y
+# CONFIG_VSX is not set
CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_64=y
CONFIG_PPC_MM_SLICES=y
# CONFIG_VIRT_CPU_ACCOUNTING is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
+CONFIG_PPC_PERF_CTRS=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_64BIT=y
CONFIG_WORD_SIZE=64
-CONFIG_PPC_MERGE=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=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_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
CONFIG_ARCH_HAS_ILOG2_U64=y
CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_ARCH_NO_VIRT_TO_BUS=y
CONFIG_PPC=y
CONFIG_EARLY_PRINTK=y
CONFIG_COMPAT=y
CONFIG_SYSVIPC_COMPAT=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_PPC_OF=y
CONFIG_OF=y
@@ -51,11 +60,14 @@ CONFIG_PPC_UDBG_16550=y
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
# CONFIG_DEFAULT_UIMAGE is not set
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
# CONFIG_PPC_OF_PLATFORM_PCI is not set
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -72,10 +84,20 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -84,13 +106,17 @@ CONFIG_NAMESPACES=y
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not set
CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -98,32 +124,52 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
+# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
+CONFIG_TRACEPOINTS=y
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -131,11 +177,10 @@ 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 is not set
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
CONFIG_BLOCK_COMPAT=y
#
@@ -150,19 +195,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_FREEZER is not set
+CONFIG_PPC_MSI_BITMAP=y
#
# Platform support
#
-CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_86xx is not set
# CONFIG_PPC_PSERIES is not set
# CONFIG_PPC_ISERIES is not set
-# CONFIG_PPC_MPC512x is not set
-# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_PMAC is not set
# CONFIG_PPC_MAPLE is not set
CONFIG_PPC_PASEMI=y
@@ -178,8 +218,10 @@ CONFIG_PPC_PASEMI_MDIO=y
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PPC_IBM_CELL_BLADE is not set
# CONFIG_PPC_CELLEB is not set
+# CONFIG_PPC_CELL_QPACE is not set
# CONFIG_PQ2ADS is not set
CONFIG_PPC_NATIVE=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
# CONFIG_IPIC is not set
CONFIG_MPIC=y
# CONFIG_MPIC_WEIRD is not set
@@ -213,6 +255,7 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=y
#
CONFIG_PPC_PASEMI_CPUFREQ=y
# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
#
# Kernel options
@@ -226,16 +269,19 @@ 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_SCHED_HRTICK=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
CONFIG_IOMMU_VMERGE=y
CONFIG_IOMMU_HELPER=y
+# CONFIG_SWIOTLB is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
@@ -243,6 +289,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_IRQ_ALL_CPUS is not set
# CONFIG_NUMA is not set
+CONFIG_MAX_ACTIVE_REGIONS=256
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -253,20 +300,28 @@ CONFIG_FLATMEM_MANUAL=y
# 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=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_HAS_HASH_64K=y
+# CONFIG_PPC_4K_PAGES is not set
+# CONFIG_PPC_16K_PAGES is not set
CONFIG_PPC_64K_PAGES=y
+# CONFIG_PPC_256K_PAGES is not set
CONFIG_FORCE_MAX_ZONEORDER=9
# CONFIG_PPC_SUBPAGE_PROT is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
# CONFIG_PM is not set
# CONFIG_SECCOMP is not set
CONFIG_ISA_DMA_API=y
@@ -285,6 +340,8 @@ CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=y
CONFIG_PCMCIA_DEBUG=y
CONFIG_PCMCIA=y
@@ -301,13 +358,10 @@ CONFIG_CARDBUS=y
CONFIG_ELECTRA_CF=y
# CONFIG_HOTPLUG_PCI is not set
# CONFIG_HAS_RAPIDIO is not set
+# CONFIG_RELOCATABLE is not set
CONFIG_PAGE_OFFSET=0xc000000000000000
CONFIG_KERNEL_START=0xc000000000000000
CONFIG_PHYSICAL_START=0x00000000
-
-#
-# Networking
-#
CONFIG_NET=y
#
@@ -356,9 +410,11 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
@@ -368,25 +424,32 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
#
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -398,15 +461,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
# CONFIG_MTD_PARTITIONS is not set
@@ -478,11 +545,17 @@ CONFIG_MTD_NAND_PASEMI=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
@@ -501,29 +574,41 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
+CONFIG_IDE_ATAPI=y
# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
# CONFIG_BLK_DEV_IDECS is not set
# CONFIG_BLK_DEV_DELKIN is not set
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-CONFIG_BLK_DEV_IDESCSI=y
CONFIG_IDE_TASK_IOCTL=y
CONFIG_IDE_PROC_FS=y
@@ -542,14 +627,13 @@ CONFIG_IDE_PROC_FS=y
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5520 is not set
# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
# CONFIG_BLK_DEV_IT8213 is not set
# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
@@ -563,8 +647,6 @@ CONFIG_IDE_PROC_FS=y
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_TC86C001 is not set
# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
@@ -586,10 +668,6 @@ CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
@@ -606,6 +684,8 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -614,11 +694,16 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS 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_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -626,7 +711,6 @@ 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
@@ -637,10 +721,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
CONFIG_SATA_SIL24=y
@@ -662,6 +750,7 @@ CONFIG_SATA_MV=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -690,6 +779,7 @@ CONFIG_ATA_GENERIC=y
CONFIG_PATA_PCMCIA=y
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -703,12 +793,15 @@ CONFIG_PATA_OF_PLATFORM=y
# CONFIG_PATA_SCH is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=y
CONFIG_MD_RAID456=y
-CONFIG_MD_RAID5_RESHAPE=y
+# CONFIG_MULTICORE_RAID456 is not set
+CONFIG_MD_RAID6_PQ=y
+# CONFIG_ASYNC_RAID6_TEST is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=y
@@ -725,12 +818,19 @@ CONFIG_DM_CRYPT=y
#
# IEEE 1394 (FireWire) support
#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
# 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=y
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -753,6 +853,9 @@ CONFIG_MARVELL_PHY=y
# CONFIG_BROADCOM_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
# CONFIG_FIXED_PHY is not set
# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
@@ -761,19 +864,23 @@ CONFIG_MII=y
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET 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_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
@@ -783,19 +890,22 @@ CONFIG_NET_PCI=y
# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
CONFIG_E1000=y
-CONFIG_E1000_NAPI=y
-# 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_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -806,30 +916,40 @@ CONFIG_E1000_NAPI=y
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=y
# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
CONFIG_PASEMI_MAC=y
+# CONFIG_MLX4_EN is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# USB Network Adapters
@@ -874,17 +994,23 @@ CONFIG_INPUT_EVDEV=y
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
@@ -900,6 +1026,7 @@ CONFIG_INPUT_MOUSE=y
# Character devices
#
CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
@@ -926,10 +1053,13 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=4
+# CONFIG_HVC_UDBG is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
CONFIG_HW_RANDOM_PASEMI=y
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -948,57 +1078,85 @@ CONFIG_MAX_RAW_DEVS=256
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y
#
# I2C Hardware Bus support
#
+
+#
+# PC SMBus host controller drivers
+#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-CONFIG_I2C_PASEMI=y
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PASEMI=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
#
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-CONFIG_EEPROM_LEGACY=y
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
@@ -1006,14 +1164,17 @@ CONFIG_HWMON_VID=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -1028,10 +1189,14 @@ CONFIG_SENSORS_LM85=y
CONFIG_SENSORS_LM90=y
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -1039,6 +1204,8 @@ CONFIG_SENSORS_LM90=y
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1050,44 +1217,40 @@ CONFIG_SENSORS_LM90=y
# 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
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
# Multifunction device drivers
#
+# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
CONFIG_DRM=y
+CONFIG_DRM_KMS_HELPER=y
+CONFIG_DRM_TTM=y
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
CONFIG_DRM_RADEON=y
@@ -1099,6 +1262,7 @@ CONFIG_VGASTATE=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_DDC=y
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
@@ -1140,6 +1304,7 @@ CONFIG_FB_RADEON_BACKLIGHT=y
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
@@ -1148,12 +1313,16 @@ CONFIG_FB_RADEON_BACKLIGHT=y
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
# CONFIG_FB_IBM_GXT4500 is not set
# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
#
# Display device support
@@ -1177,15 +1346,9 @@ CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
@@ -1198,24 +1361,24 @@ CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_HRTIMER is not set
# 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_RAWMIDI_SEQ=y
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
-
-#
-# PCI devices
-#
+CONFIG_SND_PCI=y
# CONFIG_SND_AD1889 is not set
# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALS4000 is not set
@@ -1234,6 +1397,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS5530 is not set
+# CONFIG_SND_CTXFI is not set
# CONFIG_SND_DARLA20 is not set
# CONFIG_SND_GINA20 is not set
# CONFIG_SND_LAYLA20 is not set
@@ -1246,6 +1410,8 @@ CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -1262,6 +1428,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_INTEL8X0 is not set
# CONFIG_SND_INTEL8X0M is not set
# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_LX6464ES is not set
# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
@@ -1277,57 +1444,64 @@ CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VIRTUOSO is not set
# CONFIG_SND_VX222 is not set
# CONFIG_SND_YMFPCI is not set
-
-#
-# ALSA PowerMac devices
-#
-
-#
-# ALSA PowerPC devices
-#
-
-#
-# USB devices
-#
+CONFIG_SND_PPC=y
+CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
CONFIG_SND_USB_USX2Y=y
# CONFIG_SND_USB_CAIAQ is not set
-
-#
-# PCMCIA devices
-#
+CONFIG_SND_PCMCIA=y
# CONFIG_SND_VXPOCKET is not set
# CONFIG_SND_PDAUDIOCF is not set
-
-#
-# System on Chip audio support
-#
# CONFIG_SND_SOC is not set
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# SoC Audio for the Texas Instruments OMAP
-#
-
-#
-# Open Sound System
-#
# CONFIG_SOUND_PRIME is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
# USB Input Devices
#
CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1343,18 +1517,26 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
CONFIG_USB_EHCI_HCD_PPC_OF=y
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
# CONFIG_USB_OHCI_HCD_PPC_OF is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -1363,6 +1545,8 @@ CONFIG_USB_UHCI_HCD=y
CONFIG_USB_SL811_HCD=y
# CONFIG_USB_SL811_CS is not set
# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
#
# USB Device Class drivers
@@ -1370,20 +1554,20 @@ CONFIG_USB_SL811_HCD=y
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# may also be needed; see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1399,7 +1583,6 @@ CONFIG_USB_LIBUSUAL=y
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
#
# USB port drivers
@@ -1412,7 +1595,7 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
@@ -1420,7 +1603,6 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1429,7 +1611,15 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1443,6 +1633,7 @@ CONFIG_EDAC=y
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_PASEMI=y
+# CONFIG_EDAC_CPC925 is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -1472,6 +1663,9 @@ CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
#
# SPI RTC drivers
@@ -1481,21 +1675,31 @@ CONFIG_RTC_DRV_DS1307=y
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
# on-CPU RTC drivers
#
+# CONFIG_RTC_DRV_GENERIC is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1504,11 +1708,13 @@ CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
@@ -1516,6 +1722,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_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1525,6 +1735,11 @@ CONFIG_AUTOFS4_FS=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
@@ -1549,16 +1764,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1578,8 +1791,10 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -1590,18 +1805,17 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
-CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1672,25 +1886,30 @@ CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
# CONFIG_DLM is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
#
CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
-CONFIG_LIBCRC32C=m
+# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
#
# Kernel hacking
@@ -1700,18 +1919,25 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=2048
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# 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
CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1721,26 +1947,71 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
-CONFIG_DEBUGGER=y
+# CONFIG_PPC_EMULATED_STATS is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
CONFIG_XMON=y
CONFIG_XMON_DEFAULT=y
CONFIG_XMON_DISASSEMBLY=y
+CONFIG_DEBUGGER=y
# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BOOTX_TEXT is not set
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -1749,23 +2020,34 @@ CONFIG_XMON_DISASSEMBLY=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
+CONFIG_ASYNC_PQ=y
+CONFIG_ASYNC_RAID6_RECOV=y
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set
@@ -1793,14 +2075,20 @@ CONFIG_CRYPTO_CBC=y
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
@@ -1830,7 +2118,13 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig
new file mode 100644
index 000000000000..18af46036258
--- /dev/null
+++ b/arch/powerpc/configs/ppc64e_defconfig
@@ -0,0 +1,2199 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Fri Oct 16 11:37:15 2009
+#
+CONFIG_PPC64=y
+
+#
+# Processor support
+#
+# CONFIG_PPC_BOOK3S_64 is not set
+CONFIG_PPC_BOOK3E_64=y
+CONFIG_PPC_BOOK3E=y
+CONFIG_PPC_FPU=y
+CONFIG_BOOKE=y
+CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_64=y
+CONFIG_PPC_BOOK3E_MMU=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
+CONFIG_PPC_PERF_CTRS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=32
+CONFIG_64BIT=y
+CONFIG_WORD_SIZE=64
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=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_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_ARCH_HAS_ILOG2_U64=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+# CONFIG_PPC_OF_PLATFORM_PCI is not set
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+# CONFIG_TASK_XACCT is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=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_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY 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_FREEZER is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_U3_DART 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=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# CPU Frequency drivers
+#
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+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=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_IOMMU_VMERGE=y
+CONFIG_IOMMU_HELPER=y
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_IRQ_ALL_CPUS=y
+# CONFIG_NUMA is not set
+CONFIG_MAX_ACTIVE_REGIONS=256
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_PPC_HAS_HASH_64K is not set
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+# CONFIG_SCHED_SMT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_HOTPLUG_PCI=m
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HAS_RAPIDIO is not set
+# CONFIG_RELOCATABLE is not set
+CONFIG_PAGE_OFFSET=0xc000000000000000
+CONFIG_KERNEL_START=0xc000000000000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+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_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE 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=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# 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=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=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_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# 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=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_EVENTS=y
+# CONFIG_NF_CT_PROTO_DCCP is not set
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+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 is not set
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_TPROXY=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_HL=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER 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_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+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_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=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 is not set
+CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+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_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=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_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_SCTP=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_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# 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_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_FD=y
+# 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=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+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=65536
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_XFER_MODE=y
+CONFIG_IDE_TIMINGS=y
+CONFIG_IDE_ATAPI=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+CONFIG_BLK_DEV_IDEDMA=y
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+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=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_SRP_ATTRS=y
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS 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_MPT2SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH 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=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+CONFIG_SCSI_SYM53C8XX_MMIO=y
+CONFIG_SCSI_IPR=y
+CONFIG_SCSI_IPR_TRACE=y
+CONFIG_SCSI_IPR_DUMP=y
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_LPFC_DEBUG_FS is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+CONFIG_SCSI_DEBUG=m
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SIL24=y
+CONFIG_ATA_SFF=y
+CONFIG_SATA_SVW=y
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 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_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=y
+CONFIG_MD_RAID456=y
+# CONFIG_MULTICORE_RAID456 is not set
+CONFIG_MD_RAID6_PQ=y
+# CONFIG_ASYNC_RAID6_TEST is not set
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+# CONFIG_DM_LOG_USERSPACE is not set
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_MULTIPATH_QL is not set
+# CONFIG_DM_MULTIPATH_ST is not set
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+CONFIG_IEEE1394=y
+CONFIG_IEEE1394_OHCI1394=y
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_RAWIO=y
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_DV1394=m
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+# CONFIG_I2O is not set
+CONFIG_MACINTOSH_DRIVERS=y
+# CONFIG_MAC_EMUMOUSEBTN is not set
+CONFIG_WINDFARM=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+CONFIG_BROADCOM_PHY=m
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+CONFIG_SUNGEM=y
+# CONFIG_CASSINI is not set
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+# CONFIG_TYPHOON is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET 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_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_R6040 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ACENIC=y
+CONFIG_ACENIC_OMIT_TIGON_I=y
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
+CONFIG_IXGB=m
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
+CONFIG_TR=y
+CONFIG_IBMOL=y
+# CONFIG_3C359 is not set
+# CONFIG_TMS380TR is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_NET_PCMCIA is not set
+# CONFIG_WAN 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=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NET_FC is not set
+CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+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 is not set
+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=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# 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=y
+# CONFIG_SERIAL_8250_CS is not set
+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_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+CONFIG_I2C_AMD8111=y
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_DDC=y
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# 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_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+CONFIG_FB_MACMODES=y
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# 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_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+CONFIG_FB_IBM_GXT4500=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+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
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=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_HRTIMER is not set
+# 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
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALS4000 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_AW2 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_CS5530 is not set
+# CONFIG_SND_CTXFI 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_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX 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_LX6464ES 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
+CONFIG_SND_PPC=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_PCMCIA=y
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_EHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+# CONFIG_USB_OHCI_HCD_PPC_OF 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+CONFIG_USB_APPLEDISPLAY=m
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_INFINIBAND=m
+# CONFIG_INFINIBAND_USER_MAD is not set
+# CONFIG_INFINIBAND_USER_ACCESS is not set
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+# CONFIG_INFINIBAND_IPATH is not set
+# CONFIG_INFINIBAND_AMSO1100 is not set
+# CONFIG_MLX4_INFINIBAND is not set
+# CONFIG_INFINIBAND_NES is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_CM is not set
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
+# CONFIG_INFINIBAND_SRP is not set
+CONFIG_INFINIBAND_ISER=m
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+# CONFIG_EDAC_CPC925 is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_GENERIC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING 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=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=y
+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 is not set
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_SUNRPC_XPRT_RDMA=m
+CONFIG_RPCSEC_GSS_KRB5=y
+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 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=y
+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 is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=2048
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_TRACE_IRQFLAGS=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_LATENCYTOP=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACER_MAX_TRACE=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_SCHED_TRACER=y
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_PPC_EMULATED_STATS is not set
+CONFIG_CODE_PATCHING_SELFTEST=y
+CONFIG_FTR_FIXUP_SELFTEST=y
+CONFIG_MSI_BITMAP_SELFTEST=y
+CONFIG_XMON=y
+# CONFIG_XMON_DEFAULT is not set
+CONFIG_XMON_DISASSEMBLY=y
+CONFIG_DEBUGGER=y
+CONFIG_IRQSTACKS=y
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_XOR_BLOCKS=y
+CONFIG_ASYNC_CORE=y
+CONFIG_ASYNC_MEMCPY=y
+CONFIG_ASYNC_XOR=y
+CONFIG_ASYNC_PQ=y
+CONFIG_ASYNC_RAID6_RECOV=y
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=m
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/pq2fads_defconfig b/arch/powerpc/configs/pq2fads_defconfig
index ff96bb43c32d..b7911216af78 100644
--- a/arch/powerpc/configs/pq2fads_defconfig
+++ b/arch/powerpc/configs/pq2fads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:00 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:17 2009
#
# CONFIG_PPC64 is not set
@@ -34,6 +34,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -82,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -120,29 +122,30 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -155,6 +158,7 @@ CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
# CONFIG_BLK_DEV_INTEGRITY is not set
#
@@ -239,6 +243,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_FLATMEM=y
@@ -252,6 +257,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -401,6 +407,7 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_BT is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -408,7 +415,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
@@ -420,6 +426,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -481,7 +488,6 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_PHYSMAP_OF=y
-# CONFIG_MTD_SBC8240 is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
@@ -664,7 +670,9 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_SCC is not set
CONFIG_FS_ENET_HAS_FCC=y
@@ -712,10 +720,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -764,6 +769,7 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_KEYBOARD_MATRIX is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
@@ -774,6 +780,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_APPLETOUCH is not set
@@ -855,15 +862,19 @@ CONFIG_GPIOLIB=y
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -886,6 +897,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -905,7 +917,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_USB is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_MUSB_HDRC is not set
# CONFIG_USB_GADGET_MUSB_HDRC is not set
#
@@ -922,6 +933,7 @@ CONFIG_USB_GADGET_SELECTED=y
# CONFIG_USB_GADGET_LH7A40X is not set
# CONFIG_USB_GADGET_OMAP is not set
# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
# CONFIG_USB_GADGET_PXA27X is not set
# CONFIG_USB_GADGET_S3C_HSOTG is not set
# CONFIG_USB_GADGET_IMX is not set
@@ -940,6 +952,7 @@ CONFIG_USB_GADGET_DUALSPEED=y
# CONFIG_USB_AUDIO is not set
CONFIG_USB_ETH=y
CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
# CONFIG_USB_GADGETFS is not set
# CONFIG_USB_FILE_STORAGE is not set
# CONFIG_USB_G_SERIAL is not set
@@ -1148,6 +1161,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1183,10 +1197,12 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1209,6 +1225,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1237,7 +1254,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
@@ -1279,6 +1295,7 @@ CONFIG_CRYPTO_PCBC=y
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/prpmc2800_defconfig b/arch/powerpc/configs/prpmc2800_defconfig
index 1293c465d7fa..ef50ce45d50b 100644
--- a/arch/powerpc/configs/prpmc2800_defconfig
+++ b/arch/powerpc/configs/prpmc2800_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:01 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:18 2009
#
# CONFIG_PPC64 is not set
@@ -36,6 +36,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -85,11 +86,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -131,28 +133,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -244,12 +247,12 @@ CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
# CONFIG_IOMMU_HELPER is not set
# CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -267,6 +270,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -360,6 +364,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -389,6 +394,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -396,7 +402,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -409,6 +414,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -633,6 +639,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -672,11 +679,14 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
@@ -698,6 +708,7 @@ CONFIG_SATA_MV=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
@@ -725,6 +736,7 @@ CONFIG_SATA_MV=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
@@ -823,9 +835,11 @@ CONFIG_8139TOO=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -871,10 +885,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -977,6 +988,7 @@ CONFIG_LEGACY_PTY_COUNT=256
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -1031,9 +1043,6 @@ CONFIG_I2C_MV64XXX=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1051,6 +1060,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -1100,6 +1114,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -1111,9 +1126,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1132,6 +1145,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -1142,6 +1156,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1162,7 +1177,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1186,6 +1200,7 @@ CONFIG_HID_DRAGONRISE=y
CONFIG_HID_EZKEY=y
CONFIG_HID_KYE=y
CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1239,6 +1254,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1404,6 +1420,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1463,7 +1480,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1576,6 +1592,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1593,6 +1610,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1614,7 +1632,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1645,11 +1662,13 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index f1889abb89b1..c568329723b8 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -1683,7 +1683,7 @@ CONFIG_HAVE_ARCH_KGDB=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PAGEALLOC is not set
-CONFIG_HCALL_STATS=y
+# CONFIG_HCALL_STATS is not set
# CONFIG_CODE_PATCHING_SELFTEST is not set
# CONFIG_FTR_FIXUP_SELFTEST is not set
# CONFIG_MSI_BITMAP_SELFTEST is not set
diff --git a/arch/powerpc/configs/storcenter_defconfig b/arch/powerpc/configs/storcenter_defconfig
index 28384dc01003..524263158fc0 100644
--- a/arch/powerpc/configs/storcenter_defconfig
+++ b/arch/powerpc/configs/storcenter_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:01 2009
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov 5 08:20:19 2009
#
# CONFIG_PPC64 is not set
@@ -34,6 +34,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -82,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -118,28 +120,29 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -243,6 +246,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -260,6 +264,7 @@ CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
@@ -349,6 +354,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -378,6 +384,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
@@ -385,7 +392,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
#
# CFG80211 needs to be enabled for MAC80211
#
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -398,6 +404,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -405,9 +412,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
@@ -619,6 +626,7 @@ CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -657,7 +665,9 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -670,6 +680,7 @@ CONFIG_MD_RAID1=y
# CONFIG_MD_RAID10 is not set
CONFIG_MD_RAID456=y
CONFIG_MD_RAID6_PQ=y
+# CONFIG_ASYNC_RAID6_TEST is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
# CONFIG_BLK_DEV_DM is not set
@@ -729,10 +740,7 @@ CONFIG_R8169=y
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
@@ -813,6 +821,7 @@ CONFIG_NVRAM=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -867,9 +876,6 @@ CONFIG_I2C_MPC=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -887,7 +893,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -906,6 +911,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
@@ -916,6 +922,7 @@ CONFIG_SSB_POSSIBLE=y
# Graphics support
#
# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -961,6 +968,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -1141,6 +1149,7 @@ CONFIG_XFS_FS=m
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
@@ -1210,7 +1219,6 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_EXPORTFS=m
@@ -1307,6 +1315,7 @@ CONFIG_GENERIC_ATOMIC64=y
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1324,6 +1333,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_PPC_DISABLE_WERROR is not set
@@ -1344,6 +1354,8 @@ CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
+CONFIG_ASYNC_PQ=y
+CONFIG_ASYNC_RAID6_RECOV=y
# CONFIG_CRYPTO is not set
# CONFIG_PPC_CLOCK is not set
# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h
index 9154e8526732..f0fb4fc1f6e6 100644
--- a/arch/powerpc/include/asm/emulated_ops.h
+++ b/arch/powerpc/include/asm/emulated_ops.h
@@ -19,6 +19,7 @@
#define _ASM_POWERPC_EMULATED_OPS_H
#include <asm/atomic.h>
+#include <linux/perf_event.h>
#ifdef CONFIG_PPC_EMULATED_STATS
@@ -57,7 +58,7 @@ extern u32 ppc_warn_emulated;
extern void ppc_warn_emulated_print(const char *type);
-#define PPC_WARN_EMULATED(type) \
+#define __PPC_WARN_EMULATED(type) \
do { \
atomic_inc(&ppc_emulated.type.val); \
if (ppc_warn_emulated) \
@@ -66,8 +67,22 @@ extern void ppc_warn_emulated_print(const char *type);
#else /* !CONFIG_PPC_EMULATED_STATS */
-#define PPC_WARN_EMULATED(type) do { } while (0)
+#define __PPC_WARN_EMULATED(type) do { } while (0)
#endif /* !CONFIG_PPC_EMULATED_STATS */
+#define PPC_WARN_EMULATED(type, regs) \
+ do { \
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, \
+ 1, 0, regs, 0); \
+ __PPC_WARN_EMULATED(type); \
+ } while (0)
+
+#define PPC_WARN_ALIGNMENT(type, regs) \
+ do { \
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, \
+ 1, 0, regs, regs->dar); \
+ __PPC_WARN_EMULATED(type); \
+ } while (0)
+
#endif /* _ASM_POWERPC_EMULATED_OPS_H */
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index 3a179827528d..20778a405d7a 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -37,7 +37,7 @@
#define FW_FEATURE_VIO ASM_CONST(0x0000000000004000)
#define FW_FEATURE_RDMA ASM_CONST(0x0000000000008000)
#define FW_FEATURE_LLAN ASM_CONST(0x0000000000010000)
-#define FW_FEATURE_BULK ASM_CONST(0x0000000000020000)
+#define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000000020000)
#define FW_FEATURE_XDABR ASM_CONST(0x0000000000040000)
#define FW_FEATURE_MULTITCE ASM_CONST(0x0000000000080000)
#define FW_FEATURE_SPLPAR ASM_CONST(0x0000000000100000)
@@ -45,8 +45,7 @@
#define FW_FEATURE_LPAR ASM_CONST(0x0000000000400000)
#define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000)
#define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000)
-#define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000002000000)
-#define FW_FEATURE_CMO ASM_CONST(0x0000000004000000)
+#define FW_FEATURE_CMO ASM_CONST(0x0000000002000000)
#ifndef __ASSEMBLY__
@@ -58,8 +57,9 @@ enum {
FW_FEATURE_PERF | FW_FEATURE_DUMP | FW_FEATURE_INTERRUPT |
FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ |
FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
- FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE |
- FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | FW_FEATURE_CMO,
+ FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
+ FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
+ FW_FEATURE_CMO,
FW_FEATURE_PSERIES_ALWAYS = 0,
FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index 6251a4b10be7..c27caac47ad1 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -274,6 +274,8 @@ struct hcall_stats {
unsigned long num_calls; /* number of calls (on this CPU) */
unsigned long tb_total; /* total wall time (mftb) of calls. */
unsigned long purr_total; /* total cpu time (PURR) of calls. */
+ unsigned long tb_start;
+ unsigned long purr_start;
};
#define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1)
diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h
index b6bac6f61c16..916369575c97 100644
--- a/arch/powerpc/include/asm/kmap_types.h
+++ b/arch/powerpc/include/asm/kmap_types.h
@@ -29,5 +29,16 @@ enum km_type {
KM_TYPE_NR
};
+/*
+ * This is a temporary build fix that (so they say on lkml....) should no longer
+ * be required after 2.6.33, because of changes planned to the kmap code.
+ * Let's try to remove this cruft then.
+ */
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define KM_NMI (-1)
+#define KM_NMI_PTE (-1)
+#define KM_IRQ_PTE (-1)
+#endif
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_KMAP_TYPES_H */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 6315edc205d8..bc8dd53f718a 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -489,6 +489,8 @@
#define SPRN_MMCR1 798
#define SPRN_MMCRA 0x312
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
+#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
+#define MMCRA_SDAR_ERAT_MISS 0x20000000UL
#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */
#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */
#define MMCRA_SLOT 0x07000000UL /* SLOT bits (37-39) */
diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h
new file mode 100644
index 000000000000..cbe2297d68b6
--- /dev/null
+++ b/arch/powerpc/include/asm/trace.h
@@ -0,0 +1,133 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM powerpc
+
+#if !defined(_TRACE_POWERPC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_POWERPC_H
+
+#include <linux/tracepoint.h>
+
+struct pt_regs;
+
+TRACE_EVENT(irq_entry,
+
+ TP_PROTO(struct pt_regs *regs),
+
+ TP_ARGS(regs),
+
+ TP_STRUCT__entry(
+ __field(struct pt_regs *, regs)
+ ),
+
+ TP_fast_assign(
+ __entry->regs = regs;
+ ),
+
+ TP_printk("pt_regs=%p", __entry->regs)
+);
+
+TRACE_EVENT(irq_exit,
+
+ TP_PROTO(struct pt_regs *regs),
+
+ TP_ARGS(regs),
+
+ TP_STRUCT__entry(
+ __field(struct pt_regs *, regs)
+ ),
+
+ TP_fast_assign(
+ __entry->regs = regs;
+ ),
+
+ TP_printk("pt_regs=%p", __entry->regs)
+);
+
+TRACE_EVENT(timer_interrupt_entry,
+
+ TP_PROTO(struct pt_regs *regs),
+
+ TP_ARGS(regs),
+
+ TP_STRUCT__entry(
+ __field(struct pt_regs *, regs)
+ ),
+
+ TP_fast_assign(
+ __entry->regs = regs;
+ ),
+
+ TP_printk("pt_regs=%p", __entry->regs)
+);
+
+TRACE_EVENT(timer_interrupt_exit,
+
+ TP_PROTO(struct pt_regs *regs),
+
+ TP_ARGS(regs),
+
+ TP_STRUCT__entry(
+ __field(struct pt_regs *, regs)
+ ),
+
+ TP_fast_assign(
+ __entry->regs = regs;
+ ),
+
+ TP_printk("pt_regs=%p", __entry->regs)
+);
+
+#ifdef CONFIG_PPC_PSERIES
+extern void hcall_tracepoint_regfunc(void);
+extern void hcall_tracepoint_unregfunc(void);
+
+TRACE_EVENT_FN(hcall_entry,
+
+ TP_PROTO(unsigned long opcode, unsigned long *args),
+
+ TP_ARGS(opcode, args),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, opcode)
+ ),
+
+ TP_fast_assign(
+ __entry->opcode = opcode;
+ ),
+
+ TP_printk("opcode=%lu", __entry->opcode),
+
+ hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
+);
+
+TRACE_EVENT_FN(hcall_exit,
+
+ TP_PROTO(unsigned long opcode, unsigned long retval,
+ unsigned long *retbuf),
+
+ TP_ARGS(opcode, retval, retbuf),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, opcode)
+ __field(unsigned long, retval)
+ ),
+
+ TP_fast_assign(
+ __entry->opcode = opcode;
+ __entry->retval = retval;
+ ),
+
+ TP_printk("opcode=%lu retval=%lu", __entry->opcode, __entry->retval),
+
+ hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
+);
+#endif
+
+#endif /* _TRACE_POWERPC_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH asm
+#define TRACE_INCLUDE_FILE trace
+
+#include <trace/define_trace.h>
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index a5b632e52fae..3839839f83c7 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -732,7 +732,7 @@ int fix_alignment(struct pt_regs *regs)
#ifdef CONFIG_SPE
if ((instr >> 26) == 0x4) {
- PPC_WARN_EMULATED(spe);
+ PPC_WARN_ALIGNMENT(spe, regs);
return emulate_spe(regs, reg, instr);
}
#endif
@@ -786,7 +786,7 @@ int fix_alignment(struct pt_regs *regs)
flags |= SPLT;
nb = 8;
}
- PPC_WARN_EMULATED(vsx);
+ PPC_WARN_ALIGNMENT(vsx, regs);
return emulate_vsx(addr, reg, areg, regs, flags, nb);
}
#endif
@@ -794,7 +794,7 @@ int fix_alignment(struct pt_regs *regs)
* the exception of DCBZ which is handled as a special case here
*/
if (instr == DCBZ) {
- PPC_WARN_EMULATED(dcbz);
+ PPC_WARN_ALIGNMENT(dcbz, regs);
return emulate_dcbz(regs, addr);
}
if (unlikely(nb == 0))
@@ -804,7 +804,7 @@ int fix_alignment(struct pt_regs *regs)
* function
*/
if (flags & M) {
- PPC_WARN_EMULATED(multiple);
+ PPC_WARN_ALIGNMENT(multiple, regs);
return emulate_multiple(regs, addr, reg, nb,
flags, instr, swiz);
}
@@ -825,11 +825,11 @@ int fix_alignment(struct pt_regs *regs)
/* Special case for 16-byte FP loads and stores */
if (nb == 16) {
- PPC_WARN_EMULATED(fp_pair);
+ PPC_WARN_ALIGNMENT(fp_pair, regs);
return emulate_fp_pair(addr, reg, flags);
}
- PPC_WARN_EMULATED(unaligned);
+ PPC_WARN_ALIGNMENT(unaligned, regs);
/* If we are loading, get the data from user space, else
* get it from register values
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 0b9c9135922e..03c862b6a9c4 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -711,6 +711,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_750,
.machine_check = machine_check_generic,
.platform = "ppc750",
+ .oprofile_cpu_type = "ppc/750",
+ .oprofile_type = PPC_OPROFILE_G4,
},
{ /* 745/755 */
.pvr_mask = 0xfffff000,
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 900e0eea0099..bdcb557d470a 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -551,7 +551,7 @@ restore:
BEGIN_FW_FTR_SECTION
ld r5,SOFTE(r1)
FW_FTR_SECTION_ELSE
- b iseries_check_pending_irqs
+ b .Liseries_check_pending_irqs
ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
2:
TRACE_AND_RESTORE_IRQ(r5);
@@ -623,7 +623,7 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
#endif /* CONFIG_PPC_BOOK3E */
-iseries_check_pending_irqs:
+.Liseries_check_pending_irqs:
#ifdef CONFIG_PPC_ISERIES
ld r5,SOFTE(r1)
cmpdi 0,r5,0
@@ -658,42 +658,43 @@ do_work:
cmpdi r0,0
crandc eq,cr1*4+eq,eq
bne restore
- /* here we are preempting the current task */
-1:
-#ifdef CONFIG_TRACE_IRQFLAGS
- bl .trace_hardirqs_on
- /* Note: we just clobbered r10 which used to contain the previous
- * MSR before the hard-disabling done by the caller of do_work.
- * We don't have that value anymore, but it doesn't matter as
- * we will hard-enable unconditionally, we can just reload the
- * current MSR into r10
+
+ /* Here we are preempting the current task.
+ *
+ * Ensure interrupts are soft-disabled. We also properly mark
+ * the PACA to reflect the fact that they are hard-disabled
+ * and trace the change
*/
- mfmsr r10
-#endif /* CONFIG_TRACE_IRQFLAGS */
- li r0,1
+ li r0,0
stb r0,PACASOFTIRQEN(r13)
stb r0,PACAHARDIRQEN(r13)
+ TRACE_DISABLE_INTS
+
+ /* Call the scheduler with soft IRQs off */
+1: bl .preempt_schedule_irq
+
+ /* Hard-disable interrupts again (and update PACA) */
#ifdef CONFIG_PPC_BOOK3E
- wrteei 1
- bl .preempt_schedule
wrteei 0
#else
- ori r10,r10,MSR_EE
- mtmsrd r10,1 /* reenable interrupts */
- bl .preempt_schedule
mfmsr r10
- clrrdi r9,r1,THREAD_SHIFT
- rldicl r10,r10,48,1 /* disable interrupts again */
+ rldicl r10,r10,48,1
rotldi r10,r10,16
mtmsrd r10,1
#endif /* CONFIG_PPC_BOOK3E */
+ li r0,0
+ stb r0,PACAHARDIRQEN(r13)
+
+ /* Re-test flags and eventually loop */
+ clrrdi r9,r1,THREAD_SHIFT
ld r4,TI_FLAGS(r9)
andi. r0,r4,_TIF_NEED_RESCHED
bne 1b
b restore
user_work:
-#endif
+#endif /* CONFIG_PREEMPT */
+
/* Enable interrupts */
#ifdef CONFIG_PPC_BOOK3E
wrteei 1
@@ -1038,8 +1039,7 @@ _GLOBAL(mod_return_to_handler)
* We are in a module using the module's TOC.
* Switch to our TOC to run inside the core kernel.
*/
- LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler)
- ld r2, 8(r4)
+ ld r2, PACATOC(r13)
bl .ftrace_return_to_handler
nop
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 1808876edcc9..c7eb4e0eb86c 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -185,12 +185,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
* prolog code of the PerformanceMonitor one. A little
* trickery is thus necessary
*/
+performance_monitor_pSeries_1:
. = 0xf00
b performance_monitor_pSeries
+altivec_unavailable_pSeries_1:
. = 0xf20
b altivec_unavailable_pSeries
+vsx_unavailable_pSeries_1:
. = 0xf40
b vsx_unavailable_pSeries
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index e5d121177984..02a334662cc0 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -70,6 +70,8 @@
#include <asm/firmware.h>
#include <asm/lv1call.h>
#endif
+#define CREATE_TRACE_POINTS
+#include <asm/trace.h>
int __irq_offset_value;
static int ppc_spurious_interrupts;
@@ -325,6 +327,8 @@ void do_IRQ(struct pt_regs *regs)
struct pt_regs *old_regs = set_irq_regs(regs);
unsigned int irq;
+ trace_irq_entry(regs);
+
irq_enter();
check_stack_overflow();
@@ -348,6 +352,8 @@ void do_IRQ(struct pt_regs *regs)
timer_interrupt(regs);
}
#endif
+
+ trace_irq_exit(regs);
}
void __init init_IRQ(void)
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index fe8f71dd0b3f..641c74bb8e27 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -282,12 +282,6 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
{
unsigned long *ptr = gdb_regs;
int reg;
-#ifdef CONFIG_SPE
- union {
- u32 v32[2];
- u64 v64;
- } acc;
-#endif
for (reg = 0; reg < 32; reg++)
UNPACK64(regs->gpr[reg], ptr);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index bb8209e34931..e8dfdbd9327a 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1190,7 +1190,7 @@ EXPORT_SYMBOL(pcibios_align_resource);
* Reparent resource children of pr that conflict with res
* under res, and make res replace those children.
*/
-static int __init reparent_resources(struct resource *parent,
+static int reparent_resources(struct resource *parent,
struct resource *res)
{
struct resource *p, **pp;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index ba949a2c93ac..ccf56ac92de5 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -97,7 +97,9 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
* to do an appropriate TLB flush here too
*/
if (bus->self) {
+#ifdef CONFIG_PPC_STD_MMU_64
struct resource *res = bus->resource[0];
+#endif
pr_debug("IO unmapping for PCI-PCI bridge %s\n",
pci_name(bus->self));
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index bbcbae183e92..1eb85fbf53a5 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -116,20 +116,23 @@ static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp)
static inline u32 perf_get_misc_flags(struct pt_regs *regs)
{
unsigned long mmcra = regs->dsisr;
+ unsigned long sihv = MMCRA_SIHV;
+ unsigned long sipr = MMCRA_SIPR;
if (TRAP(regs) != 0xf00)
return 0; /* not a PMU interrupt */
if (ppmu->flags & PPMU_ALT_SIPR) {
- if (mmcra & POWER6_MMCRA_SIHV)
- return PERF_RECORD_MISC_HYPERVISOR;
- return (mmcra & POWER6_MMCRA_SIPR) ?
- PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL;
+ sihv = POWER6_MMCRA_SIHV;
+ sipr = POWER6_MMCRA_SIPR;
}
- if (mmcra & MMCRA_SIHV)
+
+ /* PR has priority over HV, so order below is important */
+ if (mmcra & sipr)
+ return PERF_RECORD_MISC_USER;
+ if ((mmcra & sihv) && (freeze_events_kernel != MMCR0_FCHV))
return PERF_RECORD_MISC_HYPERVISOR;
- return (mmcra & MMCRA_SIPR) ? PERF_RECORD_MISC_USER :
- PERF_RECORD_MISC_KERNEL;
+ return PERF_RECORD_MISC_KERNEL;
}
/*
@@ -1162,7 +1165,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
*/
if (record) {
struct perf_sample_data data = {
- .addr = 0,
+ .addr = ~0ULL,
.period = event->hw.last_period,
};
diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c
index 0f4c1c73a6ad..199de527d411 100644
--- a/arch/powerpc/kernel/power5+-pmu.c
+++ b/arch/powerpc/kernel/power5+-pmu.c
@@ -73,10 +73,6 @@
#define MMCR1_PMCSEL_MSK 0x7f
/*
- * Bits in MMCRA
- */
-
-/*
* Layout of constraint bits:
* 6666555555555544444444443333333333222222222211111111110000000000
* 3210987654321098765432109876543210987654321098765432109876543210
diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c
index c351b3a57fbb..98b6a729a9dd 100644
--- a/arch/powerpc/kernel/power5-pmu.c
+++ b/arch/powerpc/kernel/power5-pmu.c
@@ -73,10 +73,6 @@
#define MMCR1_PMCSEL_MSK 0x7f
/*
- * Bits in MMCRA
- */
-
-/*
* Layout of constraint bits:
* 6666555555555544444444443333333333222222222211111111110000000000
* 3210987654321098765432109876543210987654321098765432109876543210
@@ -390,7 +386,7 @@ static int power5_compute_mmcr(u64 event[], int n_ev,
unsigned int hwc[], unsigned long mmcr[])
{
unsigned long mmcr1 = 0;
- unsigned long mmcra = 0;
+ unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
unsigned int pmc, unit, byte, psel;
unsigned int ttm, grp;
int i, isbus, bit, grsel;
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c
index ca399ba5034c..84a607bda8fb 100644
--- a/arch/powerpc/kernel/power6-pmu.c
+++ b/arch/powerpc/kernel/power6-pmu.c
@@ -178,7 +178,7 @@ static int p6_compute_mmcr(u64 event[], int n_ev,
unsigned int hwc[], unsigned long mmcr[])
{
unsigned long mmcr1 = 0;
- unsigned long mmcra = 0;
+ unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
int i;
unsigned int pmc, ev, b, u, s, psel;
unsigned int ttmset = 0;
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c
index 28a4daacdc02..852f7b7f6b40 100644
--- a/arch/powerpc/kernel/power7-pmu.c
+++ b/arch/powerpc/kernel/power7-pmu.c
@@ -51,10 +51,6 @@
#define MMCR1_PMCSEL_MSK 0xff
/*
- * Bits in MMCRA
- */
-
-/*
* Layout of constraint bits:
* 6666555555555544444444443333333333222222222211111111110000000000
* 3210987654321098765432109876543210987654321098765432109876543210
@@ -230,7 +226,7 @@ static int power7_compute_mmcr(u64 event[], int n_ev,
unsigned int hwc[], unsigned long mmcr[])
{
unsigned long mmcr1 = 0;
- unsigned long mmcra = 0;
+ unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
unsigned int pmc, unit, combine, l2sel, psel;
unsigned int pmc_inuse = 0;
int i;
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c
index 479574413a93..8eff48e20dba 100644
--- a/arch/powerpc/kernel/ppc970-pmu.c
+++ b/arch/powerpc/kernel/ppc970-pmu.c
@@ -84,10 +84,6 @@ static short mmcr1_adder_bits[8] = {
};
/*
- * Bits in MMCRA
- */
-
-/*
* Layout of constraint bits:
* 6666555555555544444444443333333333222222222211111111110000000000
* 3210987654321098765432109876543210987654321098765432109876543210
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 1168c5f440ab..c930ac38e59f 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1016,9 +1016,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
int curr_frame = current->curr_ret_stack;
extern void return_to_handler(void);
- unsigned long addr = (unsigned long)return_to_handler;
+ unsigned long rth = (unsigned long)return_to_handler;
+ unsigned long mrth = -1;
#ifdef CONFIG_PPC64
- addr = *(unsigned long*)addr;
+ extern void mod_return_to_handler(void);
+ rth = *(unsigned long *)rth;
+ mrth = (unsigned long)mod_return_to_handler;
+ mrth = *(unsigned long *)mrth;
#endif
#endif
@@ -1044,7 +1048,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
if (!firstframe || ip != lr) {
printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- if (ip == addr && curr_frame >= 0) {
+ if ((ip == rth || ip == mrth) && curr_frame >= 0) {
printk(" (%pS)",
(void *)current->ret_stack[curr_frame].ret);
curr_frame--;
@@ -1168,7 +1172,7 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
unsigned long base = mm->brk;
unsigned long ret;
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_STD_MMU_64
/*
* If we are using 1TB segments and we are allowed to randomise
* the heap, we can put it above 1TB so it is backed by a 1TB
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 4271f7a655a3..845c72ab7357 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -660,6 +660,7 @@ late_initcall(check_cache_coherency);
#ifdef CONFIG_DEBUG_FS
struct dentry *powerpc_debugfs_root;
+EXPORT_SYMBOL(powerpc_debugfs_root);
static int powerpc_debugfs_init(void)
{
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 53bcf3d792db..b152de3e64d4 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -345,7 +345,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_SWIOTLB
if (ppc_swiotlb_enable)
- swiotlb_init();
+ swiotlb_init(1);
#endif
paging_init();
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 797ea95aae2e..df2c9e932b37 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -57,7 +57,6 @@
#include <asm/cache.h>
#include <asm/page.h>
#include <asm/mmu.h>
-#include <asm/mmu-hash64.h>
#include <asm/firmware.h>
#include <asm/xmon.h>
#include <asm/udbg.h>
@@ -551,7 +550,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_SWIOTLB
if (ppc_swiotlb_enable)
- swiotlb_init();
+ swiotlb_init(1);
#endif
paging_init();
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 92dc844299b6..36707dec94d7 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -54,6 +54,7 @@
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/perf_event.h>
+#include <asm/trace.h>
#include <asm/io.h>
#include <asm/processor.h>
@@ -571,6 +572,8 @@ void timer_interrupt(struct pt_regs * regs)
struct clock_event_device *evt = &decrementer->event;
u64 now;
+ trace_timer_interrupt_entry(regs);
+
/* Ensure a positive value is written to the decrementer, or else
* some CPUs will continuue to take decrementer exceptions */
set_dec(DECREMENTER_MAX);
@@ -590,6 +593,7 @@ void timer_interrupt(struct pt_regs * regs)
now = decrementer->next_tb - now;
if (now <= DECREMENTER_MAX)
set_dec((int)now);
+ trace_timer_interrupt_exit(regs);
return;
}
old_regs = set_irq_regs(regs);
@@ -620,6 +624,8 @@ void timer_interrupt(struct pt_regs * regs)
irq_exit();
set_irq_regs(old_regs);
+
+ trace_timer_interrupt_exit(regs);
}
void wakeup_decrementer(void)
@@ -777,7 +783,7 @@ int update_persistent_clock(struct timespec now)
return ppc_md.set_rtc_time(&tm);
}
-void read_persistent_clock(struct timespec *ts)
+static void __read_persistent_clock(struct timespec *ts)
{
struct rtc_time tm;
static int first = 1;
@@ -800,10 +806,23 @@ void read_persistent_clock(struct timespec *ts)
return;
}
ppc_md.get_rtc_time(&tm);
+
ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
+void read_persistent_clock(struct timespec *ts)
+{
+ __read_persistent_clock(ts);
+
+ /* Sanitize it in case real time clock is set below EPOCH */
+ if (ts->tv_sec < 0) {
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ }
+
+}
+
/* clocksource code */
static cycle_t rtc_read(struct clocksource *cs)
{
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6f0ae1a9bfae..9d1f9354d6ca 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -759,7 +759,7 @@ static int emulate_instruction(struct pt_regs *regs)
/* Emulate the mfspr rD, PVR. */
if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
- PPC_WARN_EMULATED(mfpvr);
+ PPC_WARN_EMULATED(mfpvr, regs);
rd = (instword >> 21) & 0x1f;
regs->gpr[rd] = mfspr(SPRN_PVR);
return 0;
@@ -767,7 +767,7 @@ static int emulate_instruction(struct pt_regs *regs)
/* Emulating the dcba insn is just a no-op. */
if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) {
- PPC_WARN_EMULATED(dcba);
+ PPC_WARN_EMULATED(dcba, regs);
return 0;
}
@@ -776,7 +776,7 @@ static int emulate_instruction(struct pt_regs *regs)
int shift = (instword >> 21) & 0x1c;
unsigned long msk = 0xf0000000UL >> shift;
- PPC_WARN_EMULATED(mcrxr);
+ PPC_WARN_EMULATED(mcrxr, regs);
regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
regs->xer &= ~0xf0000000UL;
return 0;
@@ -784,19 +784,19 @@ static int emulate_instruction(struct pt_regs *regs)
/* Emulate load/store string insn. */
if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
- PPC_WARN_EMULATED(string);
+ PPC_WARN_EMULATED(string, regs);
return emulate_string_inst(regs, instword);
}
/* Emulate the popcntb (Population Count Bytes) instruction. */
if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
- PPC_WARN_EMULATED(popcntb);
+ PPC_WARN_EMULATED(popcntb, regs);
return emulate_popcntb_inst(regs, instword);
}
/* Emulate isel (Integer Select) instruction */
if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
- PPC_WARN_EMULATED(isel);
+ PPC_WARN_EMULATED(isel, regs);
return emulate_isel(regs, instword);
}
@@ -995,7 +995,7 @@ void SoftwareEmulation(struct pt_regs *regs)
#ifdef CONFIG_MATH_EMULATION
errcode = do_mathemu(regs);
if (errcode >= 0)
- PPC_WARN_EMULATED(math);
+ PPC_WARN_EMULATED(math, regs);
switch (errcode) {
case 0:
@@ -1018,7 +1018,7 @@ void SoftwareEmulation(struct pt_regs *regs)
#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
errcode = Soft_emulate_8xx(regs);
if (errcode >= 0)
- PPC_WARN_EMULATED(8xx);
+ PPC_WARN_EMULATED(8xx, regs);
switch (errcode) {
case 0:
@@ -1129,7 +1129,7 @@ void altivec_assist_exception(struct pt_regs *regs)
flush_altivec_to_thread(current);
- PPC_WARN_EMULATED(altivec);
+ PPC_WARN_EMULATED(altivec, regs);
err = emulate_altivec(regs);
if (err == 0) {
regs->nip += 4; /* skip emulated instruction */
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 94e2df3cae07..137dc22afa42 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -50,6 +50,9 @@
/* Max supported size for symbol names */
#define MAX_SYMNAME 64
+/* The alignment of the vDSO */
+#define VDSO_ALIGNMENT (1 << 16)
+
extern char vdso32_start, vdso32_end;
static void *vdso32_kbase = &vdso32_start;
static unsigned int vdso32_pages;
@@ -231,15 +234,21 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
* pick a base address for the vDSO in process space. We try to put it
* at vdso_base which is the "natural" base for it, but we might fail
* and end up putting it elsewhere.
+ * Add enough to the size so that the result can be aligned.
*/
down_write(&mm->mmap_sem);
vdso_base = get_unmapped_area(NULL, vdso_base,
- vdso_pages << PAGE_SHIFT, 0, 0);
+ (vdso_pages << PAGE_SHIFT) +
+ ((VDSO_ALIGNMENT - 1) & PAGE_MASK),
+ 0, 0);
if (IS_ERR_VALUE(vdso_base)) {
rc = vdso_base;
goto fail_mmapsem;
}
+ /* Add required alignment. */
+ vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT);
+
/*
* Put vDSO base into mm struct. We need to do this before calling
* install_special_mapping or the perf counter mmap tracking code
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 904ef1360dd7..0546bcd49cd0 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -25,7 +25,7 @@ SECTIONS
. = ALIGN(16);
.text : {
*(.text .stub .text.* .gnu.linkonce.t.* __ftr_alt_*)
- }
+ } :text
PROVIDE(__etext = .);
PROVIDE(_etext = .);
PROVIDE(etext = .);
@@ -56,7 +56,7 @@ SECTIONS
.fixup : { *(.fixup) }
.dynamic : { *(.dynamic) } :text :dynamic
- .got : { *(.got) }
+ .got : { *(.got) } :text
.plt : { *(.plt) }
_end = .;
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index f56429362a12..27735a7ac12b 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -236,6 +236,7 @@ SECTIONS
READ_MOSTLY_DATA(L1_CACHE_BYTES)
}
+ . = ALIGN(PAGE_SIZE);
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
NOSAVE_DATA
}
diff --git a/arch/powerpc/kvm/timing.h b/arch/powerpc/kvm/timing.h
index bb13b1f3cd5a..806ef67868bd 100644
--- a/arch/powerpc/kvm/timing.h
+++ b/arch/powerpc/kvm/timing.h
@@ -48,7 +48,11 @@ static inline void kvmppc_set_exit_type(struct kvm_vcpu *vcpu, int type) {}
static inline void kvmppc_account_exit_stat(struct kvm_vcpu *vcpu, int type)
{
/* type has to be known at build time for optimization */
+
+ /* The BUILD_BUG_ON below breaks in funny ways, commented out
+ * for now ... -BenH
BUILD_BUG_ON(__builtin_constant_p(type));
+ */
switch (type) {
case EXT_INTR_EXITS:
vcpu->stat.ext_intr_exits++;
diff --git a/arch/powerpc/lib/copypage_64.S b/arch/powerpc/lib/copypage_64.S
index 75f3267fdc30..e68beac0a171 100644
--- a/arch/powerpc/lib/copypage_64.S
+++ b/arch/powerpc/lib/copypage_64.S
@@ -26,11 +26,11 @@ BEGIN_FTR_SECTION
srd r8,r5,r11
mtctr r8
-setup:
+.Lsetup:
dcbt r9,r4
dcbz r9,r3
add r9,r9,r12
- bdnz setup
+ bdnz .Lsetup
END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ)
addi r3,r3,-8
srdi r8,r5,7 /* page is copied in 128 byte strides */
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index c2f93dc470e6..be4f34c30a0b 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -25,8 +25,8 @@
* also clear mm->cpu_vm_mask bits when processes are migrated
*/
-#define DEBUG_MAP_CONSISTENCY
-#define DEBUG_CLAMP_LAST_CONTEXT 31
+//#define DEBUG_MAP_CONSISTENCY
+//#define DEBUG_CLAMP_LAST_CONTEXT 31
//#define DEBUG_HARDER
/* We don't use DEBUG because it tends to be compiled in always nowadays
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index bc44dc4b5c67..95ce35581696 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -72,19 +72,17 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
1:
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
- /* vmalloc/ioremap mapping encoding bits, the "li" instructions below
- * will be patched by the kernel at boot
+ /* vmalloc mapping gets the encoding from the PACA as the mapping
+ * can be demoted from 64K -> 4K dynamically on some machines
*/
-BEGIN_FTR_SECTION
- /* check whether this is in vmalloc or ioremap space */
clrldi r11,r10,48
cmpldi r11,(VMALLOC_SIZE >> 28) - 1
bgt 5f
lhz r11,PACAVMALLOCSLLP(r13)
b 6f
5:
-END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE)
-_GLOBAL(slb_miss_kernel_load_io)
+ /* IO mapping */
+ _GLOBAL(slb_miss_kernel_load_io)
li r11,0
6:
BEGIN_FTR_SECTION
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
index c31e5b534f0a..d45be5b5ad49 100644
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
@@ -51,6 +51,8 @@ static void __init mpc5200_simple_setup_arch(void)
/* list of the supported boards */
static char *board[] __initdata = {
"intercontrol,digsy-mtc",
+ "manroland,mucmc52",
+ "manroland,uc101",
"phytec,pcm030",
"phytec,pcm032",
"promess,motionpro",
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
index 51fcae41f08a..f9aee182e6f7 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -132,12 +132,25 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
return -ENOMEM;
bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (bus->irq == NULL) {
+ ret = -ENOMEM;
+ goto err_free_bus;
+ }
bus->name = "ep8248e-mdio-bitbang";
bus->parent = &ofdev->dev;
snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
- return of_mdiobus_register(bus, ofdev->node);
+ ret = of_mdiobus_register(bus, ofdev->node);
+ if (ret)
+ goto err_free_irq;
+
+ return 0;
+err_free_irq:
+ kfree(bus->irq);
+err_free_bus:
+ free_mdio_bitbang(bus);
+ return ret;
}
static int ep8248e_mdio_remove(struct of_device *ofdev)
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index aca5741ddc67..a86c34b3bb84 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -365,7 +365,7 @@ static int axon_msi_probe(struct of_device *device,
printk(KERN_ERR
"axon_msi: couldn't parse dcr properties on %s\n",
dn->full_name);
- goto out;
+ goto out_free_msic;
}
msic->dcr_host = dcr_map(dn, dcr_base, dcr_len);
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index cc7161ff1666..ce014928d460 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -1,18 +1,9 @@
EXTRA_CFLAGS += -mno-minimal-toc
-extra-y += dt.o
-
obj-y += exception.o
-obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
+obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt.o mf.o lpevents.o \
hvcall.o proc.o htab.o iommu.o misc.o irq.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_VIOPATH) += viopath.o vio.o
obj-$(CONFIG_MODULES) += ksyms.o
-
-quiet_cmd_dt_strings = DT_STR $@
- cmd_dt_strings = $(OBJCOPY) --rename-section .rodata.str1.8=.dt_strings \
- $< $@
-
-$(obj)/dt_mod.o: $(obj)/dt.o
- $(call if_changed,dt_strings)
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index c5a87a72057b..7f45a51fe793 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -51,11 +51,16 @@
/*
* These are created by the linker script at the start and end
- * of the section containing all the strings from this file.
+ * of the section containing all the strings marked with the DS macro.
*/
extern char __dt_strings_start[];
extern char __dt_strings_end[];
+#define DS(s) ({ \
+ static const char __s[] __attribute__((section(".dt_strings"))) = s; \
+ __s; \
+})
+
struct iseries_flat_dt {
struct boot_param_header header;
u64 reserve_map[2];
@@ -64,9 +69,8 @@ struct iseries_flat_dt {
static void * __initdata dt_data;
/*
- * Putting these strings here keeps them out of the section
- * that we rename to .dt_strings using objcopy and capture
- * for the strings blob of the flattened device tree.
+ * Putting these strings here keeps them out of the .dt_strings section
+ * that we capture for the strings blob of the flattened device tree.
*/
static char __initdata device_type_cpu[] = "cpu";
static char __initdata device_type_memory[] = "memory";
@@ -173,7 +177,7 @@ static void __init dt_start_node(struct iseries_flat_dt *dt, const char *name)
#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
-static void __init dt_prop(struct iseries_flat_dt *dt, const char *name,
+static void __init __dt_prop(struct iseries_flat_dt *dt, const char *name,
const void *data, int len)
{
unsigned long offset;
@@ -191,44 +195,32 @@ static void __init dt_prop(struct iseries_flat_dt *dt, const char *name,
/* The actual data. */
dt_push_bytes(dt, data, len);
}
+#define dt_prop(dt, name, data, len) __dt_prop((dt), DS(name), (data), (len))
-static void __init dt_prop_str(struct iseries_flat_dt *dt, const char *name,
- const char *data)
-{
- dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */
-}
+#define dt_prop_str(dt, name, data) \
+ dt_prop((dt), name, (data), strlen((data)) + 1); /* + 1 for NULL */
-static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name,
+static void __init __dt_prop_u32(struct iseries_flat_dt *dt, const char *name,
u32 data)
{
- dt_prop(dt, name, &data, sizeof(u32));
+ __dt_prop(dt, name, &data, sizeof(u32));
}
+#define dt_prop_u32(dt, name, data) __dt_prop_u32((dt), DS(name), (data))
-static void __init __maybe_unused dt_prop_u64(struct iseries_flat_dt *dt,
- const char *name,
- u64 data)
+static void __init __maybe_unused __dt_prop_u64(struct iseries_flat_dt *dt,
+ const char *name, u64 data)
{
- dt_prop(dt, name, &data, sizeof(u64));
+ __dt_prop(dt, name, &data, sizeof(u64));
}
+#define dt_prop_u64(dt, name, data) __dt_prop_u64((dt), DS(name), (data))
-static void __init dt_prop_u64_list(struct iseries_flat_dt *dt,
- const char *name, u64 *data, int n)
-{
- dt_prop(dt, name, data, sizeof(u64) * n);
-}
+#define dt_prop_u64_list(dt, name, data, n) \
+ dt_prop((dt), name, (data), sizeof(u64) * (n))
-static void __init dt_prop_u32_list(struct iseries_flat_dt *dt,
- const char *name, u32 *data, int n)
-{
- dt_prop(dt, name, data, sizeof(u32) * n);
-}
+#define dt_prop_u32_list(dt, name, data, n) \
+ dt_prop((dt), name, (data), sizeof(u32) * (n))
-#ifdef notyet
-static void __init dt_prop_empty(struct iseries_flat_dt *dt, const char *name)
-{
- dt_prop(dt, name, NULL, 0);
-}
-#endif
+#define dt_prop_empty(dt, name) dt_prop((dt), name, NULL, 0)
static void __init dt_cpus(struct iseries_flat_dt *dt)
{
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 21226b74c9b2..414ca9849f23 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -540,8 +540,11 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
/* Make sure IRQ is disabled */
kw_write_reg(reg_ier, 0);
- /* Request chip interrupt */
- if (request_irq(host->irq, kw_i2c_irq, 0, "keywest i2c", host))
+ /* Request chip interrupt. We set IRQF_TIMER because we don't
+ * want that interrupt disabled between the 2 passes of driver
+ * suspend or we'll have issues running the pfuncs
+ */
+ if (request_irq(host->irq, kw_i2c_irq, IRQF_TIMER, "keywest i2c", host))
host->irq = NO_IRQ;
printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n",
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 5a707da3f5c2..0a14d8cd314f 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -51,11 +51,10 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
{FW_FEATURE_VIO, "hcall-vio"},
{FW_FEATURE_RDMA, "hcall-rdma"},
{FW_FEATURE_LLAN, "hcall-lLAN"},
- {FW_FEATURE_BULK, "hcall-bulk"},
+ {FW_FEATURE_BULK_REMOVE, "hcall-bulk"},
{FW_FEATURE_XDABR, "hcall-xdabr"},
{FW_FEATURE_MULTITCE, "hcall-multi-tce"},
{FW_FEATURE_SPLPAR, "hcall-splpar"},
- {FW_FEATURE_BULK_REMOVE, "hcall-bulk"},
};
/* Build up the firmware features bitmask using the contents of
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index c1427b3634ec..383a5d0e9818 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -14,68 +14,94 @@
#define STK_PARM(i) (48 + ((i)-3)*8)
-#ifdef CONFIG_HCALL_STATS
+#ifdef CONFIG_TRACEPOINTS
+
+ .section ".toc","aw"
+
+ .globl hcall_tracepoint_refcount
+hcall_tracepoint_refcount:
+ .llong 0
+
+ .section ".text"
+
/*
* precall must preserve all registers. use unused STK_PARM()
- * areas to save snapshots and opcode.
+ * areas to save snapshots and opcode. We branch around this
+ * in early init (eg when populating the MMU hashtable) by using an
+ * unconditional cpu feature.
*/
-#define HCALL_INST_PRECALL \
- std r3,STK_PARM(r3)(r1); /* save opcode */ \
- mftb r0; /* get timebase and */ \
- std r0,STK_PARM(r5)(r1); /* save for later */ \
+#define HCALL_INST_PRECALL(FIRST_REG) \
BEGIN_FTR_SECTION; \
- mfspr r0,SPRN_PURR; /* get PURR and */ \
- std r0,STK_PARM(r6)(r1); /* save for later */ \
-END_FTR_SECTION_IFSET(CPU_FTR_PURR);
-
+ b 1f; \
+END_FTR_SECTION(0, 1); \
+ ld r12,hcall_tracepoint_refcount@toc(r2); \
+ cmpdi r12,0; \
+ beq+ 1f; \
+ mflr r0; \
+ std r3,STK_PARM(r3)(r1); \
+ std r4,STK_PARM(r4)(r1); \
+ std r5,STK_PARM(r5)(r1); \
+ std r6,STK_PARM(r6)(r1); \
+ std r7,STK_PARM(r7)(r1); \
+ std r8,STK_PARM(r8)(r1); \
+ std r9,STK_PARM(r9)(r1); \
+ std r10,STK_PARM(r10)(r1); \
+ std r0,16(r1); \
+ addi r4,r1,STK_PARM(FIRST_REG); \
+ stdu r1,-STACK_FRAME_OVERHEAD(r1); \
+ bl .__trace_hcall_entry; \
+ addi r1,r1,STACK_FRAME_OVERHEAD; \
+ ld r0,16(r1); \
+ ld r3,STK_PARM(r3)(r1); \
+ ld r4,STK_PARM(r4)(r1); \
+ ld r5,STK_PARM(r5)(r1); \
+ ld r6,STK_PARM(r6)(r1); \
+ ld r7,STK_PARM(r7)(r1); \
+ ld r8,STK_PARM(r8)(r1); \
+ ld r9,STK_PARM(r9)(r1); \
+ ld r10,STK_PARM(r10)(r1); \
+ mtlr r0; \
+1:
+
/*
* postcall is performed immediately before function return which
* allows liberal use of volatile registers. We branch around this
* in early init (eg when populating the MMU hashtable) by using an
* unconditional cpu feature.
*/
-#define HCALL_INST_POSTCALL \
+#define __HCALL_INST_POSTCALL \
BEGIN_FTR_SECTION; \
b 1f; \
END_FTR_SECTION(0, 1); \
- ld r4,STK_PARM(r3)(r1); /* validate opcode */ \
- cmpldi cr7,r4,MAX_HCALL_OPCODE; \
- bgt- cr7,1f; \
- \
- /* get time and PURR snapshots after hcall */ \
- mftb r7; /* timebase after */ \
-BEGIN_FTR_SECTION; \
- mfspr r8,SPRN_PURR; /* PURR after */ \
- ld r6,STK_PARM(r6)(r1); /* PURR before */ \
- subf r6,r6,r8; /* delta */ \
-END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
- ld r5,STK_PARM(r5)(r1); /* timebase before */ \
- subf r5,r5,r7; /* time delta */ \
- \
- /* calculate address of stat structure r4 = opcode */ \
- srdi r4,r4,2; /* index into array */ \
- mulli r4,r4,HCALL_STAT_SIZE; \
- LOAD_REG_ADDR(r7, per_cpu__hcall_stats); \
- add r4,r4,r7; \
- ld r7,PACA_DATA_OFFSET(r13); /* per cpu offset */ \
- add r4,r4,r7; \
- \
- /* update stats */ \
- ld r7,HCALL_STAT_CALLS(r4); /* count */ \
- addi r7,r7,1; \
- std r7,HCALL_STAT_CALLS(r4); \
- ld r7,HCALL_STAT_TB(r4); /* timebase */ \
- add r7,r7,r5; \
- std r7,HCALL_STAT_TB(r4); \
-BEGIN_FTR_SECTION; \
- ld r7,HCALL_STAT_PURR(r4); /* PURR */ \
- add r7,r7,r6; \
- std r7,HCALL_STAT_PURR(r4); \
-END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
+ ld r12,hcall_tracepoint_refcount@toc(r2); \
+ cmpdi r12,0; \
+ beq+ 1f; \
+ mflr r0; \
+ ld r6,STK_PARM(r3)(r1); \
+ std r3,STK_PARM(r3)(r1); \
+ mr r4,r3; \
+ mr r3,r6; \
+ std r0,16(r1); \
+ stdu r1,-STACK_FRAME_OVERHEAD(r1); \
+ bl .__trace_hcall_exit; \
+ addi r1,r1,STACK_FRAME_OVERHEAD; \
+ ld r0,16(r1); \
+ ld r3,STK_PARM(r3)(r1); \
+ mtlr r0; \
1:
+
+#define HCALL_INST_POSTCALL_NORETS \
+ li r5,0; \
+ __HCALL_INST_POSTCALL
+
+#define HCALL_INST_POSTCALL(BUFREG) \
+ mr r5,BUFREG; \
+ __HCALL_INST_POSTCALL
+
#else
-#define HCALL_INST_PRECALL
-#define HCALL_INST_POSTCALL
+#define HCALL_INST_PRECALL(FIRST_ARG)
+#define HCALL_INST_POSTCALL_NORETS
+#define HCALL_INST_POSTCALL(BUFREG)
#endif
.text
@@ -86,11 +112,11 @@ _GLOBAL(plpar_hcall_norets)
mfcr r0
stw r0,8(r1)
- HCALL_INST_PRECALL
+ HCALL_INST_PRECALL(r4)
HVSC /* invoke the hypervisor */
- HCALL_INST_POSTCALL
+ HCALL_INST_POSTCALL_NORETS
lwz r0,8(r1)
mtcrf 0xff,r0
@@ -102,7 +128,7 @@ _GLOBAL(plpar_hcall)
mfcr r0
stw r0,8(r1)
- HCALL_INST_PRECALL
+ HCALL_INST_PRECALL(r5)
std r4,STK_PARM(r4)(r1) /* Save ret buffer */
@@ -121,7 +147,7 @@ _GLOBAL(plpar_hcall)
std r6, 16(r12)
std r7, 24(r12)
- HCALL_INST_POSTCALL
+ HCALL_INST_POSTCALL(r12)
lwz r0,8(r1)
mtcrf 0xff,r0
@@ -168,7 +194,7 @@ _GLOBAL(plpar_hcall9)
mfcr r0
stw r0,8(r1)
- HCALL_INST_PRECALL
+ HCALL_INST_PRECALL(r5)
std r4,STK_PARM(r4)(r1) /* Save ret buffer */
@@ -196,7 +222,7 @@ _GLOBAL(plpar_hcall9)
std r11,56(r12)
std r0, 64(r12)
- HCALL_INST_POSTCALL
+ HCALL_INST_POSTCALL(r12)
lwz r0,8(r1)
mtcrf 0xff,r0
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
index 3631a4f277eb..2f58c71b7259 100644
--- a/arch/powerpc/platforms/pseries/hvCall_inst.c
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
@@ -26,6 +26,7 @@
#include <asm/hvcall.h>
#include <asm/firmware.h>
#include <asm/cputable.h>
+#include <asm/trace.h>
DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats);
@@ -100,6 +101,35 @@ static const struct file_operations hcall_inst_seq_fops = {
#define HCALL_ROOT_DIR "hcall_inst"
#define CPU_NAME_BUF_SIZE 32
+
+static void probe_hcall_entry(unsigned long opcode, unsigned long *args)
+{
+ struct hcall_stats *h;
+
+ if (opcode > MAX_HCALL_OPCODE)
+ return;
+
+ h = &get_cpu_var(hcall_stats)[opcode / 4];
+ h->tb_start = mftb();
+ h->purr_start = mfspr(SPRN_PURR);
+}
+
+static void probe_hcall_exit(unsigned long opcode, unsigned long retval,
+ unsigned long *retbuf)
+{
+ struct hcall_stats *h;
+
+ if (opcode > MAX_HCALL_OPCODE)
+ return;
+
+ h = &__get_cpu_var(hcall_stats)[opcode / 4];
+ h->num_calls++;
+ h->tb_total = mftb() - h->tb_start;
+ h->purr_total = mfspr(SPRN_PURR) - h->purr_start;
+
+ put_cpu_var(hcall_stats);
+}
+
static int __init hcall_inst_init(void)
{
struct dentry *hcall_root;
@@ -110,6 +140,14 @@ static int __init hcall_inst_init(void)
if (!firmware_has_feature(FW_FEATURE_LPAR))
return 0;
+ if (register_trace_hcall_entry(probe_hcall_entry))
+ return -EINVAL;
+
+ if (register_trace_hcall_exit(probe_hcall_exit)) {
+ unregister_trace_hcall_entry(probe_hcall_entry);
+ return -EINVAL;
+ }
+
hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL);
if (!hcall_root)
return -ENOMEM;
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 903eb9eec687..0707653612ba 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -39,6 +39,7 @@
#include <asm/cputable.h>
#include <asm/udbg.h>
#include <asm/smp.h>
+#include <asm/trace.h>
#include "plpar_wrappers.h"
#include "pseries.h"
@@ -661,3 +662,35 @@ void arch_free_page(struct page *page, int order)
EXPORT_SYMBOL(arch_free_page);
#endif
+
+#ifdef CONFIG_TRACEPOINTS
+/*
+ * We optimise our hcall path by placing hcall_tracepoint_refcount
+ * directly in the TOC so we can check if the hcall tracepoints are
+ * enabled via a single load.
+ */
+
+/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
+extern long hcall_tracepoint_refcount;
+
+void hcall_tracepoint_regfunc(void)
+{
+ hcall_tracepoint_refcount++;
+}
+
+void hcall_tracepoint_unregfunc(void)
+{
+ hcall_tracepoint_refcount--;
+}
+
+void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
+{
+ trace_hcall_entry(opcode, args);
+}
+
+void __trace_hcall_exit(long opcode, unsigned long retval,
+ unsigned long *retbuf)
+{
+ trace_hcall_exit(opcode, retval, retbuf);
+}
+#endif
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index bf2e1ac41308..1164c3430f2c 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -432,8 +432,6 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
/* Read config space back so we can restore after reset */
read_msi_msg(virq, &msg);
entry->msg = msg;
-
- unmask_msi_irq(virq);
}
return 0;
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 419f8a637ffe..b9bf0eedccf2 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/radix-tree.h>
#include <linux/cpu.h>
+#include <linux/msi.h>
#include <linux/of.h>
#include <asm/firmware.h>
@@ -219,6 +220,14 @@ static void xics_unmask_irq(unsigned int virq)
static unsigned int xics_startup(unsigned int virq)
{
+ /*
+ * The generic MSI code returns with the interrupt disabled on the
+ * card, using the MSI mask bits. Firmware doesn't appear to unmask
+ * at that level, so we do it here by hand.
+ */
+ if (irq_to_desc(virq)->msi_desc)
+ unmask_msi_irq(virq);
+
/* unmask it */
xics_unmask_irq(virq);
return 0;
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index c6f0a71b405e..bdbe96c8a7e4 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -517,6 +517,15 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
in_xmon = 0;
#endif
+#ifdef CONFIG_BOOKE
+ if (regs->msr & MSR_DE) {
+ bp = at_breakpoint(regs->nip);
+ if (bp != NULL) {
+ regs->nip = (unsigned long) &bp->instr[0];
+ atomic_inc(&bp->ref_count);
+ }
+ }
+#else
if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
bp = at_breakpoint(regs->nip);
if (bp != NULL) {
@@ -530,7 +539,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
}
}
}
-
+#endif
insert_cpu_bpts();
local_irq_restore(flags);
@@ -894,6 +903,14 @@ cmds(struct pt_regs *excp)
}
}
+#ifdef CONFIG_BOOKE
+static int do_step(struct pt_regs *regs)
+{
+ regs->msr |= MSR_DE;
+ mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
+ return 1;
+}
+#else
/*
* Step a single instruction.
* Some instructions we emulate, others we execute with MSR_SE set.
@@ -924,6 +941,7 @@ static int do_step(struct pt_regs *regs)
regs->msr |= MSR_SE;
return 1;
}
+#endif
static void bootcmds(void)
{
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 43c0acad7160..16c673096a22 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -95,6 +95,34 @@ config S390
select HAVE_ARCH_TRACEHOOK
select INIT_ALL_POSSIBLE
select HAVE_PERF_EVENTS
+ select ARCH_INLINE_SPIN_TRYLOCK
+ select ARCH_INLINE_SPIN_TRYLOCK_BH
+ select ARCH_INLINE_SPIN_LOCK
+ select ARCH_INLINE_SPIN_LOCK_BH
+ select ARCH_INLINE_SPIN_LOCK_IRQ
+ select ARCH_INLINE_SPIN_LOCK_IRQSAVE
+ select ARCH_INLINE_SPIN_UNLOCK
+ select ARCH_INLINE_SPIN_UNLOCK_BH
+ select ARCH_INLINE_SPIN_UNLOCK_IRQ
+ select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
+ select ARCH_INLINE_READ_TRYLOCK
+ select ARCH_INLINE_READ_LOCK
+ select ARCH_INLINE_READ_LOCK_BH
+ select ARCH_INLINE_READ_LOCK_IRQ
+ select ARCH_INLINE_READ_LOCK_IRQSAVE
+ select ARCH_INLINE_READ_UNLOCK
+ select ARCH_INLINE_READ_UNLOCK_BH
+ select ARCH_INLINE_READ_UNLOCK_IRQ
+ select ARCH_INLINE_READ_UNLOCK_IRQRESTORE
+ select ARCH_INLINE_WRITE_TRYLOCK
+ select ARCH_INLINE_WRITE_LOCK
+ select ARCH_INLINE_WRITE_LOCK_BH
+ select ARCH_INLINE_WRITE_LOCK_IRQ
+ select ARCH_INLINE_WRITE_LOCK_IRQSAVE
+ select ARCH_INLINE_WRITE_UNLOCK
+ select ARCH_INLINE_WRITE_UNLOCK_BH
+ select ARCH_INLINE_WRITE_UNLOCK_IRQ
+ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
config SCHED_OMIT_FRAME_POINTER
bool
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 704dd396257b..77df726180ba 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -438,7 +438,7 @@ static int diag204_probe(void)
}
if (diag204((unsigned long)SUBC_STIB6 |
(unsigned long)INFO_EXT, pages, buf) >= 0) {
- diag204_store_sc = SUBC_STIB7;
+ diag204_store_sc = SUBC_STIB6;
diag204_info_type = INFO_EXT;
goto out;
}
diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h
index 7efd0abe8887..efb74fd5156e 100644
--- a/arch/s390/include/asm/bug.h
+++ b/arch/s390/include/asm/bug.h
@@ -49,7 +49,7 @@
#define BUG() do { \
__EMIT_BUG(0); \
- for (;;); \
+ unreachable(); \
} while (0)
#define WARN_ON(x) ({ \
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index 24b1244aadb9..f23961ada7fb 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -78,7 +78,7 @@ cputime64_to_jiffies64(cputime64_t cputime)
static inline unsigned int
cputime_to_msecs(const cputime_t cputime)
{
- return __div(cputime, 4096000);
+ return cputime_div(cputime, 4096000);
}
static inline cputime_t
@@ -160,7 +160,7 @@ cputime_to_timeval(const cputime_t cputime, struct timeval *value)
static inline clock_t
cputime_to_clock_t(cputime_t cputime)
{
- return __div(cputime, 4096000000ULL / USER_HZ);
+ return cputime_div(cputime, 4096000000ULL / USER_HZ);
}
static inline cputime_t
@@ -175,7 +175,7 @@ clock_t_to_cputime(unsigned long x)
static inline clock_t
cputime64_to_clock_t(cputime64_t cputime)
{
- return __div(cputime, 4096000000ULL / USER_HZ);
+ return cputime_div(cputime, 4096000000ULL / USER_HZ);
}
struct s390_idle_data {
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h
index 41ce6861174e..c9af0d19c7ab 100644
--- a/arch/s390/include/asm/spinlock.h
+++ b/arch/s390/include/asm/spinlock.h
@@ -191,33 +191,4 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
#define _raw_read_relax(lock) cpu_relax()
#define _raw_write_relax(lock) cpu_relax()
-#define __always_inline__spin_lock
-#define __always_inline__read_lock
-#define __always_inline__write_lock
-#define __always_inline__spin_lock_bh
-#define __always_inline__read_lock_bh
-#define __always_inline__write_lock_bh
-#define __always_inline__spin_lock_irq
-#define __always_inline__read_lock_irq
-#define __always_inline__write_lock_irq
-#define __always_inline__spin_lock_irqsave
-#define __always_inline__read_lock_irqsave
-#define __always_inline__write_lock_irqsave
-#define __always_inline__spin_trylock
-#define __always_inline__read_trylock
-#define __always_inline__write_trylock
-#define __always_inline__spin_trylock_bh
-#define __always_inline__spin_unlock
-#define __always_inline__read_unlock
-#define __always_inline__write_unlock
-#define __always_inline__spin_unlock_bh
-#define __always_inline__read_unlock_bh
-#define __always_inline__write_unlock_bh
-#define __always_inline__spin_unlock_irq
-#define __always_inline__read_unlock_irq
-#define __always_inline__write_unlock_irq
-#define __always_inline__spin_unlock_irqrestore
-#define __always_inline__read_unlock_irqrestore
-#define __always_inline__write_unlock_irqrestore
-
#endif /* __ASM_SPINLOCK_H */
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index bf8b4ae7ff2d..e49e9e0c69fd 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -55,6 +55,7 @@ static void __init reset_tod_clock(void)
disabled_wait(0);
sched_clock_base_cc = TOD_UNIX_EPOCH;
+ S390_lowcore.last_update_clock = sched_clock_base_cc;
}
#ifdef CONFIG_SHARED_KERNEL
@@ -167,6 +168,14 @@ static noinline __init void create_kernel_nss(void)
return;
}
+ /* re-initialize cputime accounting. */
+ sched_clock_base_cc = get_clock();
+ S390_lowcore.last_update_clock = sched_clock_base_cc;
+ S390_lowcore.last_update_timer = 0x7fffffffffffffffULL;
+ S390_lowcore.user_timer = 0;
+ S390_lowcore.system_timer = 0;
+ asm volatile("SPT 0(%0)" : : "a" (&S390_lowcore.last_update_timer));
+
/* re-setup boot command line with new ipl vm parms */
ipl_update_parameters();
setup_boot_command_line();
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index f43d2ee54464..48215d15762b 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -565,10 +565,10 @@ pgm_svcper:
lh %r7,0x8a # get svc number from lowcore
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
- l %r1,__TI_task(%r9)
- mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
- mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
- mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
+ l %r8,__TI_task(%r9)
+ mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
+ mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS
+ mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index a6f7b20df616..9aff1d449b6e 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -543,10 +543,10 @@ pgm_svcper:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
- lg %r1,__TI_task(%r9)
- mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
- mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
- mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
+ lg %r8,__TI_task(%r9)
+ mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
+ mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
+ mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index f5fe34dd821b..5a82bc68193e 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -203,73 +203,10 @@ out:
#ifdef CONFIG_FTRACE_SYSCALLS
-extern unsigned long __start_syscalls_metadata[];
-extern unsigned long __stop_syscalls_metadata[];
extern unsigned int sys_call_table[];
-static struct syscall_metadata **syscalls_metadata;
-
-struct syscall_metadata *syscall_nr_to_meta(int nr)
-{
- if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
- return NULL;
-
- return syscalls_metadata[nr];
-}
-
-int syscall_name_to_nr(char *name)
-{
- int i;
-
- if (!syscalls_metadata)
- return -1;
- for (i = 0; i < NR_syscalls; i++)
- if (syscalls_metadata[i])
- if (!strcmp(syscalls_metadata[i]->name, name))
- return i;
- return -1;
-}
-
-void set_syscall_enter_id(int num, int id)
-{
- syscalls_metadata[num]->enter_id = id;
-}
-
-void set_syscall_exit_id(int num, int id)
+unsigned long __init arch_syscall_addr(int nr)
{
- syscalls_metadata[num]->exit_id = id;
-}
-
-static struct syscall_metadata *find_syscall_meta(unsigned long syscall)
-{
- struct syscall_metadata *start;
- struct syscall_metadata *stop;
- char str[KSYM_SYMBOL_LEN];
-
- start = (struct syscall_metadata *)__start_syscalls_metadata;
- stop = (struct syscall_metadata *)__stop_syscalls_metadata;
- kallsyms_lookup(syscall, NULL, NULL, NULL, str);
-
- for ( ; start < stop; start++) {
- if (start->name && !strcmp(start->name + 3, str + 3))
- return start;
- }
- return NULL;
-}
-
-static int __init arch_init_ftrace_syscalls(void)
-{
- struct syscall_metadata *meta;
- int i;
- syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls,
- GFP_KERNEL);
- if (!syscalls_metadata)
- return -ENOMEM;
- for (i = 0; i < NR_syscalls; i++) {
- meta = find_syscall_meta((unsigned long)sys_call_table[i]);
- syscalls_metadata[i] = meta;
- }
- return 0;
+ return (unsigned long)sys_call_table[nr];
}
-arch_initcall(arch_init_ftrace_syscalls);
#endif
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index ee57a42e6e93..4890ac6d7faa 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1595,10 +1595,9 @@ static void stop_run(struct shutdown_trigger *trigger)
{
if (strcmp(trigger->name, ON_PANIC_STR) == 0)
disabled_wait((unsigned long) __builtin_return_address(0));
- else {
- signal_processor(smp_processor_id(), sigp_stop);
- for (;;);
- }
+ while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+ cpu_relax();
+ for (;;);
}
static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index 802c8ab247f3..0729f36c2fe3 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -31,9 +31,9 @@ void __cpuinit print_cpu_info(void)
static int show_cpuinfo(struct seq_file *m, void *v)
{
- static const char *hwcap_str[9] = {
+ static const char *hwcap_str[10] = {
"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
- "edat", "etf3eh"
+ "edat", "etf3eh", "highgprs"
};
struct _lowcore *lc;
unsigned long n = (unsigned long) v - 1;
@@ -48,7 +48,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
num_online_cpus(), loops_per_jiffy/(500000/HZ),
(loops_per_jiffy/(5000/HZ))%100);
seq_puts(m, "features\t: ");
- for (i = 0; i < 9; i++)
+ for (i = 0; i < 10; i++)
if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
seq_printf(m, "%s ", hwcap_str[i]);
seq_puts(m, "\n");
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index c932caa5e850..93e52039321b 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -76,7 +76,6 @@ static int cpu_stopped(int cpu)
__u32 status;
switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) {
- case sigp_order_code_accepted:
case sigp_status_stored:
/* Check for stopped and check stop state */
if (status & 0x50)
@@ -638,6 +637,8 @@ void __cpu_die(unsigned int cpu)
/* Wait until target cpu is down */
while (!cpu_stopped(cpu))
cpu_relax();
+ while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy)
+ udelay(10);
smp_free_lowcore(cpu);
pr_info("Processor %d stopped\n", cpu);
}
@@ -645,8 +646,8 @@ void __cpu_die(unsigned int cpu)
void cpu_die(void)
{
idle_task_exit();
- signal_processor(smp_processor_id(), sigp_stop);
- BUG();
+ while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+ cpu_relax();
for (;;);
}
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index 7c8653e27db6..0c26cc1898ec 100644
--- a/arch/s390/kernel/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -199,6 +199,7 @@ pgm_check_entry:
brc 2,4b /* busy, try again */
5:
sigp %r9,%r2,__SIGP_STOP /* stop resume (current) CPU */
+ brc 2,5b /* busy, try again */
6: j 6b
restart_suspend:
@@ -206,6 +207,7 @@ restart_suspend:
llgh %r2,0(%r1)
7:
sigp %r9,%r2,__SIGP_SENSE /* Wait for resume CPU */
+ brc 8,7b /* accepted, status 0, still running */
brc 2,7b /* busy, try again */
tmll %r9,0x40 /* Test if resume CPU is stopped */
jz 7b
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index b940424f8ccc..88cdeb9f72d9 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -37,7 +37,6 @@ config SUPERH32
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
- select HAVE_FTRACE_SYSCALLS
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_ARCH_KGDB
select ARCH_HIBERNATION_POSSIBLE if MMU
@@ -122,6 +121,9 @@ config SYS_SUPPORTS_APM_EMULATION
bool
select ARCH_SUSPEND_POSSIBLE
+config SYS_SUPPORTS_HUGETLBFS
+ bool
+
config SYS_SUPPORTS_SMP
bool
@@ -196,6 +198,7 @@ config CPU_SH4
select CPU_HAS_SR_RB
select CPU_HAS_FPU if !CPU_SH4AL_DSP
select SYS_SUPPORTS_TMU
+ select SYS_SUPPORTS_HUGETLBFS if MMU
config CPU_SH4A
bool
@@ -210,6 +213,7 @@ config CPU_SH5
bool
select CPU_HAS_FPU
select SYS_SUPPORTS_TMU
+ select SYS_SUPPORTS_HUGETLBFS if MMU
config CPU_SHX2
bool
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index fc51a918b31a..66e40aabc600 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -199,7 +199,7 @@ endif
libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
-BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec \
+BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec uImage.bin \
zImage vmlinux.srec romImage
PHONY += maketools $(BOOT_TARGETS) FORCE
@@ -225,6 +225,7 @@ define archhelp
@echo ' vmlinux.srec - Create an ELF S-record'
@echo '* uImage - Alias to bootable U-Boot image'
@echo ' uImage.srec - Create an S-record for U-Boot'
+ @echo ' uImage.bin - Kernel-only image for U-Boot (bin)'
@echo '* uImage.gz - Kernel-only image for U-Boot (gzip)'
@echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)'
@echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)'
diff --git a/arch/sh/boards/mach-landisk/gio.c b/arch/sh/boards/mach-landisk/gio.c
index 25cdf7358000..528013188196 100644
--- a/arch/sh/boards/mach-landisk/gio.c
+++ b/arch/sh/boards/mach-landisk/gio.c
@@ -14,7 +14,6 @@
*/
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/fs.h>
@@ -35,7 +34,7 @@ static int gio_open(struct inode *inode, struct file *filp)
int minor;
int ret = -ENOENT;
- lock_kernel();
+ preempt_disable();
minor = MINOR(inode->i_rdev);
if (minor < DEVCOUNT) {
if (openCnt > 0) {
@@ -45,7 +44,7 @@ static int gio_open(struct inode *inode, struct file *filp)
ret = 0;
}
}
- unlock_kernel();
+ preempt_enable();
return ret;
}
@@ -60,8 +59,7 @@ static int gio_close(struct inode *inode, struct file *filp)
return 0;
}
-static int gio_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static long gio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int data;
static unsigned int addr = 0;
@@ -129,7 +127,7 @@ static const struct file_operations gio_fops = {
.owner = THIS_MODULE,
.open = gio_open, /* open */
.release = gio_close, /* release */
- .ioctl = gio_ioctl, /* ioctl */
+ .unlocked_ioctl = gio_ioctl,
};
static int __init gio_init(void)
diff --git a/arch/sh/boards/mach-rsk/devices-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c
index 4af3a771c058..c37617e63220 100644
--- a/arch/sh/boards/mach-rsk/devices-rsk7203.c
+++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c
@@ -11,10 +11,6 @@
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/map.h>
#include <linux/smsc911x.h>
#include <linux/gpio.h>
#include <linux/leds.h>
diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c
index af64d030a5c7..a5c0df785bfe 100644
--- a/arch/sh/boards/mach-rsk/setup.c
+++ b/arch/sh/boards/mach-rsk/setup.c
@@ -15,14 +15,12 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
+#ifdef CONFIG_MTD
#include <linux/mtd/map.h>
+#endif
#include <asm/machvec.h>
#include <asm/io.h>
-static const char *probes[] = { "cmdlinepart", NULL };
-
-static struct mtd_partition *parsed_partitions;
-
static struct mtd_partition rsk_partitions[] = {
{
.name = "Bootloader",
@@ -41,6 +39,8 @@ static struct mtd_partition rsk_partitions[] = {
};
static struct physmap_flash_data flash_data = {
+ .parts = rsk_partitions,
+ .nr_parts = ARRAY_SIZE(rsk_partitions),
.width = 2,
};
@@ -60,7 +60,8 @@ static struct platform_device flash_device = {
},
};
-static struct mtd_info *flash_mtd;
+#ifdef CONFIG_MTD
+static const char *probes[] = { "cmdlinepart", NULL };
static struct map_info rsk_flash_map = {
.name = "RSK+ Flash",
@@ -68,6 +69,10 @@ static struct map_info rsk_flash_map = {
.bankwidth = 2,
};
+static struct mtd_info *flash_mtd;
+
+static struct mtd_partition *parsed_partitions;
+
static void __init set_mtd_partitions(void)
{
int nr_parts = 0;
@@ -77,14 +82,14 @@ static void __init set_mtd_partitions(void)
nr_parts = parse_mtd_partitions(flash_mtd, probes,
&parsed_partitions, 0);
/* If there is no partition table, used the hard coded table */
- if (nr_parts <= 0) {
- flash_data.parts = rsk_partitions;
- flash_data.nr_parts = ARRAY_SIZE(rsk_partitions);
- } else {
+ if (nr_parts > 0) {
flash_data.nr_parts = nr_parts;
flash_data.parts = parsed_partitions;
}
}
+#else
+static inline void set_mtd_partitions(void) {}
+#endif
static struct platform_device *rsk_devices[] __initdata = {
&flash_device,
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index a1316872be6f..cb8cf5572e79 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -20,11 +20,12 @@ CONFIG_BOOT_LINK_OFFSET ?= 0x00800000
CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000
CONFIG_ENTRY_OFFSET ?= 0x00001000
+suffix-y := bin
suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
suffix-$(CONFIG_KERNEL_LZMA) := lzma
-targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma
+targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma uImage.bin
extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
subdir- := compressed romimage
@@ -88,6 +89,9 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
$(call if_changed,uimage,lzma)
+$(obj)/uImage.bin: $(obj)/vmlinux.bin
+ $(call if_changed,uimage,none)
+
OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux
$(call if_changed,objcopy)
diff --git a/arch/sh/include/asm/rwsem.h b/arch/sh/include/asm/rwsem.h
index 1987f3ea7f1b..06e2251a5e48 100644
--- a/arch/sh/include/asm/rwsem.h
+++ b/arch/sh/include/asm/rwsem.h
@@ -41,7 +41,7 @@ struct rw_semaphore {
#endif
#define __RWSEM_INITIALIZER(name) \
- { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+ { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
LIST_HEAD_INIT((name).wait_list) \
__RWSEM_DEP_MAP_INIT(name) }
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c
index 6b5d191eec3a..a351ed84eec5 100644
--- a/arch/sh/kernel/cpu/irq/imask.c
+++ b/arch/sh/kernel/cpu/irq/imask.c
@@ -68,7 +68,7 @@ static void unmask_imask_irq(unsigned int irq)
}
static struct irq_chip imask_irq_chip = {
- .typename = "SR.IMASK",
+ .name = "SR.IMASK",
.mask = mask_imask_irq,
.unmask = unmask_imask_irq,
.mask_ack = mask_imask_irq,
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index 6c092f1f5557..06e7e2959b54 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -85,7 +85,7 @@ static void mask_and_ack_intc(unsigned int);
static void end_intc_irq(unsigned int irq);
static struct irq_chip intc_irq_type = {
- .typename = "INTC",
+ .name = "INTC",
.startup = startup_intc_irq,
.shutdown = shutdown_intc_irq,
.enable = enable_intc_irq,
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index 03b3616c80a5..d76a23170dbb 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -20,6 +20,7 @@
#include <linux/list.h>
#include <linux/mempool.h>
#include <linux/mm.h>
+#include <linux/ftrace.h>
#include <asm/dwarf.h>
#include <asm/unwinder.h>
#include <asm/sections.h>
@@ -554,9 +555,30 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
* NOTE: the return address is guaranteed to be setup by the
* time this function makes its first function call.
*/
- if (!pc && !prev)
+ if (!pc || !prev)
pc = (unsigned long)current_text_addr();
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ /*
+ * If our stack has been patched by the function graph tracer
+ * then we might see the address of return_to_handler() where we
+ * expected to find the real return address.
+ */
+ if (pc == (unsigned long)&return_to_handler) {
+ int index = current->curr_ret_stack;
+
+ /*
+ * We currently have no way of tracking how many
+ * return_to_handler()'s we've seen. If there is more
+ * than one patched return address on our stack,
+ * complain loudly.
+ */
+ WARN_ON(index > 0);
+
+ pc = current->ret_stack[index].ret;
+ }
+#endif
+
frame = mempool_alloc(dwarf_frame_pool, GFP_ATOMIC);
if (!frame) {
printk(KERN_ERR "Unable to allocate a dwarf frame\n");
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 68d9223b145e..3eb84931d2aa 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -121,7 +121,7 @@ noresched:
ENTRY(resume_userspace)
! r8: current_thread_info
cli
- TRACE_IRQS_OfF
+ TRACE_IRQS_OFF
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
tst #(_TIF_WORK_MASK & 0xff), r0
bt/s __restore_all
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index a3dcc6d5d253..2c48e267256e 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -291,31 +291,48 @@ struct syscall_metadata *syscall_nr_to_meta(int nr)
return syscalls_metadata[nr];
}
-void arch_init_ftrace_syscalls(void)
+int syscall_name_to_nr(char *name)
+{
+ int i;
+
+ if (!syscalls_metadata)
+ return -1;
+ for (i = 0; i < NR_syscalls; i++)
+ if (syscalls_metadata[i])
+ if (!strcmp(syscalls_metadata[i]->name, name))
+ return i;
+ return -1;
+}
+
+void set_syscall_enter_id(int num, int id)
+{
+ syscalls_metadata[num]->enter_id = id;
+}
+
+void set_syscall_exit_id(int num, int id)
+{
+ syscalls_metadata[num]->exit_id = id;
+}
+
+static int __init arch_init_ftrace_syscalls(void)
{
int i;
struct syscall_metadata *meta;
unsigned long **psys_syscall_table = &sys_call_table;
- static atomic_t refs;
-
- if (atomic_inc_return(&refs) != 1)
- goto end;
syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
FTRACE_SYSCALL_MAX, GFP_KERNEL);
if (!syscalls_metadata) {
WARN_ON(1);
- return;
+ return -ENOMEM;
}
for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
meta = find_syscall_meta(psys_syscall_table[i]);
syscalls_metadata[i] = meta;
}
- return;
- /* Paranoid: avoid overflow */
-end:
- atomic_dec(&refs);
+ return 0;
}
+arch_initcall(arch_init_ftrace_syscalls);
#endif /* CONFIG_FTRACE_SYSCALLS */
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 7cb933ba4957..eac7da772fc2 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/kernel_stat.h>
#include <linux/seq_file.h>
+#include <linux/ftrace.h>
#include <asm/processor.h>
#include <asm/machvec.h>
#include <asm/uaccess.h>
@@ -106,7 +107,7 @@ static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
#endif
-asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
+asmlinkage __irq_entry int do_IRQ(unsigned int irq, struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
#ifdef CONFIG_IRQSTACKS
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index f9d44f8e0df6..99b4fb553bf1 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -549,6 +549,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
if (cpu == 0)
seq_printf(m, "machine\t\t: %s\n", get_system_type());
+ else
+ seq_printf(m, "\n");
seq_printf(m, "processor\t: %d\n", cpu);
seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 86c270428357..444cce3ae921 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -85,6 +85,20 @@ DECLARE_EXPORT(__movstr_i4_even);
DECLARE_EXPORT(__movstr_i4_odd);
DECLARE_EXPORT(__movstrSI12_i4);
DECLARE_EXPORT(__movmem);
+DECLARE_EXPORT(__movmemSI8);
+DECLARE_EXPORT(__movmemSI12);
+DECLARE_EXPORT(__movmemSI16);
+DECLARE_EXPORT(__movmemSI20);
+DECLARE_EXPORT(__movmemSI24);
+DECLARE_EXPORT(__movmemSI28);
+DECLARE_EXPORT(__movmemSI32);
+DECLARE_EXPORT(__movmemSI36);
+DECLARE_EXPORT(__movmemSI40);
+DECLARE_EXPORT(__movmemSI44);
+DECLARE_EXPORT(__movmemSI48);
+DECLARE_EXPORT(__movmemSI52);
+DECLARE_EXPORT(__movmemSI56);
+DECLARE_EXPORT(__movmemSI60);
DECLARE_EXPORT(__movmem_i4_even);
DECLARE_EXPORT(__movmem_i4_odd);
DECLARE_EXPORT(__movmemSI12_i4);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 6729703547a1..3db37425210d 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -145,7 +145,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
{
struct task_struct *tsk = current;
- if (!(current_cpu_data.flags & CPU_HAS_FPU))
+ if (!(boot_cpu_data.flags & CPU_HAS_FPU))
return 0;
set_used_math();
@@ -158,7 +158,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
{
struct task_struct *tsk = current;
- if (!(current_cpu_data.flags & CPU_HAS_FPU))
+ if (!(boot_cpu_data.flags & CPU_HAS_FPU))
return 0;
if (!used_math()) {
@@ -199,7 +199,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
#undef COPY
#ifdef CONFIG_SH_FPU
- if (current_cpu_data.flags & CPU_HAS_FPU) {
+ if (boot_cpu_data.flags & CPU_HAS_FPU) {
int owned_fp;
struct task_struct *tsk = current;
@@ -472,6 +472,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(OR_R0_R0, &frame->retcode[6]);
err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]);
regs->pr = (unsigned long) frame->retcode;
+ flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
}
if (err)
@@ -497,8 +498,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
- flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
-
return 0;
give_sigsegv:
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 442d8d47a41e..160db1003cfb 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -35,6 +35,8 @@ static inline void __init smp_store_cpu_info(unsigned int cpu)
{
struct sh_cpuinfo *c = cpu_data + cpu;
+ memcpy(c, &boot_cpu_data, sizeof(struct sh_cpuinfo));
+
c->loops_per_jiffy = loops_per_jiffy;
}
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index e0b5e4b5accd..7a2ee3a6b8e7 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -25,6 +25,7 @@
#include <linux/kexec.h>
#include <linux/limits.h>
#include <linux/proc_fs.h>
+#include <linux/sysfs.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/fpu.h>
@@ -159,12 +160,12 @@ void die(const char * str, struct pt_regs * regs, long err)
oops_enter();
- console_verbose();
spin_lock_irq(&die_lock);
+ console_verbose();
bust_spinlocks(1);
printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
-
+ sysfs_printk_last_file();
print_modules();
show_regs(regs);
@@ -180,6 +181,7 @@ void die(const char * str, struct pt_regs * regs, long err)
bust_spinlocks(0);
add_taint(TAINT_DIE);
spin_unlock_irq(&die_lock);
+ oops_exit();
if (kexec_should_crash(current))
crash_kexec(regs);
@@ -190,7 +192,6 @@ void die(const char * str, struct pt_regs * regs, long err)
if (panic_on_oops)
panic("Fatal exception");
- oops_exit();
do_exit(SIGSEGV);
}
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 64dc1ad59801..7f7b52f9beba 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -227,7 +227,7 @@ endchoice
choice
prompt "HugeTLB page size"
- depends on HUGETLB_PAGE && (CPU_SH4 || CPU_SH5) && MMU
+ depends on HUGETLB_PAGE
default HUGETLB_PAGE_SIZE_1MB if PAGE_SIZE_64KB
default HUGETLB_PAGE_SIZE_64K
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index a98c7d8984fa..b7f235c74d66 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -26,7 +26,7 @@
#define MAX_DCACHE_PAGES 64 /* XXX: Tune for ways */
#define MAX_ICACHE_PAGES 32
-static void __flush_cache_4096(unsigned long addr, unsigned long phys,
+static void __flush_cache_one(unsigned long addr, unsigned long phys,
unsigned long exec_offset);
/*
@@ -72,6 +72,7 @@ static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
for (v = start; v < end; v += L1_CACHE_BYTES) {
unsigned long icacheaddr;
+ int j, n;
__ocbwb(v);
@@ -79,8 +80,10 @@ static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
cpu_data->icache.entry_mask);
/* Clear i-cache line valid-bit */
+ n = boot_cpu_data.icache.n_aliases;
for (i = 0; i < cpu_data->icache.ways; i++) {
- __raw_writel(0, icacheaddr);
+ for (j = 0; j < n; j++)
+ __raw_writel(0, icacheaddr + (j * PAGE_SIZE));
icacheaddr += cpu_data->icache.way_incr;
}
}
@@ -89,8 +92,7 @@ static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
local_irq_restore(flags);
}
-static inline void flush_cache_4096(unsigned long start,
- unsigned long phys)
+static inline void flush_cache_one(unsigned long start, unsigned long phys)
{
unsigned long flags, exec_offset = 0;
@@ -103,8 +105,7 @@ static inline void flush_cache_4096(unsigned long start,
exec_offset = 0x20000000;
local_irq_save(flags);
- __flush_cache_4096(start | SH_CACHE_ASSOC,
- P1SEGADDR(phys), exec_offset);
+ __flush_cache_one(start | SH_CACHE_ASSOC, P1SEGADDR(phys), exec_offset);
local_irq_restore(flags);
}
@@ -129,8 +130,8 @@ static void sh4_flush_dcache_page(void *arg)
/* Loop all the D-cache */
n = boot_cpu_data.dcache.n_aliases;
- for (i = 0; i < n; i++, addr += 4096)
- flush_cache_4096(addr, phys);
+ for (i = 0; i < n; i++, addr += PAGE_SIZE)
+ flush_cache_one(addr, phys);
}
wmb();
@@ -318,11 +319,11 @@ static void sh4_flush_cache_page(void *args)
/* We only need to flush D-cache when we have alias */
if ((address^phys) & alias_mask) {
/* Loop 4K of the D-cache */
- flush_cache_4096(
+ flush_cache_one(
CACHE_OC_ADDRESS_ARRAY | (address & alias_mask),
phys);
/* Loop another 4K of the D-cache */
- flush_cache_4096(
+ flush_cache_one(
CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask),
phys);
}
@@ -337,7 +338,7 @@ static void sh4_flush_cache_page(void *args)
* kernel has never executed the code through its identity
* translation.
*/
- flush_cache_4096(
+ flush_cache_one(
CACHE_IC_ADDRESS_ARRAY | (address & alias_mask),
phys);
}
@@ -393,7 +394,7 @@ static void sh4_flush_cache_range(void *args)
}
/**
- * __flush_cache_4096
+ * __flush_cache_one
*
* @addr: address in memory mapped cache array
* @phys: P1 address to flush (has to match tags if addr has 'A' bit
@@ -406,7 +407,7 @@ static void sh4_flush_cache_range(void *args)
* operation (purge/write-back) is selected by the lower 2 bits of
* 'phys'.
*/
-static void __flush_cache_4096(unsigned long addr, unsigned long phys,
+static void __flush_cache_one(unsigned long addr, unsigned long phys,
unsigned long exec_offset)
{
int way_count;
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 35c37b7f717a..a2dc7f9ecc51 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -128,7 +128,7 @@ void __update_cache(struct vm_area_struct *vma,
return;
page = pfn_to_page(pfn);
- if (pfn_valid(pfn) && page_mapping(page)) {
+ if (pfn_valid(pfn)) {
int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
if (dirty) {
unsigned long addr = (unsigned long)page_address(page);
@@ -265,6 +265,8 @@ static void __init emit_cache_params(void)
void __init cpu_cache_init(void)
{
+ unsigned int cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE);
+
compute_alias(&boot_cpu_data.icache);
compute_alias(&boot_cpu_data.dcache);
compute_alias(&boot_cpu_data.scache);
@@ -273,6 +275,13 @@ void __init cpu_cache_init(void)
__flush_purge_region = noop__flush_region;
__flush_invalidate_region = noop__flush_region;
+ /*
+ * No flushing is necessary in the disabled cache case so we can
+ * just keep the noop functions in local_flush_..() and __flush_..()
+ */
+ if (unlikely(cache_disabled))
+ goto skip;
+
if (boot_cpu_data.family == CPU_FAMILY_SH2) {
extern void __weak sh2_cache_init(void);
@@ -312,5 +321,6 @@ void __init cpu_cache_init(void)
sh5_cache_init();
}
+skip:
emit_cache_params();
}
diff --git a/arch/sparc/boot/btfixupprep.c b/arch/sparc/boot/btfixupprep.c
index 52a4208fe4f0..bbf91b9c3d39 100644
--- a/arch/sparc/boot/btfixupprep.c
+++ b/arch/sparc/boot/btfixupprep.c
@@ -61,14 +61,14 @@ unsigned long lastfoffset = -1;
unsigned long lastfrelno;
btfixup *lastf;
-void fatal(void) __attribute__((noreturn));
-void fatal(void)
+static void fatal(void) __attribute__((noreturn));
+static void fatal(void)
{
fprintf(stderr, "Malformed output from objdump\n%s\n", buffer);
exit(1);
}
-btfixup *find(int type, char *name)
+static btfixup *find(int type, char *name)
{
int i;
for (i = 0; i < last; i++) {
@@ -88,7 +88,7 @@ btfixup *find(int type, char *name)
return array + last - 1;
}
-void set_mode (char *buffer)
+static void set_mode (char *buffer)
{
for (mode = 0;; mode++)
if (buffer[mode] < '0' || buffer[mode] > '9')
diff --git a/arch/sparc/boot/piggyback_32.c b/arch/sparc/boot/piggyback_32.c
index e8dc9adfcd61..ac944aec7301 100644
--- a/arch/sparc/boot/piggyback_32.c
+++ b/arch/sparc/boot/piggyback_32.c
@@ -35,17 +35,17 @@
* as PROM looks for a.out image only.
*/
-unsigned short ld2(char *p)
+static unsigned short ld2(char *p)
{
return (p[0] << 8) | p[1];
}
-unsigned int ld4(char *p)
+static unsigned int ld4(char *p)
{
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
-void st4(char *p, unsigned int x)
+static void st4(char *p, unsigned int x)
{
p[0] = x >> 24;
p[1] = x >> 16;
@@ -53,7 +53,7 @@ void st4(char *p, unsigned int x)
p[3] = x;
}
-void usage(void)
+static void usage(void)
{
/* fs_img.gz is an image of initial ramdisk. */
fprintf(stderr, "Usage: piggyback vmlinux.aout System.map fs_img.gz\n");
@@ -61,7 +61,7 @@ void usage(void)
exit(1);
}
-void die(char *str)
+static void die(char *str)
{
perror (str);
exit(1);
diff --git a/arch/sparc/boot/piggyback_64.c b/arch/sparc/boot/piggyback_64.c
index c63fd1b6bdd4..a26a686cb5aa 100644
--- a/arch/sparc/boot/piggyback_64.c
+++ b/arch/sparc/boot/piggyback_64.c
@@ -32,7 +32,7 @@
/* Note: run this on an a.out kernel (use elftoaout for it), as PROM looks for a.out image onlly
usage: piggyback vmlinux System.map tail, where tail is gzipped fs of the initial ramdisk */
-void die(char *str)
+static void die(char *str)
{
perror (str);
exit(1);
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h
index 25e848f0cad7..d47a98e66972 100644
--- a/arch/sparc/include/asm/system_64.h
+++ b/arch/sparc/include/asm/system_64.h
@@ -63,6 +63,10 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
: : : "memory"); \
} while (0)
+/* The kernel always executes in TSO memory model these days,
+ * and furthermore most sparc64 chips implement more stringent
+ * memory ordering than required by the specifications.
+ */
#define mb() membar_safe("#StoreLoad")
#define rmb() __asm__ __volatile__("":::"memory")
#define wmb() __asm__ __volatile__("":::"memory")
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
index adf5f273868a..cb3c72c45aab 100644
--- a/arch/sparc/kernel/ldc.c
+++ b/arch/sparc/kernel/ldc.c
@@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name)
snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
err = request_irq(lp->cfg.rx_irq, ldc_rx,
- IRQF_SAMPLE_RANDOM | IRQF_SHARED,
+ IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
lp->rx_irq_name, lp);
if (err)
return err;
err = request_irq(lp->cfg.tx_irq, ldc_tx,
- IRQF_SAMPLE_RANDOM | IRQF_SHARED,
+ IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
lp->tx_irq_name, lp);
if (err) {
free_irq(lp->cfg.rx_irq, lp);
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 04db92743896..fa5936e1c3b9 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -437,7 +437,7 @@ static const struct sparc_pmu niagara2_pmu = {
.lower_shift = 6,
.event_mask = 0xfff,
.hv_bit = 0x8,
- .irq_bit = 0x03,
+ .irq_bit = 0x30,
.upper_nop = 0x220,
.lower_nop = 0x220,
};
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 138910c67206..d80a65d9e893 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -79,6 +79,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
err = -ENODEV;
+ mutex_lock(&of_set_property_mutex);
write_lock(&devtree_lock);
prevp = &dp->properties;
while (*prevp) {
@@ -88,9 +89,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
void *old_val = prop->value;
int ret;
- mutex_lock(&of_set_property_mutex);
ret = prom_setprop(dp->node, name, val, len);
- mutex_unlock(&of_set_property_mutex);
err = -EINVAL;
if (ret >= 0) {
@@ -109,6 +108,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
prevp = &(*prevp)->next;
}
write_unlock(&devtree_lock);
+ mutex_unlock(&of_set_property_mutex);
/* XXX Upate procfs if necessary... */
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c
index b956fd71c131..d231cbd5c526 100644
--- a/arch/sparc/kernel/visemul.c
+++ b/arch/sparc/kernel/visemul.c
@@ -617,7 +617,7 @@ static void pmul(struct pt_regs *regs, unsigned int insn, unsigned int opf)
rs2 = fps_regval(f, RS2(insn));
rd_val = 0;
- src2 = (rs2 >> (opf == FMUL8x16AU_OPF) ? 16 : 0);
+ src2 = rs2 >> (opf == FMUL8x16AU_OPF ? 16 : 0);
for (byte = 0; byte < 4; byte++) {
u16 src1 = (rs1 >> (byte * 8)) & 0x00ff;
u32 prod = src1 * src2;
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index a70a5e1904d9..1886d37d411b 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -265,7 +265,7 @@ static void flush_dcache(unsigned long pfn)
struct page *page;
page = pfn_to_page(pfn);
- if (page && page_mapping(page)) {
+ if (page) {
unsigned long pg_flags;
pg_flags = page->flags;
diff --git a/arch/sparc/mm/init_64.h b/arch/sparc/mm/init_64.h
index c2f772dbd556..77d1b313e344 100644
--- a/arch/sparc/mm/init_64.h
+++ b/arch/sparc/mm/init_64.h
@@ -45,7 +45,7 @@ extern void free_initmem(void);
#define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK)
#define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \
- sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT)
+ sizeof(struct page)) >> VMEMMAP_CHUNK_SHIFT)
extern unsigned long vmemmap_table[VMEMMAP_SIZE];
#endif
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c876bace8fdc..178084b4377c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -49,6 +49,7 @@ config X86
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
+ select HAVE_HW_BREAKPOINT
select HAVE_ARCH_KMEMCHECK
config OUTPUT_FORMAT
@@ -491,7 +492,7 @@ if PARAVIRT_GUEST
source "arch/x86/xen/Kconfig"
config VMI
- bool "VMI Guest support"
+ bool "VMI Guest support (DEPRECATED)"
select PARAVIRT
depends on X86_32
---help---
@@ -500,6 +501,15 @@ config VMI
at the moment), by linking the kernel to a GPL-ed ROM module
provided by the hypervisor.
+ As of September 2009, VMware has started a phased retirement
+ of this feature from VMware's products. Please see
+ feature-removal-schedule.txt for details. If you are
+ planning to enable this option, please note that you cannot
+ live migrate a VMI enabled VM to a future VMware product,
+ which doesn't support VMI. So if you expect your kernel to
+ seamlessly migrate to newer VMware products, keep this
+ disabled.
+
config KVM_CLOCK
bool "KVM paravirtualized clock"
select PARAVIRT
@@ -1434,12 +1444,8 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here.
-config CC_STACKPROTECTOR_ALL
- bool
-
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
- select CC_STACKPROTECTOR_ALL
---help---
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of functions, a canary value on
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index f2824fb8c79c..5e99762eb5c2 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -400,13 +400,13 @@ config X86_TSC
config X86_CMPXCHG64
def_bool y
- depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM
+ depends on !M386 && !M486
# this should be set for all -march=.. options where the compiler
# generates cmov.
config X86_CMOV
def_bool y
- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM)
+ depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
config X86_MINIMUM_CPU_FAMILY
int
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index d105f29bb6bb..731318e5ac1d 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -186,6 +186,15 @@ config X86_DS_SELFTEST
config HAVE_MMIOTRACE_SUPPORT
def_bool y
+config X86_DECODER_SELFTEST
+ bool "x86 instruction decoder selftest"
+ depends on DEBUG_KERNEL
+ ---help---
+ Perform x86 instruction decoder selftests at build time.
+ This option is useful for checking the sanity of x86 instruction
+ decoder code.
+ If unsure, say "N".
+
#
# IO delay types:
#
@@ -287,4 +296,18 @@ config OPTIMIZE_INLINING
If unsure, say N.
+config DEBUG_STRICT_USER_COPY_CHECKS
+ bool "Strict copy size checks"
+ depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING
+ ---help---
+ Enabling this option turns a certain set of sanity checks for user
+ copy operations into compile time failures.
+
+ The copy_from_user() etc checks are there to help test if there
+ are sufficient security checks on the length argument of
+ the copy operation, by having gcc prove that the argument is
+ within bounds.
+
+ If unsure, or if you run an older (pre 4.4) gcc, say N.
+
endmenu
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index a012ee8ef803..78b32be55e9e 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -76,7 +76,6 @@ ifdef CONFIG_CC_STACKPROTECTOR
cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y)
stackp-y := -fstack-protector
- stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all
KBUILD_CFLAGS += $(stackp-y)
else
$(warning stack protector enabled but no compiler support)
@@ -156,6 +155,9 @@ all: bzImage
KBUILD_IMAGE := $(boot)/bzImage
bzImage: vmlinux
+ifeq ($(CONFIG_X86_DECODER_SELFTEST),y)
+ $(Q)$(MAKE) $(build)=arch/x86/tools posttest
+endif
$(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
$(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot
$(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/$@
diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
index 30e9a264f69d..cbf0776dbec1 100644
--- a/arch/x86/Makefile_32.cpu
+++ b/arch/x86/Makefile_32.cpu
@@ -41,7 +41,7 @@ cflags-$(CONFIG_X86_ELAN) += -march=i486
# Geode GX1 support
cflags-$(CONFIG_MGEODEGX1) += -march=pentium-mmx
-
+cflags-$(CONFIG_MGEODE_LX) += $(call cc-option,-march=geode,-march=pentium-mmx)
# add at the end to overwrite eventual tuning options from earlier
# cpu entries
cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686))
diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld
index 0f6ec455a2b1..03c0683636b6 100644
--- a/arch/x86/boot/setup.ld
+++ b/arch/x86/boot/setup.ld
@@ -53,6 +53,9 @@ SECTIONS
/DISCARD/ : { *(.note*) }
+ /*
+ * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
+ */
. = ASSERT(_end <= 0x8000, "Setup too big!");
. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
/* Necessary for the very-old-loader check to work... */
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 585edebe12cf..49c552c060e9 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -82,7 +82,7 @@ static int aes_set_key_common(struct crypto_tfm *tfm, void *raw_ctx,
return -EINVAL;
}
- if (irq_fpu_usable())
+ if (!irq_fpu_usable())
err = crypto_aes_expand_key(ctx, in_key, key_len);
else {
kernel_fpu_begin();
@@ -103,7 +103,7 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
{
struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
- if (irq_fpu_usable())
+ if (!irq_fpu_usable())
crypto_aes_encrypt_x86(ctx, dst, src);
else {
kernel_fpu_begin();
@@ -116,7 +116,7 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
{
struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
- if (irq_fpu_usable())
+ if (!irq_fpu_usable())
crypto_aes_decrypt_x86(ctx, dst, src);
else {
kernel_fpu_begin();
@@ -342,7 +342,7 @@ static int ablk_encrypt(struct ablkcipher_request *req)
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
- if (irq_fpu_usable()) {
+ if (!irq_fpu_usable()) {
struct ablkcipher_request *cryptd_req =
ablkcipher_request_ctx(req);
memcpy(cryptd_req, req, sizeof(*req));
@@ -363,7 +363,7 @@ static int ablk_decrypt(struct ablkcipher_request *req)
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
- if (irq_fpu_usable()) {
+ if (!irq_fpu_usable()) {
struct ablkcipher_request *cryptd_req =
ablkcipher_request_ctx(req);
memcpy(cryptd_req, req, sizeof(*req));
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 1733f9f65e82..581b0568fe19 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -204,7 +204,7 @@ sysexit_from_sys_call:
movl RDI-ARGOFFSET(%rsp),%r8d /* reload 5th syscall arg */
.endm
- .macro auditsys_exit exit,ebpsave=RBP
+ .macro auditsys_exit exit
testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10)
jnz ia32_ret_from_sys_call
TRACE_IRQS_ON
@@ -217,7 +217,6 @@ sysexit_from_sys_call:
call audit_syscall_exit
GET_THREAD_INFO(%r10)
movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall return value */
- movl \ebpsave-ARGOFFSET(%rsp),%ebp /* reload user register value */
movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
cli
TRACE_IRQS_OFF
@@ -351,7 +350,7 @@ cstar_auditsys:
jmp cstar_dispatch
sysretl_audit:
- auditsys_exit sysretl_from_sys_call, RCX /* user %ebp in RCX slot */
+ auditsys_exit sysretl_from_sys_call
#endif
cstar_tracesys:
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index 4a8e80cdcfa5..9f828f87ca35 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -10,6 +10,7 @@ header-y += ptrace-abi.h
header-y += sigcontext32.h
header-y += ucontext.h
header-y += processor-flags.h
+header-y += hw_breakpoint.h
unifdef-y += e820.h
unifdef-y += ist.h
diff --git a/arch/x86/include/asm/a.out-core.h b/arch/x86/include/asm/a.out-core.h
index bb70e397aa84..7a15588e45d4 100644
--- a/arch/x86/include/asm/a.out-core.h
+++ b/arch/x86/include/asm/a.out-core.h
@@ -17,6 +17,7 @@
#include <linux/user.h>
#include <linux/elfcore.h>
+#include <asm/debugreg.h>
/*
* fill in the user structure for an a.out core dump
@@ -32,14 +33,7 @@ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
>> PAGE_SHIFT;
dump->u_dsize -= dump->u_tsize;
dump->u_ssize = 0;
- dump->u_debugreg[0] = current->thread.debugreg0;
- dump->u_debugreg[1] = current->thread.debugreg1;
- dump->u_debugreg[2] = current->thread.debugreg2;
- dump->u_debugreg[3] = current->thread.debugreg3;
- dump->u_debugreg[4] = 0;
- dump->u_debugreg[5] = 0;
- dump->u_debugreg[6] = current->thread.debugreg6;
- dump->u_debugreg[7] = current->thread.debugreg7;
+ aout_dump_debugregs(dump);
if (dump->start_stack < TASK_SIZE)
dump->u_ssize = ((unsigned long)(TASK_SIZE - dump->start_stack))
diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h
index e2077d343c33..b97f786a48d5 100644
--- a/arch/x86/include/asm/alternative-asm.h
+++ b/arch/x86/include/asm/alternative-asm.h
@@ -1,17 +1,13 @@
#ifdef __ASSEMBLY__
-#ifdef CONFIG_X86_32
-# define X86_ALIGN .long
-#else
-# define X86_ALIGN .quad
-#endif
+#include <asm/asm.h>
#ifdef CONFIG_SMP
.macro LOCK_PREFIX
1: lock
.section .smp_locks,"a"
- .align 4
- X86_ALIGN 1b
+ _ASM_ALIGN
+ _ASM_PTR 1b
.previous
.endm
#else
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index c240efc74e00..69b74a7b877f 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -84,6 +84,7 @@ static inline void alternatives_smp_switch(int smp) {}
" .byte " __stringify(feature) "\n" /* feature bit */ \
" .byte 662b-661b\n" /* sourcelen */ \
" .byte 664f-663f\n" /* replacementlen */ \
+ " .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */ \
".previous\n" \
".section .altinstr_replacement, \"ax\"\n" \
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h
index ac95995b7bad..5af2982133b5 100644
--- a/arch/x86/include/asm/amd_iommu.h
+++ b/arch/x86/include/asm/amd_iommu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
* Leo Duran <leo.duran@amd.com>
*
@@ -23,18 +23,13 @@
#include <linux/irqreturn.h>
#ifdef CONFIG_AMD_IOMMU
-extern int amd_iommu_init(void);
-extern int amd_iommu_init_dma_ops(void);
-extern int amd_iommu_init_passthrough(void);
+
extern void amd_iommu_detect(void);
-extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
-extern void amd_iommu_flush_all_domains(void);
-extern void amd_iommu_flush_all_devices(void);
-extern void amd_iommu_shutdown(void);
+
#else
-static inline int amd_iommu_init(void) { return -ENODEV; }
+
static inline void amd_iommu_detect(void) { }
-static inline void amd_iommu_shutdown(void) { }
+
#endif
#endif /* _ASM_X86_AMD_IOMMU_H */
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h
new file mode 100644
index 000000000000..84786fb9a23b
--- /dev/null
+++ b/arch/x86/include/asm/amd_iommu_proto.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 Advanced Micro Devices, Inc.
+ * Author: Joerg Roedel <joerg.roedel@amd.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.
+ *
+ * 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
+ */
+
+#ifndef _ASM_X86_AMD_IOMMU_PROTO_H
+#define _ASM_X86_AMD_IOMMU_PROTO_H
+
+struct amd_iommu;
+
+extern int amd_iommu_init_dma_ops(void);
+extern int amd_iommu_init_passthrough(void);
+extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
+extern void amd_iommu_flush_all_domains(void);
+extern void amd_iommu_flush_all_devices(void);
+extern void amd_iommu_apply_erratum_63(u16 devid);
+extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
+
+#ifndef CONFIG_AMD_IOMMU_STATS
+
+static inline void amd_iommu_stats_init(void) { }
+
+#endif /* !CONFIG_AMD_IOMMU_STATS */
+
+#endif /* _ASM_X86_AMD_IOMMU_PROTO_H */
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h
index 2a2cc7a78a81..ba19ad4c47d0 100644
--- a/arch/x86/include/asm/amd_iommu_types.h
+++ b/arch/x86/include/asm/amd_iommu_types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
* Leo Duran <leo.duran@amd.com>
*
@@ -25,6 +25,11 @@
#include <linux/spinlock.h>
/*
+ * Maximum number of IOMMUs supported
+ */
+#define MAX_IOMMUS 32
+
+/*
* some size calculation constants
*/
#define DEV_TABLE_ENTRY_SIZE 32
@@ -206,6 +211,9 @@ extern bool amd_iommu_dump;
printk(KERN_INFO "AMD-Vi: " format, ## arg); \
} while(0);
+/* global flag if IOMMUs cache non-present entries */
+extern bool amd_iommu_np_cache;
+
/*
* Make iterating over all IOMMUs easier
*/
@@ -226,6 +234,8 @@ extern bool amd_iommu_dump;
* independent of their use.
*/
struct protection_domain {
+ struct list_head list; /* for list of all protection domains */
+ struct list_head dev_list; /* List of all devices in this domain */
spinlock_t lock; /* mostly used to lock the page table*/
u16 id; /* the domain id written to the device table */
int mode; /* paging mode (0-6 levels) */
@@ -233,7 +243,20 @@ struct protection_domain {
unsigned long flags; /* flags to find out type of domain */
bool updated; /* complete domain flush required */
unsigned dev_cnt; /* devices assigned to this domain */
+ unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
void *priv; /* private data */
+
+};
+
+/*
+ * This struct contains device specific data for the IOMMU
+ */
+struct iommu_dev_data {
+ struct list_head list; /* For domain->dev_list */
+ struct device *dev; /* Device this data belong to */
+ struct device *alias; /* The Alias Device */
+ struct protection_domain *domain; /* Domain the device is bound to */
+ atomic_t bind; /* Domain attach reverent count */
};
/*
@@ -291,6 +314,9 @@ struct dma_ops_domain {
struct amd_iommu {
struct list_head list;
+ /* Index within the IOMMU array */
+ int index;
+
/* locks the accesses to the hardware */
spinlock_t lock;
@@ -357,6 +383,21 @@ struct amd_iommu {
extern struct list_head amd_iommu_list;
/*
+ * Array with pointers to each IOMMU struct
+ * The indices are referenced in the protection domains
+ */
+extern struct amd_iommu *amd_iommus[MAX_IOMMUS];
+
+/* Number of IOMMUs present in the system */
+extern int amd_iommus_present;
+
+/*
+ * Declarations for the global list of all protection domains
+ */
+extern spinlock_t amd_iommu_pd_lock;
+extern struct list_head amd_iommu_pd_list;
+
+/*
* Structure defining one entry in the device table
*/
struct dev_table_entry {
@@ -416,15 +457,9 @@ extern unsigned amd_iommu_aperture_order;
/* largest PCI device id we expect translation requests for */
extern u16 amd_iommu_last_bdf;
-/* data structures for protection domain handling */
-extern struct protection_domain **amd_iommu_pd_table;
-
/* allocation bitmap for domain ids */
extern unsigned long *amd_iommu_pd_alloc_bitmap;
-/* will be 1 if device isolation is enabled */
-extern bool amd_iommu_isolate;
-
/*
* If true, the addresses will be flushed on unmap time, not when
* they are reused
@@ -462,11 +497,6 @@ struct __iommu_counter {
#define ADD_STATS_COUNTER(name, x)
#define SUB_STATS_COUNTER(name, x)
-static inline void amd_iommu_stats_init(void) { }
-
#endif /* CONFIG_AMD_IOMMU_STATS */
-/* some function prototypes */
-extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
-
#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 474d80d3e6cc..b4ac2cdcb64f 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -297,20 +297,20 @@ struct apic {
int disable_esr;
int dest_logical;
- unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
+ unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid);
unsigned long (*check_apicid_present)(int apicid);
void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
void (*init_apic_ldr)(void);
- physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
+ void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
void (*setup_apic_routing)(void);
int (*multi_timer_check)(int apic, int irq);
int (*apicid_to_node)(int logical_apicid);
int (*cpu_to_logical_apicid)(int cpu);
int (*cpu_present_to_apicid)(int mps_cpu);
- physid_mask_t (*apicid_to_cpu_present)(int phys_apicid);
+ void (*apicid_to_cpu_present)(int phys_apicid, physid_mask_t *retmap);
void (*setup_portio_remap)(void);
int (*check_phys_apicid_present)(int phys_apicid);
void (*enable_apic_mode)(void);
@@ -488,6 +488,8 @@ static inline unsigned int read_apic_id(void)
extern void default_setup_apic_routing(void);
+extern struct apic apic_noop;
+
#ifdef CONFIG_X86_32
extern struct apic apic_default;
@@ -532,9 +534,9 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
return (unsigned int)(mask1 & mask2 & mask3);
}
-static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid)
+static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid)
{
- return physid_isset(apicid, bitmap);
+ return physid_isset(apicid, *map);
}
static inline unsigned long default_check_apicid_present(int bit)
@@ -542,9 +544,9 @@ static inline unsigned long default_check_apicid_present(int bit)
return physid_isset(bit, phys_cpu_present_map);
}
-static inline physid_mask_t default_ioapic_phys_id_map(physid_mask_t phys_map)
+static inline void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
{
- return phys_map;
+ *retmap = *phys_map;
}
/* Mapping from cpu number to logical apicid */
@@ -583,11 +585,6 @@ extern int default_cpu_present_to_apicid(int mps_cpu);
extern int default_check_phys_apicid_present(int phys_apicid);
#endif
-static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid)
-{
- return physid_mask_of_physid(phys_apicid);
-}
-
#endif /* CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_32
diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index 3b62da926de9..7fe3b3060f08 100644
--- a/arch/x86/include/asm/apicdef.h
+++ b/arch/x86/include/asm/apicdef.h
@@ -11,6 +11,12 @@
#define IO_APIC_DEFAULT_PHYS_BASE 0xfec00000
#define APIC_DEFAULT_PHYS_BASE 0xfee00000
+/*
+ * This is the IO-APIC register space as specified
+ * by Intel docs:
+ */
+#define IO_APIC_SLOT_SIZE 1024
+
#define APIC_ID 0x20
#define APIC_LVR 0x30
diff --git a/arch/x86/include/asm/apicnum.h b/arch/x86/include/asm/apicnum.h
deleted file mode 100644
index 82f613c607ce..000000000000
--- a/arch/x86/include/asm/apicnum.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASM_X86_APICNUM_H
-#define _ASM_X86_APICNUM_H
-
-/* define MAX_IO_APICS */
-#ifdef CONFIG_X86_32
-# define MAX_IO_APICS 64
-#else
-# define MAX_IO_APICS 128
-# define MAX_LOCAL_APIC 32768
-#endif
-
-#endif /* _ASM_X86_APICNUM_H */
diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index d9cf1cd156d2..f654d1bb17fb 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -22,14 +22,14 @@ do { \
".popsection" \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (sizeof(struct bug_entry))); \
- for (;;) ; \
+ unreachable(); \
} while (0)
#else
#define BUG() \
do { \
asm volatile("ud2"); \
- for (;;) ; \
+ unreachable(); \
} while (0)
#endif
diff --git a/arch/x86/include/asm/calgary.h b/arch/x86/include/asm/calgary.h
index b03bedb62aa7..0918654305af 100644
--- a/arch/x86/include/asm/calgary.h
+++ b/arch/x86/include/asm/calgary.h
@@ -62,10 +62,8 @@ struct cal_chipset_ops {
extern int use_calgary;
#ifdef CONFIG_CALGARY_IOMMU
-extern int calgary_iommu_init(void);
extern void detect_calgary(void);
#else
-static inline int calgary_iommu_init(void) { return 1; }
static inline void detect_calgary(void) { return; }
#endif
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index ee1931be6593..ffb9bb6b6c37 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -8,14 +8,50 @@
* you need to test for the feature in boot_cpu_data.
*/
-#define xchg(ptr, v) \
- ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), sizeof(*(ptr))))
+extern void __xchg_wrong_size(void);
+
+/*
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
+ * but generally the primitive is invalid, *ptr is output argument. --ANK
+ */
struct __xchg_dummy {
unsigned long a[100];
};
#define __xg(x) ((struct __xchg_dummy *)(x))
+#define __xchg(x, ptr, size) \
+({ \
+ __typeof(*(ptr)) __x = (x); \
+ switch (size) { \
+ case 1: \
+ asm volatile("xchgb %b0,%1" \
+ : "=q" (__x) \
+ : "m" (*__xg(ptr)), "0" (__x) \
+ : "memory"); \
+ break; \
+ case 2: \
+ asm volatile("xchgw %w0,%1" \
+ : "=r" (__x) \
+ : "m" (*__xg(ptr)), "0" (__x) \
+ : "memory"); \
+ break; \
+ case 4: \
+ asm volatile("xchgl %0,%1" \
+ : "=r" (__x) \
+ : "m" (*__xg(ptr)), "0" (__x) \
+ : "memory"); \
+ break; \
+ default: \
+ __xchg_wrong_size(); \
+ } \
+ __x; \
+})
+
+#define xchg(ptr, v) \
+ __xchg((v), (ptr), sizeof(*ptr))
+
/*
* The semantics of XCHGCMP8B are a bit strange, this is why
* there is a loop and the loading of %%eax and %%edx has to
@@ -71,57 +107,63 @@ static inline void __set_64bit_var(unsigned long long *ptr,
(unsigned int)((value) >> 32)) \
: __set_64bit(ptr, ll_low((value)), ll_high((value))))
-/*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- * Note 2: xchg has side effect, so that attribute volatile is necessary,
- * but generally the primitive is invalid, *ptr is output argument. --ANK
- */
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
- int size)
-{
- switch (size) {
- case 1:
- asm volatile("xchgb %b0,%1"
- : "=q" (x)
- : "m" (*__xg(ptr)), "0" (x)
- : "memory");
- break;
- case 2:
- asm volatile("xchgw %w0,%1"
- : "=r" (x)
- : "m" (*__xg(ptr)), "0" (x)
- : "memory");
- break;
- case 4:
- asm volatile("xchgl %0,%1"
- : "=r" (x)
- : "m" (*__xg(ptr)), "0" (x)
- : "memory");
- break;
- }
- return x;
-}
+extern void __cmpxchg_wrong_size(void);
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*/
+#define __raw_cmpxchg(ptr, old, new, size, lock) \
+({ \
+ __typeof__(*(ptr)) __ret; \
+ __typeof__(*(ptr)) __old = (old); \
+ __typeof__(*(ptr)) __new = (new); \
+ switch (size) { \
+ case 1: \
+ asm volatile(lock "cmpxchgb %b1,%2" \
+ : "=a"(__ret) \
+ : "q"(__new), "m"(*__xg(ptr)), "0"(__old) \
+ : "memory"); \
+ break; \
+ case 2: \
+ asm volatile(lock "cmpxchgw %w1,%2" \
+ : "=a"(__ret) \
+ : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
+ : "memory"); \
+ break; \
+ case 4: \
+ asm volatile(lock "cmpxchgl %1,%2" \
+ : "=a"(__ret) \
+ : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
+ : "memory"); \
+ break; \
+ default: \
+ __cmpxchg_wrong_size(); \
+ } \
+ __ret; \
+})
+
+#define __cmpxchg(ptr, old, new, size) \
+ __raw_cmpxchg((ptr), (old), (new), (size), LOCK_PREFIX)
+
+#define __sync_cmpxchg(ptr, old, new, size) \
+ __raw_cmpxchg((ptr), (old), (new), (size), "lock; ")
+
+#define __cmpxchg_local(ptr, old, new, size) \
+ __raw_cmpxchg((ptr), (old), (new), (size), "")
#ifdef CONFIG_X86_CMPXCHG
#define __HAVE_ARCH_CMPXCHG 1
-#define cmpxchg(ptr, o, n) \
- ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \
- (unsigned long)(n), \
- sizeof(*(ptr))))
-#define sync_cmpxchg(ptr, o, n) \
- ((__typeof__(*(ptr)))__sync_cmpxchg((ptr), (unsigned long)(o), \
- (unsigned long)(n), \
- sizeof(*(ptr))))
-#define cmpxchg_local(ptr, o, n) \
- ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
- (unsigned long)(n), \
- sizeof(*(ptr))))
+
+#define cmpxchg(ptr, old, new) \
+ __cmpxchg((ptr), (old), (new), sizeof(*ptr))
+
+#define sync_cmpxchg(ptr, old, new) \
+ __sync_cmpxchg((ptr), (old), (new), sizeof(*ptr))
+
+#define cmpxchg_local(ptr, old, new) \
+ __cmpxchg_local((ptr), (old), (new), sizeof(*ptr))
#endif
#ifdef CONFIG_X86_CMPXCHG64
@@ -133,94 +175,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
(unsigned long long)(n)))
#endif
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- asm volatile(LOCK_PREFIX "cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- asm volatile(LOCK_PREFIX "cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- asm volatile(LOCK_PREFIX "cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
-
-/*
- * Always use locked operations when touching memory shared with a
- * hypervisor, since the system may be SMP even if the guest kernel
- * isn't.
- */
-static inline unsigned long __sync_cmpxchg(volatile void *ptr,
- unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- asm volatile("lock; cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- asm volatile("lock; cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- asm volatile("lock; cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
-
-static inline unsigned long __cmpxchg_local(volatile void *ptr,
- unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- asm volatile("cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- asm volatile("cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- asm volatile("cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
-
static inline unsigned long long __cmpxchg64(volatile void *ptr,
unsigned long long old,
unsigned long long new)
diff --git a/arch/x86/include/asm/cmpxchg_64.h b/arch/x86/include/asm/cmpxchg_64.h
index 52de72e0de8c..485ae415faec 100644
--- a/arch/x86/include/asm/cmpxchg_64.h
+++ b/arch/x86/include/asm/cmpxchg_64.h
@@ -3,9 +3,6 @@
#include <asm/alternative.h> /* Provides LOCK_PREFIX */
-#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), \
- (ptr), sizeof(*(ptr))))
-
#define __xg(x) ((volatile long *)(x))
static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
@@ -15,167 +12,118 @@ static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
#define _set_64bit set_64bit
+extern void __xchg_wrong_size(void);
+extern void __cmpxchg_wrong_size(void);
+
/*
* Note: no "lock" prefix even on SMP: xchg always implies lock anyway
* Note 2: xchg has side effect, so that attribute volatile is necessary,
* but generally the primitive is invalid, *ptr is output argument. --ANK
*/
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
- int size)
-{
- switch (size) {
- case 1:
- asm volatile("xchgb %b0,%1"
- : "=q" (x)
- : "m" (*__xg(ptr)), "0" (x)
- : "memory");
- break;
- case 2:
- asm volatile("xchgw %w0,%1"
- : "=r" (x)
- : "m" (*__xg(ptr)), "0" (x)
- : "memory");
- break;
- case 4:
- asm volatile("xchgl %k0,%1"
- : "=r" (x)
- : "m" (*__xg(ptr)), "0" (x)
- : "memory");
- break;
- case 8:
- asm volatile("xchgq %0,%1"
- : "=r" (x)
- : "m" (*__xg(ptr)), "0" (x)
- : "memory");
- break;
- }
- return x;
-}
+#define __xchg(x, ptr, size) \
+({ \
+ __typeof(*(ptr)) __x = (x); \
+ switch (size) { \
+ case 1: \
+ asm volatile("xchgb %b0,%1" \
+ : "=q" (__x) \
+ : "m" (*__xg(ptr)), "0" (__x) \
+ : "memory"); \
+ break; \
+ case 2: \
+ asm volatile("xchgw %w0,%1" \
+ : "=r" (__x) \
+ : "m" (*__xg(ptr)), "0" (__x) \
+ : "memory"); \
+ break; \
+ case 4: \
+ asm volatile("xchgl %k0,%1" \
+ : "=r" (__x) \
+ : "m" (*__xg(ptr)), "0" (__x) \
+ : "memory"); \
+ break; \
+ case 8: \
+ asm volatile("xchgq %0,%1" \
+ : "=r" (__x) \
+ : "m" (*__xg(ptr)), "0" (__x) \
+ : "memory"); \
+ break; \
+ default: \
+ __xchg_wrong_size(); \
+ } \
+ __x; \
+})
+
+#define xchg(ptr, v) \
+ __xchg((v), (ptr), sizeof(*ptr))
+
+#define __HAVE_ARCH_CMPXCHG 1
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*/
+#define __raw_cmpxchg(ptr, old, new, size, lock) \
+({ \
+ __typeof__(*(ptr)) __ret; \
+ __typeof__(*(ptr)) __old = (old); \
+ __typeof__(*(ptr)) __new = (new); \
+ switch (size) { \
+ case 1: \
+ asm volatile(lock "cmpxchgb %b1,%2" \
+ : "=a"(__ret) \
+ : "q"(__new), "m"(*__xg(ptr)), "0"(__old) \
+ : "memory"); \
+ break; \
+ case 2: \
+ asm volatile(lock "cmpxchgw %w1,%2" \
+ : "=a"(__ret) \
+ : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
+ : "memory"); \
+ break; \
+ case 4: \
+ asm volatile(lock "cmpxchgl %k1,%2" \
+ : "=a"(__ret) \
+ : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
+ : "memory"); \
+ break; \
+ case 8: \
+ asm volatile(lock "cmpxchgq %1,%2" \
+ : "=a"(__ret) \
+ : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
+ : "memory"); \
+ break; \
+ default: \
+ __cmpxchg_wrong_size(); \
+ } \
+ __ret; \
+})
-#define __HAVE_ARCH_CMPXCHG 1
+#define __cmpxchg(ptr, old, new, size) \
+ __raw_cmpxchg((ptr), (old), (new), (size), LOCK_PREFIX)
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- asm volatile(LOCK_PREFIX "cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- asm volatile(LOCK_PREFIX "cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- asm volatile(LOCK_PREFIX "cmpxchgl %k1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 8:
- asm volatile(LOCK_PREFIX "cmpxchgq %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
+#define __sync_cmpxchg(ptr, old, new, size) \
+ __raw_cmpxchg((ptr), (old), (new), (size), "lock; ")
-/*
- * Always use locked operations when touching memory shared with a
- * hypervisor, since the system may be SMP even if the guest kernel
- * isn't.
- */
-static inline unsigned long __sync_cmpxchg(volatile void *ptr,
- unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- asm volatile("lock; cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- asm volatile("lock; cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- asm volatile("lock; cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
+#define __cmpxchg_local(ptr, old, new, size) \
+ __raw_cmpxchg((ptr), (old), (new), (size), "")
-static inline unsigned long __cmpxchg_local(volatile void *ptr,
- unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- asm volatile("cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- asm volatile("cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- asm volatile("cmpxchgl %k1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 8:
- asm volatile("cmpxchgq %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
+#define cmpxchg(ptr, old, new) \
+ __cmpxchg((ptr), (old), (new), sizeof(*ptr))
+
+#define sync_cmpxchg(ptr, old, new) \
+ __sync_cmpxchg((ptr), (old), (new), sizeof(*ptr))
+
+#define cmpxchg_local(ptr, old, new) \
+ __cmpxchg_local((ptr), (old), (new), sizeof(*ptr))
-#define cmpxchg(ptr, o, n) \
- ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \
- (unsigned long)(n), sizeof(*(ptr))))
#define cmpxchg64(ptr, o, n) \
({ \
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
cmpxchg((ptr), (o), (n)); \
})
-#define cmpxchg_local(ptr, o, n) \
- ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
- (unsigned long)(n), \
- sizeof(*(ptr))))
-#define sync_cmpxchg(ptr, o, n) \
- ((__typeof__(*(ptr)))__sync_cmpxchg((ptr), (unsigned long)(o), \
- (unsigned long)(n), \
- sizeof(*(ptr))))
+
#define cmpxchg64_local(ptr, o, n) \
({ \
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
diff --git a/arch/x86/include/asm/debugreg.h b/arch/x86/include/asm/debugreg.h
index 3ea6f37be9e2..8240f76b531e 100644
--- a/arch/x86/include/asm/debugreg.h
+++ b/arch/x86/include/asm/debugreg.h
@@ -18,6 +18,7 @@
#define DR_TRAP1 (0x2) /* db1 */
#define DR_TRAP2 (0x4) /* db2 */
#define DR_TRAP3 (0x8) /* db3 */
+#define DR_TRAP_BITS (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)
#define DR_STEP (0x4000) /* single-step */
#define DR_SWITCH (0x8000) /* task switch */
@@ -49,6 +50,8 @@
#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */
#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */
+#define DR_LOCAL_ENABLE (0x1) /* Local enable for reg 0 */
+#define DR_GLOBAL_ENABLE (0x2) /* Global enable for reg 0 */
#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */
#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */
@@ -67,4 +70,34 @@
#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */
#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */
+/*
+ * HW breakpoint additions
+ */
+#ifdef __KERNEL__
+
+DECLARE_PER_CPU(unsigned long, cpu_dr7);
+
+static inline void hw_breakpoint_disable(void)
+{
+ /* Zero the control register for HW Breakpoint */
+ set_debugreg(0UL, 7);
+
+ /* Zero-out the individual HW breakpoint address registers */
+ set_debugreg(0UL, 0);
+ set_debugreg(0UL, 1);
+ set_debugreg(0UL, 2);
+ set_debugreg(0UL, 3);
+}
+
+static inline int hw_breakpoint_active(void)
+{
+ return __get_cpu_var(cpu_dr7) & DR_GLOBAL_ENABLE_MASK;
+}
+
+extern void aout_dump_debugregs(struct user *dump);
+
+extern void hw_breakpoint_restore(void);
+
+#endif /* __KERNEL__ */
+
#endif /* _ASM_X86_DEBUGREG_H */
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index e8de2f6f5ca5..617bd56b3070 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -288,7 +288,7 @@ static inline void load_LDT(mm_context_t *pc)
static inline unsigned long get_desc_base(const struct desc_struct *desc)
{
- return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24);
+ return (unsigned)(desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24));
}
static inline void set_desc_base(struct desc_struct *desc, unsigned long base)
diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
index cee34e9ca45b..029f230ab637 100644
--- a/arch/x86/include/asm/device.h
+++ b/arch/x86/include/asm/device.h
@@ -8,7 +8,7 @@ struct dev_archdata {
#ifdef CONFIG_X86_64
struct dma_map_ops *dma_ops;
#endif
-#ifdef CONFIG_DMAR
+#if defined(CONFIG_DMAR) || defined(CONFIG_AMD_IOMMU)
void *iommu; /* hook for IOMMU specific extension */
#endif
};
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 0ee770d23d0e..0f6c02f3b7d4 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -14,7 +14,14 @@
#include <asm/swiotlb.h>
#include <asm-generic/dma-coherent.h>
-extern dma_addr_t bad_dma_address;
+#ifdef CONFIG_ISA
+# define ISA_DMA_BIT_MASK DMA_BIT_MASK(24)
+#else
+# define ISA_DMA_BIT_MASK DMA_BIT_MASK(32)
+#endif
+
+#define DMA_ERROR_CODE 0
+
extern int iommu_merge;
extern struct device x86_dma_fallback_dev;
extern int panic_on_overflow;
@@ -42,7 +49,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
if (ops->mapping_error)
return ops->mapping_error(dev, dma_addr);
- return (dma_addr == bad_dma_address);
+ return (dma_addr == DMA_ERROR_CODE);
}
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
@@ -124,10 +131,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
if (dma_alloc_from_coherent(dev, size, dma_handle, &memory))
return memory;
- if (!dev) {
+ if (!dev)
dev = &x86_dma_fallback_dev;
- gfp |= GFP_DMA;
- }
if (!is_device_dma_capable(dev))
return NULL;
diff --git a/arch/x86/include/asm/gart.h b/arch/x86/include/asm/gart.h
index 6cfdafa409d8..4ac5b0f33fc1 100644
--- a/arch/x86/include/asm/gart.h
+++ b/arch/x86/include/asm/gart.h
@@ -35,8 +35,7 @@ extern int gart_iommu_aperture_allowed;
extern int gart_iommu_aperture_disabled;
extern void early_gart_iommu_check(void);
-extern void gart_iommu_init(void);
-extern void gart_iommu_shutdown(void);
+extern int gart_iommu_init(void);
extern void __init gart_parse_options(char *);
extern void gart_iommu_hole_init(void);
@@ -48,12 +47,6 @@ extern void gart_iommu_hole_init(void);
static inline void early_gart_iommu_check(void)
{
}
-static inline void gart_iommu_init(void)
-{
-}
-static inline void gart_iommu_shutdown(void)
-{
-}
static inline void gart_parse_options(char *options)
{
}
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index 82e3e8f01043..108eb6fd1ae7 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -20,11 +20,11 @@ typedef struct {
unsigned int irq_call_count;
unsigned int irq_tlb_count;
#endif
-#ifdef CONFIG_X86_MCE
+#ifdef CONFIG_X86_THERMAL_VECTOR
unsigned int irq_thermal_count;
-# ifdef CONFIG_X86_MCE_THRESHOLD
+#endif
+#ifdef CONFIG_X86_MCE_THRESHOLD
unsigned int irq_threshold_count;
-# endif
#endif
} ____cacheline_aligned irq_cpustat_t;
diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h
new file mode 100644
index 000000000000..0675a7c4c20e
--- /dev/null
+++ b/arch/x86/include/asm/hw_breakpoint.h
@@ -0,0 +1,73 @@
+#ifndef _I386_HW_BREAKPOINT_H
+#define _I386_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#define __ARCH_HW_BREAKPOINT_H
+
+/*
+ * The name should probably be something dealt in
+ * a higher level. While dealing with the user
+ * (display/resolving)
+ */
+struct arch_hw_breakpoint {
+ char *name; /* Contains name of the symbol to set bkpt */
+ unsigned long address;
+ u8 len;
+ u8 type;
+};
+
+#include <linux/kdebug.h>
+#include <linux/percpu.h>
+#include <linux/list.h>
+
+/* Available HW breakpoint length encodings */
+#define X86_BREAKPOINT_LEN_1 0x40
+#define X86_BREAKPOINT_LEN_2 0x44
+#define X86_BREAKPOINT_LEN_4 0x4c
+#define X86_BREAKPOINT_LEN_EXECUTE 0x40
+
+#ifdef CONFIG_X86_64
+#define X86_BREAKPOINT_LEN_8 0x48
+#endif
+
+/* Available HW breakpoint type encodings */
+
+/* trigger on instruction execute */
+#define X86_BREAKPOINT_EXECUTE 0x80
+/* trigger on memory write */
+#define X86_BREAKPOINT_WRITE 0x81
+/* trigger on memory read or write */
+#define X86_BREAKPOINT_RW 0x83
+
+/* Total number of available HW breakpoint registers */
+#define HBP_NUM 4
+
+struct perf_event;
+struct pmu;
+
+extern int arch_check_va_in_userspace(unsigned long va, u8 hbp_len);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+ struct task_struct *tsk);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+ unsigned long val, void *data);
+
+
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+void hw_breakpoint_pmu_unthrottle(struct perf_event *bp);
+
+extern void
+arch_fill_perf_breakpoint(struct perf_event *bp);
+
+unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type);
+int decode_dr7(unsigned long dr7, int bpnum, unsigned *len, unsigned *type);
+
+extern int arch_bp_generic_fields(int x86_len, int x86_type,
+ int *gen_len, int *gen_type);
+
+extern struct pmu perf_ops_bp;
+
+#endif /* __KERNEL__ */
+#endif /* _I386_HW_BREAKPOINT_H */
+
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index ba180d93b08c..6e124269fd4b 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -79,14 +79,32 @@ static inline void set_io_apic_irq_attr(struct io_apic_irq_attr *irq_attr,
int ioapic, int ioapic_pin,
int trigger, int polarity)
{
- irq_attr->ioapic = ioapic;
- irq_attr->ioapic_pin = ioapic_pin;
- irq_attr->trigger = trigger;
- irq_attr->polarity = polarity;
+ irq_attr->ioapic = ioapic;
+ irq_attr->ioapic_pin = ioapic_pin;
+ irq_attr->trigger = trigger;
+ irq_attr->polarity = polarity;
}
-extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin,
- struct io_apic_irq_attr *irq_attr);
+/*
+ * This is performance-critical, we want to do it O(1)
+ *
+ * Most irqs are mapped 1:1 with pins.
+ */
+struct irq_cfg {
+ struct irq_pin_list *irq_2_pin;
+ cpumask_var_t domain;
+ cpumask_var_t old_domain;
+ u8 vector;
+ u8 move_in_progress : 1;
+};
+
+extern struct irq_cfg *irq_cfg(unsigned int);
+extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
+extern void send_cleanup_vector(struct irq_cfg *);
+
+struct irq_desc;
+extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *);
+extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr);
extern void setup_ioapic_dest(void);
extern void enable_IO_APIC(void);
diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
new file mode 100644
index 000000000000..205b063e3e32
--- /dev/null
+++ b/arch/x86/include/asm/inat.h
@@ -0,0 +1,220 @@
+#ifndef _ASM_X86_INAT_H
+#define _ASM_X86_INAT_H
+/*
+ * x86 instruction attributes
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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 <asm/inat_types.h>
+
+/*
+ * Internal bits. Don't use bitmasks directly, because these bits are
+ * unstable. You should use checking functions.
+ */
+
+#define INAT_OPCODE_TABLE_SIZE 256
+#define INAT_GROUP_TABLE_SIZE 8
+
+/* Legacy last prefixes */
+#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */
+#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */
+#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */
+/* Other Legacy prefixes */
+#define INAT_PFX_LOCK 4 /* 0xF0 */
+#define INAT_PFX_CS 5 /* 0x2E */
+#define INAT_PFX_DS 6 /* 0x3E */
+#define INAT_PFX_ES 7 /* 0x26 */
+#define INAT_PFX_FS 8 /* 0x64 */
+#define INAT_PFX_GS 9 /* 0x65 */
+#define INAT_PFX_SS 10 /* 0x36 */
+#define INAT_PFX_ADDRSZ 11 /* 0x67 */
+/* x86-64 REX prefix */
+#define INAT_PFX_REX 12 /* 0x4X */
+/* AVX VEX prefixes */
+#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
+#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
+
+#define INAT_LSTPFX_MAX 3
+#define INAT_LGCPFX_MAX 11
+
+/* Immediate size */
+#define INAT_IMM_BYTE 1
+#define INAT_IMM_WORD 2
+#define INAT_IMM_DWORD 3
+#define INAT_IMM_QWORD 4
+#define INAT_IMM_PTR 5
+#define INAT_IMM_VWORD32 6
+#define INAT_IMM_VWORD 7
+
+/* Legacy prefix */
+#define INAT_PFX_OFFS 0
+#define INAT_PFX_BITS 4
+#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)
+#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)
+/* Escape opcodes */
+#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS)
+#define INAT_ESC_BITS 2
+#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1)
+#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS)
+/* Group opcodes (1-16) */
+#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS)
+#define INAT_GRP_BITS 5
+#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1)
+#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS)
+/* Immediates */
+#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS)
+#define INAT_IMM_BITS 3
+#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
+/* Flags */
+#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS)
+#define INAT_MODRM (1 << (INAT_FLAG_OFFS))
+#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1))
+#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2))
+#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3))
+#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
+#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
+#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
+/* Attribute making macros for attribute tables */
+#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
+#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
+#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM)
+#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS)
+
+/* Attribute search APIs */
+extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
+extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
+ insn_byte_t last_pfx,
+ insn_attr_t esc_attr);
+extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
+ insn_byte_t last_pfx,
+ insn_attr_t esc_attr);
+extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
+ insn_byte_t vex_m,
+ insn_byte_t vex_pp);
+
+/* Attribute checking functions */
+static inline int inat_is_legacy_prefix(insn_attr_t attr)
+{
+ attr &= INAT_PFX_MASK;
+ return attr && attr <= INAT_LGCPFX_MAX;
+}
+
+static inline int inat_is_address_size_prefix(insn_attr_t attr)
+{
+ return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
+}
+
+static inline int inat_is_operand_size_prefix(insn_attr_t attr)
+{
+ return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
+}
+
+static inline int inat_is_rex_prefix(insn_attr_t attr)
+{
+ return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
+}
+
+static inline int inat_last_prefix_id(insn_attr_t attr)
+{
+ if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
+ return 0;
+ else
+ return attr & INAT_PFX_MASK;
+}
+
+static inline int inat_is_vex_prefix(insn_attr_t attr)
+{
+ attr &= INAT_PFX_MASK;
+ return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3;
+}
+
+static inline int inat_is_vex3_prefix(insn_attr_t attr)
+{
+ return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
+}
+
+static inline int inat_is_escape(insn_attr_t attr)
+{
+ return attr & INAT_ESC_MASK;
+}
+
+static inline int inat_escape_id(insn_attr_t attr)
+{
+ return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
+}
+
+static inline int inat_is_group(insn_attr_t attr)
+{
+ return attr & INAT_GRP_MASK;
+}
+
+static inline int inat_group_id(insn_attr_t attr)
+{
+ return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
+}
+
+static inline int inat_group_common_attribute(insn_attr_t attr)
+{
+ return attr & ~INAT_GRP_MASK;
+}
+
+static inline int inat_has_immediate(insn_attr_t attr)
+{
+ return attr & INAT_IMM_MASK;
+}
+
+static inline int inat_immediate_size(insn_attr_t attr)
+{
+ return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
+}
+
+static inline int inat_has_modrm(insn_attr_t attr)
+{
+ return attr & INAT_MODRM;
+}
+
+static inline int inat_is_force64(insn_attr_t attr)
+{
+ return attr & INAT_FORCE64;
+}
+
+static inline int inat_has_second_immediate(insn_attr_t attr)
+{
+ return attr & INAT_SCNDIMM;
+}
+
+static inline int inat_has_moffset(insn_attr_t attr)
+{
+ return attr & INAT_MOFFSET;
+}
+
+static inline int inat_has_variant(insn_attr_t attr)
+{
+ return attr & INAT_VARIANT;
+}
+
+static inline int inat_accept_vex(insn_attr_t attr)
+{
+ return attr & INAT_VEXOK;
+}
+
+static inline int inat_must_vex(insn_attr_t attr)
+{
+ return attr & INAT_VEXONLY;
+}
+#endif
diff --git a/arch/x86/include/asm/inat_types.h b/arch/x86/include/asm/inat_types.h
new file mode 100644
index 000000000000..cb3c20ce39cf
--- /dev/null
+++ b/arch/x86/include/asm/inat_types.h
@@ -0,0 +1,29 @@
+#ifndef _ASM_X86_INAT_TYPES_H
+#define _ASM_X86_INAT_TYPES_H
+/*
+ * x86 instruction attributes
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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.
+ *
+ */
+
+/* Instruction attributes */
+typedef unsigned int insn_attr_t;
+typedef unsigned char insn_byte_t;
+typedef signed int insn_value_t;
+
+#endif
diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
new file mode 100644
index 000000000000..96c2e0ad04ca
--- /dev/null
+++ b/arch/x86/include/asm/insn.h
@@ -0,0 +1,184 @@
+#ifndef _ASM_X86_INSN_H
+#define _ASM_X86_INSN_H
+/*
+ * x86 instruction analysis
+ *
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2009
+ */
+
+/* insn_attr_t is defined in inat.h */
+#include <asm/inat.h>
+
+struct insn_field {
+ union {
+ insn_value_t value;
+ insn_byte_t bytes[4];
+ };
+ /* !0 if we've run insn_get_xxx() for this field */
+ unsigned char got;
+ unsigned char nbytes;
+};
+
+struct insn {
+ struct insn_field prefixes; /*
+ * Prefixes
+ * prefixes.bytes[3]: last prefix
+ */
+ struct insn_field rex_prefix; /* REX prefix */
+ struct insn_field vex_prefix; /* VEX prefix */
+ struct insn_field opcode; /*
+ * opcode.bytes[0]: opcode1
+ * opcode.bytes[1]: opcode2
+ * opcode.bytes[2]: opcode3
+ */
+ struct insn_field modrm;
+ struct insn_field sib;
+ struct insn_field displacement;
+ union {
+ struct insn_field immediate;
+ struct insn_field moffset1; /* for 64bit MOV */
+ struct insn_field immediate1; /* for 64bit imm or off16/32 */
+ };
+ union {
+ struct insn_field moffset2; /* for 64bit MOV */
+ struct insn_field immediate2; /* for 64bit imm or seg16 */
+ };
+
+ insn_attr_t attr;
+ unsigned char opnd_bytes;
+ unsigned char addr_bytes;
+ unsigned char length;
+ unsigned char x86_64;
+
+ const insn_byte_t *kaddr; /* kernel address of insn to analyze */
+ const insn_byte_t *next_byte;
+};
+
+#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
+#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
+#define X86_MODRM_RM(modrm) ((modrm) & 0x07)
+
+#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6)
+#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3)
+#define X86_SIB_BASE(sib) ((sib) & 0x07)
+
+#define X86_REX_W(rex) ((rex) & 8)
+#define X86_REX_R(rex) ((rex) & 4)
+#define X86_REX_X(rex) ((rex) & 2)
+#define X86_REX_B(rex) ((rex) & 1)
+
+/* VEX bit flags */
+#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */
+#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */
+#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */
+#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
+#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
+/* VEX bit fields */
+#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
+#define X86_VEX2_M 1 /* VEX2.M always 1 */
+#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
+#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */
+#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */
+
+/* The last prefix is needed for two-byte and three-byte opcodes */
+static inline insn_byte_t insn_last_prefix(struct insn *insn)
+{
+ return insn->prefixes.bytes[3];
+}
+
+extern void insn_init(struct insn *insn, const void *kaddr, int x86_64);
+extern void insn_get_prefixes(struct insn *insn);
+extern void insn_get_opcode(struct insn *insn);
+extern void insn_get_modrm(struct insn *insn);
+extern void insn_get_sib(struct insn *insn);
+extern void insn_get_displacement(struct insn *insn);
+extern void insn_get_immediate(struct insn *insn);
+extern void insn_get_length(struct insn *insn);
+
+/* Attribute will be determined after getting ModRM (for opcode groups) */
+static inline void insn_get_attribute(struct insn *insn)
+{
+ insn_get_modrm(insn);
+}
+
+/* Instruction uses RIP-relative addressing */
+extern int insn_rip_relative(struct insn *insn);
+
+/* Init insn for kernel text */
+static inline void kernel_insn_init(struct insn *insn, const void *kaddr)
+{
+#ifdef CONFIG_X86_64
+ insn_init(insn, kaddr, 1);
+#else /* CONFIG_X86_32 */
+ insn_init(insn, kaddr, 0);
+#endif
+}
+
+static inline int insn_is_avx(struct insn *insn)
+{
+ if (!insn->prefixes.got)
+ insn_get_prefixes(insn);
+ return (insn->vex_prefix.value != 0);
+}
+
+static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
+{
+ if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
+ return X86_VEX2_M;
+ else
+ return X86_VEX3_M(insn->vex_prefix.bytes[1]);
+}
+
+static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
+{
+ if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
+ return X86_VEX_P(insn->vex_prefix.bytes[1]);
+ else
+ return X86_VEX_P(insn->vex_prefix.bytes[2]);
+}
+
+/* Offset of each field from kaddr */
+static inline int insn_offset_rex_prefix(struct insn *insn)
+{
+ return insn->prefixes.nbytes;
+}
+static inline int insn_offset_vex_prefix(struct insn *insn)
+{
+ return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes;
+}
+static inline int insn_offset_opcode(struct insn *insn)
+{
+ return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes;
+}
+static inline int insn_offset_modrm(struct insn *insn)
+{
+ return insn_offset_opcode(insn) + insn->opcode.nbytes;
+}
+static inline int insn_offset_sib(struct insn *insn)
+{
+ return insn_offset_modrm(insn) + insn->modrm.nbytes;
+}
+static inline int insn_offset_displacement(struct insn *insn)
+{
+ return insn_offset_sib(insn) + insn->sib.nbytes;
+}
+static inline int insn_offset_immediate(struct insn *insn)
+{
+ return insn_offset_displacement(insn) + insn->displacement.nbytes;
+}
+
+#endif /* _ASM_X86_INSN_H */
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index fd6d21bbee6c..345c99cef152 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -1,8 +1,6 @@
#ifndef _ASM_X86_IOMMU_H
#define _ASM_X86_IOMMU_H
-extern void pci_iommu_shutdown(void);
-extern void no_iommu_init(void);
extern struct dma_map_ops nommu_dma_ops;
extern int force_iommu, no_iommu;
extern int iommu_detected;
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index ddda6cbed6f4..ffd700ff5dcb 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -34,6 +34,7 @@ static inline int irq_canonicalize(int irq)
#ifdef CONFIG_HOTPLUG_CPU
#include <linux/cpumask.h>
extern void fixup_irqs(void);
+extern void irq_force_complete_move(int);
#endif
extern void (*generic_interrupt_extension)(void);
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index f1363b72364f..858baa061cfc 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -108,6 +108,8 @@ struct mce_log {
#define K8_MCE_THRESHOLD_BANK_5 (MCE_THRESHOLD_BASE + 5 * 9)
#define K8_MCE_THRESHOLD_DRAM_ECC (MCE_THRESHOLD_BANK_4 + 0)
+extern struct atomic_notifier_head x86_mce_decoder_chain;
+
#ifdef __KERNEL__
#include <linux/percpu.h>
@@ -118,9 +120,11 @@ extern int mce_disabled;
extern int mce_p5_enabled;
#ifdef CONFIG_X86_MCE
-void mcheck_init(struct cpuinfo_x86 *c);
+int mcheck_init(void);
+void mcheck_cpu_init(struct cpuinfo_x86 *c);
#else
-static inline void mcheck_init(struct cpuinfo_x86 *c) {}
+static inline int mcheck_init(void) { return 0; }
+static inline void mcheck_cpu_init(struct cpuinfo_x86 *c) {}
#endif
#ifdef CONFIG_X86_ANCIENT_MCE
@@ -214,5 +218,11 @@ void intel_init_thermal(struct cpuinfo_x86 *c);
void mce_log_therm_throt_event(__u64 status);
+#ifdef CONFIG_X86_THERMAL_VECTOR
+extern void mcheck_intel_therm_init(void);
+#else
+static inline void mcheck_intel_therm_init(void) { }
+#endif
+
#endif /* __KERNEL__ */
#endif /* _ASM_X86_MCE_H */
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 79c94500c0bb..61d90b1331c3 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -163,14 +163,16 @@ typedef struct physid_mask physid_mask_t;
#define physids_shift_left(d, s, n) \
bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS)
-#define physids_coerce(map) ((map).mask[0])
+static inline unsigned long physids_coerce(physid_mask_t *map)
+{
+ return map->mask[0];
+}
-#define physids_promote(physids) \
- ({ \
- physid_mask_t __physid_mask = PHYSID_MASK_NONE; \
- __physid_mask.mask[0] = physids; \
- __physid_mask; \
- })
+static inline void physids_promote(unsigned long physids, physid_mask_t *map)
+{
+ physids_clear(*map);
+ map->mask[0] = physids;
+}
/* Note: will create very large stack frames if physid_mask_t is big */
#define physid_mask_of_physid(physid) \
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 7e2b6ba962ff..5bef931f8b14 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -247,8 +247,8 @@ do { \
#ifdef CONFIG_SMP
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
-void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
-void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
@@ -264,12 +264,12 @@ static inline int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
wrmsr(msr_no, l, h);
return 0;
}
-static inline void rdmsr_on_cpus(const cpumask_t *m, u32 msr_no,
+static inline void rdmsr_on_cpus(const struct cpumask *m, u32 msr_no,
struct msr *msrs)
{
rdmsr_on_cpu(0, msr_no, &(msrs[0].l), &(msrs[0].h));
}
-static inline void wrmsr_on_cpus(const cpumask_t *m, u32 msr_no,
+static inline void wrmsr_on_cpus(const struct cpumask *m, u32 msr_no,
struct msr *msrs)
{
wrmsr_on_cpu(0, msr_no, msrs[0].l, msrs[0].h);
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 8aebcc41041d..efb38994859c 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -840,42 +840,22 @@ static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock)
static inline unsigned long __raw_local_save_flags(void)
{
- unsigned long f;
-
- asm volatile(paravirt_alt(PARAVIRT_CALL)
- : "=a"(f)
- : paravirt_type(pv_irq_ops.save_fl),
- paravirt_clobber(CLBR_EAX)
- : "memory", "cc");
- return f;
+ return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl);
}
static inline void raw_local_irq_restore(unsigned long f)
{
- asm volatile(paravirt_alt(PARAVIRT_CALL)
- : "=a"(f)
- : PV_FLAGS_ARG(f),
- paravirt_type(pv_irq_ops.restore_fl),
- paravirt_clobber(CLBR_EAX)
- : "memory", "cc");
+ PVOP_VCALLEE1(pv_irq_ops.restore_fl, f);
}
static inline void raw_local_irq_disable(void)
{
- asm volatile(paravirt_alt(PARAVIRT_CALL)
- :
- : paravirt_type(pv_irq_ops.irq_disable),
- paravirt_clobber(CLBR_EAX)
- : "memory", "eax", "cc");
+ PVOP_VCALLEE0(pv_irq_ops.irq_disable);
}
static inline void raw_local_irq_enable(void)
{
- asm volatile(paravirt_alt(PARAVIRT_CALL)
- :
- : paravirt_type(pv_irq_ops.irq_enable),
- paravirt_clobber(CLBR_EAX)
- : "memory", "eax", "cc");
+ PVOP_VCALLEE0(pv_irq_ops.irq_enable);
}
static inline unsigned long __raw_local_irq_save(void)
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index dd0f5b32489d..9357473c8da0 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -494,10 +494,11 @@ int paravirt_disable_iospace(void);
#define EXTRA_CLOBBERS
#define VEXTRA_CLOBBERS
#else /* CONFIG_X86_64 */
+/* [re]ax isn't an arg, but the return val */
#define PVOP_VCALL_ARGS \
unsigned long __edi = __edi, __esi = __esi, \
- __edx = __edx, __ecx = __ecx
-#define PVOP_CALL_ARGS PVOP_VCALL_ARGS, __eax
+ __edx = __edx, __ecx = __ecx, __eax = __eax
+#define PVOP_CALL_ARGS PVOP_VCALL_ARGS
#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x))
#define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x))
@@ -509,6 +510,7 @@ int paravirt_disable_iospace(void);
"=c" (__ecx)
#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax)
+/* void functions are still allowed [re]ax for scratch */
#define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
@@ -583,8 +585,8 @@ int paravirt_disable_iospace(void);
VEXTRA_CLOBBERS, \
pre, post, ##__VA_ARGS__)
-#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...) \
- ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \
+#define __PVOP_VCALLEESAVE(op, pre, post, ...) \
+ ____PVOP_VCALL(op.func, CLBR_RET_REG, \
PVOP_VCALLEE_CLOBBERS, , \
pre, post, ##__VA_ARGS__)
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index ad7ce3fd5065..8d9f8548a870 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -28,9 +28,20 @@
*/
#define ARCH_PERFMON_EVENT_MASK 0xffff
+/*
+ * filter mask to validate fixed counter events.
+ * the following filters disqualify for fixed counters:
+ * - inv
+ * - edge
+ * - cnt-mask
+ * The other filters are supported by fixed counters.
+ * The any-thread option is supported starting with v3.
+ */
+#define ARCH_PERFMON_EVENT_FILTER_MASK 0xff840000
+
#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c
#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX 0
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX 0
#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
(1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c3429e8b2424..6f8ec1c37e0a 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -30,6 +30,7 @@ struct mm_struct;
#include <linux/math64.h>
#include <linux/init.h>
+#define HBP_NUM 4
/*
* Default implementation of macro that returns current
* instruction pointer ("program counter").
@@ -422,6 +423,8 @@ extern unsigned int xstate_size;
extern void free_thread_xstate(struct task_struct *);
extern struct kmem_cache *task_xstate_cachep;
+struct perf_event;
+
struct thread_struct {
/* Cached TLS descriptors: */
struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
@@ -443,13 +446,10 @@ struct thread_struct {
unsigned long fs;
#endif
unsigned long gs;
- /* Hardware debugging registers: */
- unsigned long debugreg0;
- unsigned long debugreg1;
- unsigned long debugreg2;
- unsigned long debugreg3;
- unsigned long debugreg6;
- unsigned long debugreg7;
+ /* Save middle states of ptrace breakpoints */
+ struct perf_event *ptrace_bps[HBP_NUM];
+ /* Debug status used for traps, single steps, etc... */
+ unsigned long debugreg6;
/* Fault info: */
unsigned long cr2;
unsigned long trap_no;
@@ -1000,7 +1000,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8))
#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)
-#define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */
+extern unsigned long KSTK_ESP(struct task_struct *task);
#endif /* CONFIG_X86_64 */
extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index 0f0d908349aa..3d11fd0f44c5 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -7,6 +7,7 @@
#ifdef __KERNEL__
#include <asm/segment.h>
+#include <asm/page_types.h>
#endif
#ifndef __ASSEMBLY__
@@ -216,6 +217,67 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
return regs->sp;
}
+/* Query offset/name of register from its name/offset */
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+#define MAX_REG_OFFSET (offsetof(struct pt_regs, ss))
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs: pt_regs from which register value is gotten.
+ * @offset: offset number of the register.
+ *
+ * regs_get_register returns the value of a register. The @offset is the
+ * offset of the register in struct pt_regs address which specified by @regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+ unsigned int offset)
+{
+ if (unlikely(offset > MAX_REG_OFFSET))
+ return 0;
+ return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @addr: address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+static inline int regs_within_kernel_stack(struct pt_regs *regs,
+ unsigned long addr)
+{
+ return ((addr & ~(THREAD_SIZE - 1)) ==
+ (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @n: stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+ unsigned int n)
+{
+ unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+ addr += n;
+ if (regs_within_kernel_stack(regs, (unsigned long)addr))
+ return *addr;
+ else
+ return 0;
+}
+
+/* Get Nth argument at function call */
+extern unsigned long regs_get_argument_nth(struct pt_regs *regs,
+ unsigned int n);
+
/*
* These are defined as per linux/ptrace.h, which see.
*/
diff --git a/arch/x86/include/asm/string_32.h b/arch/x86/include/asm/string_32.h
index ae907e617181..3d3e8353ee5c 100644
--- a/arch/x86/include/asm/string_32.h
+++ b/arch/x86/include/asm/string_32.h
@@ -177,10 +177,15 @@ static inline void *__memcpy3d(void *to, const void *from, size_t len)
*/
#ifndef CONFIG_KMEMCHECK
+
+#if (__GNUC__ >= 4)
+#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
+#else
#define memcpy(t, f, n) \
(__builtin_constant_p((n)) \
? __constant_memcpy((t), (f), (n)) \
: __memcpy((t), (f), (n)))
+#endif
#else
/*
* kmemcheck becomes very happy if we use the REP instructions unconditionally,
@@ -316,11 +321,15 @@ void *__constant_c_and_count_memset(void *s, unsigned long pattern,
: __memset_generic((s), (c), (count)))
#define __HAVE_ARCH_MEMSET
+#if (__GNUC__ >= 4)
+#define memset(s, c, count) __builtin_memset(s, c, count)
+#else
#define memset(s, c, count) \
(__builtin_constant_p(c) \
? __constant_c_x_memset((s), (0x01010101UL * (unsigned char)(c)), \
(count)) \
: __memset((s), (c), (count)))
+#endif
/*
* find the first occurrence of byte 'c', or 1 past the area if none
diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h
index b9e4e20174fb..87ffcb12a1b8 100644
--- a/arch/x86/include/asm/swiotlb.h
+++ b/arch/x86/include/asm/swiotlb.h
@@ -3,17 +3,14 @@
#include <linux/swiotlb.h>
-/* SWIOTLB interface */
-
-extern int swiotlb_force;
-
#ifdef CONFIG_SWIOTLB
extern int swiotlb;
-extern void pci_swiotlb_init(void);
+extern int pci_swiotlb_init(void);
#else
#define swiotlb 0
-static inline void pci_swiotlb_init(void)
+static inline int pci_swiotlb_init(void)
{
+ return 0;
}
#endif
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index f08f97374892..022a84386de8 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -128,8 +128,6 @@ do { \
"movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \
"movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \
"call __switch_to\n\t" \
- ".globl thread_return\n" \
- "thread_return:\n\t" \
"movq "__percpu_arg([current_task])",%%rsi\n\t" \
__switch_canary \
"movq %P[thread_info](%%rsi),%%r8\n\t" \
@@ -157,19 +155,22 @@ extern void native_load_gs_index(unsigned);
* Load a segment. Fall back on loading the zero
* segment if something goes wrong..
*/
-#define loadsegment(seg, value) \
- asm volatile("\n" \
- "1:\t" \
- "movl %k0,%%" #seg "\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3:\t" \
- "movl %k1, %%" #seg "\n\t" \
- "jmp 2b\n" \
- ".previous\n" \
- _ASM_EXTABLE(1b,3b) \
- : :"r" (value), "r" (0) : "memory")
-
+#define loadsegment(seg, value) \
+do { \
+ unsigned short __val = (value); \
+ \
+ asm volatile(" \n" \
+ "1: movl %k0,%%" #seg " \n" \
+ \
+ ".section .fixup,\"ax\" \n" \
+ "2: xorl %k0,%k0 \n" \
+ " jmp 1b \n" \
+ ".previous \n" \
+ \
+ _ASM_EXTABLE(1b, 2b) \
+ \
+ : "+r" (__val) : : "memory"); \
+} while (0)
/*
* Save a segment register away
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 25a92842dd99..40e37b10c6c0 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -143,6 +143,7 @@ extern unsigned long node_remap_size[];
| 1*SD_BALANCE_FORK \
| 0*SD_BALANCE_WAKE \
| 1*SD_WAKE_AFFINE \
+ | 0*SD_PREFER_LOCAL \
| 0*SD_SHARE_CPUPOWER \
| 0*SD_POWERSAVINGS_BALANCE \
| 0*SD_SHARE_PKG_RESOURCES \
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index d2c6c930b491..abd3e0ea762a 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -570,7 +570,6 @@ extern struct movsl_mask {
#ifdef CONFIG_X86_32
# include "uaccess_32.h"
#else
-# define ARCH_HAS_SEARCH_EXTABLE
# include "uaccess_64.h"
#endif
diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
index 632fb44b4cb5..0c9825e97f36 100644
--- a/arch/x86/include/asm/uaccess_32.h
+++ b/arch/x86/include/asm/uaccess_32.h
@@ -187,9 +187,34 @@ __copy_from_user_inatomic_nocache(void *to, const void __user *from,
unsigned long __must_check copy_to_user(void __user *to,
const void *from, unsigned long n);
-unsigned long __must_check copy_from_user(void *to,
+unsigned long __must_check _copy_from_user(void *to,
const void __user *from,
unsigned long n);
+
+
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+ __compiletime_error("copy_from_user() buffer size is not provably correct")
+#else
+ __compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
+static inline unsigned long __must_check copy_from_user(void *to,
+ const void __user *from,
+ unsigned long n)
+{
+ int sz = __compiletime_object_size(to);
+ int ret = -EFAULT;
+
+ if (likely(sz == -1 || sz >= n))
+ ret = _copy_from_user(to, from, n);
+ else
+ copy_from_user_overflow();
+
+ return ret;
+}
+
long __must_check strncpy_from_user(char *dst, const char __user *src,
long count);
long __must_check __strncpy_from_user(char *dst,
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
index db24b215fc50..46324c6a4f6e 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -19,12 +19,37 @@ __must_check unsigned long
copy_user_generic(void *to, const void *from, unsigned len);
__must_check unsigned long
-copy_to_user(void __user *to, const void *from, unsigned len);
+_copy_to_user(void __user *to, const void *from, unsigned len);
__must_check unsigned long
-copy_from_user(void *to, const void __user *from, unsigned len);
+_copy_from_user(void *to, const void __user *from, unsigned len);
__must_check unsigned long
copy_in_user(void __user *to, const void __user *from, unsigned len);
+static inline unsigned long __must_check copy_from_user(void *to,
+ const void __user *from,
+ unsigned long n)
+{
+ int sz = __compiletime_object_size(to);
+ int ret = -EFAULT;
+
+ might_fault();
+ if (likely(sz == -1 || sz >= n))
+ ret = _copy_from_user(to, from, n);
+#ifdef CONFIG_DEBUG_VM
+ else
+ WARN(1, "Buffer overflow detected!\n");
+#endif
+ return ret;
+}
+
+static __always_inline __must_check
+int copy_to_user(void __user *dst, const void *src, unsigned size)
+{
+ might_fault();
+
+ return _copy_to_user(dst, src, size);
+}
+
static __always_inline __must_check
int __copy_from_user(void *dst, const void __user *src, unsigned size)
{
@@ -176,8 +201,11 @@ __must_check long strlen_user(const char __user *str);
__must_check unsigned long clear_user(void __user *mem, unsigned long len);
__must_check unsigned long __clear_user(void __user *mem, unsigned long len);
-__must_check long __copy_from_user_inatomic(void *dst, const void __user *src,
- unsigned size);
+static __must_check __always_inline int
+__copy_from_user_inatomic(void *dst, const void __user *src, unsigned size)
+{
+ return copy_user_generic(dst, (__force const void *)src, size);
+}
static __must_check __always_inline int
__copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index 04eb6c958b9d..d1414af98559 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -19,6 +19,8 @@
#include <asm/types.h>
#include <asm/percpu.h>
#include <asm/uv/uv_mmrs.h>
+#include <asm/irq_vectors.h>
+#include <asm/io_apic.h>
/*
@@ -114,7 +116,7 @@
/*
* The largest possible NASID of a C or M brick (+ 2)
*/
-#define UV_MAX_NASID_VALUE (UV_MAX_NUMALINK_NODES * 2)
+#define UV_MAX_NASID_VALUE (UV_MAX_NUMALINK_BLADES * 2)
struct uv_scir_s {
struct timer_list timer;
@@ -230,6 +232,20 @@ static inline unsigned long uv_gpa(void *v)
return uv_soc_phys_ram_to_gpa(__pa(v));
}
+/* gnode -> pnode */
+static inline unsigned long uv_gpa_to_gnode(unsigned long gpa)
+{
+ return gpa >> uv_hub_info->m_val;
+}
+
+/* gpa -> pnode */
+static inline int uv_gpa_to_pnode(unsigned long gpa)
+{
+ unsigned long n_mask = (1UL << uv_hub_info->n_val) - 1;
+
+ return uv_gpa_to_gnode(gpa) & n_mask;
+}
+
/* pnode, offset --> socket virtual */
static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
{
@@ -421,9 +437,14 @@ static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
{
unsigned long val;
+ unsigned long dmode = dest_Fixed;
+
+ if (vector == NMI_VECTOR)
+ dmode = dest_NMI;
val = (1UL << UVH_IPI_INT_SEND_SHFT) |
((apicid) << UVH_IPI_INT_APIC_ID_SHFT) |
+ (dmode << UVH_IPI_INT_DELIVERY_MODE_SHFT) |
(vector << UVH_IPI_INT_VECTOR_SHFT);
uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
}
diff --git a/arch/x86/include/asm/uv/uv_irq.h b/arch/x86/include/asm/uv/uv_irq.h
index 9613c8c0b647..d6b17c760622 100644
--- a/arch/x86/include/asm/uv/uv_irq.h
+++ b/arch/x86/include/asm/uv/uv_irq.h
@@ -25,12 +25,14 @@ struct uv_IO_APIC_route_entry {
dest : 32;
};
-extern struct irq_chip uv_irq_chip;
-
-extern int arch_enable_uv_irq(char *, unsigned int, int, int, unsigned long);
-extern void arch_disable_uv_irq(int, unsigned long);
+enum {
+ UV_AFFINITY_ALL,
+ UV_AFFINITY_NODE,
+ UV_AFFINITY_CPU
+};
-extern int uv_setup_irq(char *, int, int, unsigned long);
-extern void uv_teardown_irq(unsigned int, int, unsigned long);
+extern int uv_irq_2_mmr_info(int, unsigned long *, int *);
+extern int uv_setup_irq(char *, int, int, unsigned long, int);
+extern void uv_teardown_irq(unsigned int);
#endif /* _ASM_X86_UV_UV_IRQ_H */
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 2c756fd4ab0e..d8e71459f025 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -91,6 +91,14 @@ struct x86_init_timers {
};
/**
+ * struct x86_init_iommu - platform specific iommu setup
+ * @iommu_init: platform specific iommu setup
+ */
+struct x86_init_iommu {
+ int (*iommu_init)(void);
+};
+
+/**
* struct x86_init_ops - functions for platform specific setup
*
*/
@@ -101,6 +109,7 @@ struct x86_init_ops {
struct x86_init_oem oem;
struct x86_init_paging paging;
struct x86_init_timers timers;
+ struct x86_init_iommu iommu;
};
/**
@@ -121,6 +130,7 @@ struct x86_platform_ops {
unsigned long (*calibrate_tsc)(void);
unsigned long (*get_wallclock)(void);
int (*set_wallclock)(unsigned long nowtime);
+ void (*iommu_shutdown)(void);
};
extern struct x86_init_ops x86_init;
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index d8e5d0cdd678..4f2e66e29ecc 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -40,7 +40,7 @@ obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o
obj-y += bootflag.o e820.o
obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
-obj-y += alternative.o i8253.o pci-nommu.o
+obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
obj-y += tsc.o io_delay.o rtc.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c
index d296f4a195c9..d85d1b2432ba 100644
--- a/arch/x86/kernel/acpi/processor.c
+++ b/arch/x86/kernel/acpi/processor.c
@@ -79,7 +79,8 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
struct cpuinfo_x86 *c = &cpu_data(pr->id);
pr->pdc = NULL;
- if (c->x86_vendor == X86_VENDOR_INTEL)
+ if (c->x86_vendor == X86_VENDOR_INTEL ||
+ c->x86_vendor == X86_VENDOR_CENTAUR)
init_intel_pdc(pr, c);
return;
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S
index 7da00b799cda..060fff8f5c5b 100644
--- a/arch/x86/kernel/acpi/realmode/wakeup.lds.S
+++ b/arch/x86/kernel/acpi/realmode/wakeup.lds.S
@@ -57,5 +57,8 @@ SECTIONS
*(.note*)
}
+ /*
+ * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
+ */
. = ASSERT(_end <= WAKEUP_SIZE, "Wakeup too big!");
}
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 98f230f6a28d..32fb09102a13 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
* Leo Duran <leo.duran@amd.com>
*
@@ -28,6 +28,7 @@
#include <asm/proto.h>
#include <asm/iommu.h>
#include <asm/gart.h>
+#include <asm/amd_iommu_proto.h>
#include <asm/amd_iommu_types.h>
#include <asm/amd_iommu.h>
@@ -56,20 +57,115 @@ struct iommu_cmd {
u32 data[4];
};
-static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
- struct unity_map_entry *e);
-static struct dma_ops_domain *find_protection_domain(u16 devid);
-static u64 *alloc_pte(struct protection_domain *domain,
- unsigned long address, int end_lvl,
- u64 **pte_page, gfp_t gfp);
-static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
- unsigned long start_page,
- unsigned int pages);
static void reset_iommu_command_buffer(struct amd_iommu *iommu);
-static u64 *fetch_pte(struct protection_domain *domain,
- unsigned long address, int map_size);
static void update_domain(struct protection_domain *domain);
+/****************************************************************************
+ *
+ * Helper functions
+ *
+ ****************************************************************************/
+
+static inline u16 get_device_id(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ return calc_devid(pdev->bus->number, pdev->devfn);
+}
+
+static struct iommu_dev_data *get_dev_data(struct device *dev)
+{
+ return dev->archdata.iommu;
+}
+
+/*
+ * In this function the list of preallocated protection domains is traversed to
+ * find the domain for a specific device
+ */
+static struct dma_ops_domain *find_protection_domain(u16 devid)
+{
+ struct dma_ops_domain *entry, *ret = NULL;
+ unsigned long flags;
+ u16 alias = amd_iommu_alias_table[devid];
+
+ if (list_empty(&iommu_pd_list))
+ return NULL;
+
+ spin_lock_irqsave(&iommu_pd_list_lock, flags);
+
+ list_for_each_entry(entry, &iommu_pd_list, list) {
+ if (entry->target_dev == devid ||
+ entry->target_dev == alias) {
+ ret = entry;
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
+
+ return ret;
+}
+
+/*
+ * This function checks if the driver got a valid device from the caller to
+ * avoid dereferencing invalid pointers.
+ */
+static bool check_device(struct device *dev)
+{
+ u16 devid;
+
+ if (!dev || !dev->dma_mask)
+ return false;
+
+ /* No device or no PCI device */
+ if (!dev || dev->bus != &pci_bus_type)
+ return false;
+
+ devid = get_device_id(dev);
+
+ /* Out of our scope? */
+ if (devid > amd_iommu_last_bdf)
+ return false;
+
+ if (amd_iommu_rlookup_table[devid] == NULL)
+ return false;
+
+ return true;
+}
+
+static int iommu_init_device(struct device *dev)
+{
+ struct iommu_dev_data *dev_data;
+ struct pci_dev *pdev;
+ u16 devid, alias;
+
+ if (dev->archdata.iommu)
+ return 0;
+
+ dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
+ if (!dev_data)
+ return -ENOMEM;
+
+ dev_data->dev = dev;
+
+ devid = get_device_id(dev);
+ alias = amd_iommu_alias_table[devid];
+ pdev = pci_get_bus_and_slot(PCI_BUS(alias), alias & 0xff);
+ if (pdev)
+ dev_data->alias = &pdev->dev;
+
+ atomic_set(&dev_data->bind, 0);
+
+ dev->archdata.iommu = dev_data;
+
+
+ return 0;
+}
+
+static void iommu_uninit_device(struct device *dev)
+{
+ kfree(dev->archdata.iommu);
+}
#ifdef CONFIG_AMD_IOMMU_STATS
/*
@@ -90,7 +186,6 @@ DECLARE_STATS_COUNTER(alloced_io_mem);
DECLARE_STATS_COUNTER(total_map_requests);
static struct dentry *stats_dir;
-static struct dentry *de_isolate;
static struct dentry *de_fflush;
static void amd_iommu_stats_add(struct __iommu_counter *cnt)
@@ -108,9 +203,6 @@ static void amd_iommu_stats_init(void)
if (stats_dir == NULL)
return;
- de_isolate = debugfs_create_bool("isolation", 0444, stats_dir,
- (u32 *)&amd_iommu_isolate);
-
de_fflush = debugfs_create_bool("fullflush", 0444, stats_dir,
(u32 *)&amd_iommu_unmap_flush);
@@ -130,12 +222,6 @@ static void amd_iommu_stats_init(void)
#endif
-/* returns !0 if the IOMMU is caching non-present entries in its TLB */
-static int iommu_has_npcache(struct amd_iommu *iommu)
-{
- return iommu->cap & (1UL << IOMMU_CAP_NPCACHE);
-}
-
/****************************************************************************
*
* Interrupt handling functions
@@ -199,6 +285,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
break;
case EVENT_TYPE_ILL_CMD:
printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
+ iommu->reset_in_progress = true;
reset_iommu_command_buffer(iommu);
dump_command(address);
break;
@@ -321,11 +408,8 @@ static void __iommu_wait_for_completion(struct amd_iommu *iommu)
status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
- if (unlikely(i == EXIT_LOOP_COUNT)) {
- spin_unlock(&iommu->lock);
- reset_iommu_command_buffer(iommu);
- spin_lock(&iommu->lock);
- }
+ if (unlikely(i == EXIT_LOOP_COUNT))
+ iommu->reset_in_progress = true;
}
/*
@@ -372,26 +456,46 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
out:
spin_unlock_irqrestore(&iommu->lock, flags);
+ if (iommu->reset_in_progress)
+ reset_iommu_command_buffer(iommu);
+
return 0;
}
+static void iommu_flush_complete(struct protection_domain *domain)
+{
+ int i;
+
+ for (i = 0; i < amd_iommus_present; ++i) {
+ if (!domain->dev_iommu[i])
+ continue;
+
+ /*
+ * Devices of this domain are behind this IOMMU
+ * We need to wait for completion of all commands.
+ */
+ iommu_completion_wait(amd_iommus[i]);
+ }
+}
+
/*
* Command send function for invalidating a device table entry
*/
-static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
+static int iommu_flush_device(struct device *dev)
{
+ struct amd_iommu *iommu;
struct iommu_cmd cmd;
- int ret;
+ u16 devid;
- BUG_ON(iommu == NULL);
+ devid = get_device_id(dev);
+ iommu = amd_iommu_rlookup_table[devid];
+ /* Build command */
memset(&cmd, 0, sizeof(cmd));
CMD_SET_TYPE(&cmd, CMD_INV_DEV_ENTRY);
cmd.data[0] = devid;
- ret = iommu_queue_command(iommu, &cmd);
-
- return ret;
+ return iommu_queue_command(iommu, &cmd);
}
static void __iommu_build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address,
@@ -430,11 +534,11 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
* It invalidates a single PTE if the range to flush is within a single
* page. Otherwise it flushes the whole TLB of the IOMMU.
*/
-static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
- u64 address, size_t size)
+static void __iommu_flush_pages(struct protection_domain *domain,
+ u64 address, size_t size, int pde)
{
- int s = 0;
- unsigned pages = iommu_num_pages(address, size, PAGE_SIZE);
+ int s = 0, i;
+ unsigned long pages = iommu_num_pages(address, size, PAGE_SIZE);
address &= PAGE_MASK;
@@ -447,142 +551,212 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
s = 1;
}
- iommu_queue_inv_iommu_pages(iommu, address, domid, 0, s);
- return 0;
+ for (i = 0; i < amd_iommus_present; ++i) {
+ if (!domain->dev_iommu[i])
+ continue;
+
+ /*
+ * Devices of this domain are behind this IOMMU
+ * We need a TLB flush
+ */
+ iommu_queue_inv_iommu_pages(amd_iommus[i], address,
+ domain->id, pde, s);
+ }
+
+ return;
}
-/* Flush the whole IO/TLB for a given protection domain */
-static void iommu_flush_tlb(struct amd_iommu *iommu, u16 domid)
+static void iommu_flush_pages(struct protection_domain *domain,
+ u64 address, size_t size)
{
- u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
-
- INC_STATS_COUNTER(domain_flush_single);
+ __iommu_flush_pages(domain, address, size, 0);
+}
- iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1);
+/* Flush the whole IO/TLB for a given protection domain */
+static void iommu_flush_tlb(struct protection_domain *domain)
+{
+ __iommu_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 0);
}
/* Flush the whole IO/TLB for a given protection domain - including PDE */
-static void iommu_flush_tlb_pde(struct amd_iommu *iommu, u16 domid)
+static void iommu_flush_tlb_pde(struct protection_domain *domain)
{
- u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
-
- INC_STATS_COUNTER(domain_flush_single);
-
- iommu_queue_inv_iommu_pages(iommu, address, domid, 1, 1);
+ __iommu_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1);
}
+
/*
- * This function flushes one domain on one IOMMU
+ * This function flushes the DTEs for all devices in domain
*/
-static void flush_domain_on_iommu(struct amd_iommu *iommu, u16 domid)
+static void iommu_flush_domain_devices(struct protection_domain *domain)
{
- struct iommu_cmd cmd;
+ struct iommu_dev_data *dev_data;
unsigned long flags;
- __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
- domid, 1, 1);
+ spin_lock_irqsave(&domain->lock, flags);
- spin_lock_irqsave(&iommu->lock, flags);
- __iommu_queue_command(iommu, &cmd);
- __iommu_completion_wait(iommu);
- __iommu_wait_for_completion(iommu);
- spin_unlock_irqrestore(&iommu->lock, flags);
+ list_for_each_entry(dev_data, &domain->dev_list, list)
+ iommu_flush_device(dev_data->dev);
+
+ spin_unlock_irqrestore(&domain->lock, flags);
}
-static void flush_all_domains_on_iommu(struct amd_iommu *iommu)
+static void iommu_flush_all_domain_devices(void)
{
- int i;
+ struct protection_domain *domain;
+ unsigned long flags;
- for (i = 1; i < MAX_DOMAIN_ID; ++i) {
- if (!test_bit(i, amd_iommu_pd_alloc_bitmap))
- continue;
- flush_domain_on_iommu(iommu, i);
+ spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+
+ list_for_each_entry(domain, &amd_iommu_pd_list, list) {
+ iommu_flush_domain_devices(domain);
+ iommu_flush_complete(domain);
}
+ spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+}
+
+void amd_iommu_flush_all_devices(void)
+{
+ iommu_flush_all_domain_devices();
}
/*
- * This function is used to flush the IO/TLB for a given protection domain
- * on every IOMMU in the system
+ * This function uses heavy locking and may disable irqs for some time. But
+ * this is no issue because it is only called during resume.
*/
-static void iommu_flush_domain(u16 domid)
+void amd_iommu_flush_all_domains(void)
{
- struct amd_iommu *iommu;
+ struct protection_domain *domain;
+ unsigned long flags;
- INC_STATS_COUNTER(domain_flush_all);
+ spin_lock_irqsave(&amd_iommu_pd_lock, flags);
- for_each_iommu(iommu)
- flush_domain_on_iommu(iommu, domid);
+ list_for_each_entry(domain, &amd_iommu_pd_list, list) {
+ spin_lock(&domain->lock);
+ iommu_flush_tlb_pde(domain);
+ iommu_flush_complete(domain);
+ spin_unlock(&domain->lock);
+ }
+
+ spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
}
-void amd_iommu_flush_all_domains(void)
+static void reset_iommu_command_buffer(struct amd_iommu *iommu)
{
- struct amd_iommu *iommu;
+ pr_err("AMD-Vi: Resetting IOMMU command buffer\n");
- for_each_iommu(iommu)
- flush_all_domains_on_iommu(iommu);
+ if (iommu->reset_in_progress)
+ panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n");
+
+ amd_iommu_reset_cmd_buffer(iommu);
+ amd_iommu_flush_all_devices();
+ amd_iommu_flush_all_domains();
+
+ iommu->reset_in_progress = false;
}
-static void flush_all_devices_for_iommu(struct amd_iommu *iommu)
+/****************************************************************************
+ *
+ * The functions below are used the create the page table mappings for
+ * unity mapped regions.
+ *
+ ****************************************************************************/
+
+/*
+ * This function is used to add another level to an IO page table. Adding
+ * another level increases the size of the address space by 9 bits to a size up
+ * to 64 bits.
+ */
+static bool increase_address_space(struct protection_domain *domain,
+ gfp_t gfp)
{
- int i;
+ u64 *pte;
- for (i = 0; i <= amd_iommu_last_bdf; ++i) {
- if (iommu != amd_iommu_rlookup_table[i])
- continue;
+ if (domain->mode == PAGE_MODE_6_LEVEL)
+ /* address space already 64 bit large */
+ return false;
- iommu_queue_inv_dev_entry(iommu, i);
- iommu_completion_wait(iommu);
- }
+ pte = (void *)get_zeroed_page(gfp);
+ if (!pte)
+ return false;
+
+ *pte = PM_LEVEL_PDE(domain->mode,
+ virt_to_phys(domain->pt_root));
+ domain->pt_root = pte;
+ domain->mode += 1;
+ domain->updated = true;
+
+ return true;
}
-static void flush_devices_by_domain(struct protection_domain *domain)
+static u64 *alloc_pte(struct protection_domain *domain,
+ unsigned long address,
+ int end_lvl,
+ u64 **pte_page,
+ gfp_t gfp)
{
- struct amd_iommu *iommu;
- int i;
+ u64 *pte, *page;
+ int level;
- for (i = 0; i <= amd_iommu_last_bdf; ++i) {
- if ((domain == NULL && amd_iommu_pd_table[i] == NULL) ||
- (amd_iommu_pd_table[i] != domain))
- continue;
+ while (address > PM_LEVEL_SIZE(domain->mode))
+ increase_address_space(domain, gfp);
- iommu = amd_iommu_rlookup_table[i];
- if (!iommu)
- continue;
+ level = domain->mode - 1;
+ pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
+
+ while (level > end_lvl) {
+ if (!IOMMU_PTE_PRESENT(*pte)) {
+ page = (u64 *)get_zeroed_page(gfp);
+ if (!page)
+ return NULL;
+ *pte = PM_LEVEL_PDE(level, virt_to_phys(page));
+ }
- iommu_queue_inv_dev_entry(iommu, i);
- iommu_completion_wait(iommu);
+ level -= 1;
+
+ pte = IOMMU_PTE_PAGE(*pte);
+
+ if (pte_page && level == end_lvl)
+ *pte_page = pte;
+
+ pte = &pte[PM_LEVEL_INDEX(level, address)];
}
+
+ return pte;
}
-static void reset_iommu_command_buffer(struct amd_iommu *iommu)
+/*
+ * This function checks if there is a PTE for a given dma address. If
+ * there is one, it returns the pointer to it.
+ */
+static u64 *fetch_pte(struct protection_domain *domain,
+ unsigned long address, int map_size)
{
- pr_err("AMD-Vi: Resetting IOMMU command buffer\n");
+ int level;
+ u64 *pte;
- if (iommu->reset_in_progress)
- panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n");
+ level = domain->mode - 1;
+ pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
- iommu->reset_in_progress = true;
+ while (level > map_size) {
+ if (!IOMMU_PTE_PRESENT(*pte))
+ return NULL;
- amd_iommu_reset_cmd_buffer(iommu);
- flush_all_devices_for_iommu(iommu);
- flush_all_domains_on_iommu(iommu);
+ level -= 1;
- iommu->reset_in_progress = false;
-}
+ pte = IOMMU_PTE_PAGE(*pte);
+ pte = &pte[PM_LEVEL_INDEX(level, address)];
-void amd_iommu_flush_all_devices(void)
-{
- flush_devices_by_domain(NULL);
-}
+ if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
+ pte = NULL;
+ break;
+ }
+ }
-/****************************************************************************
- *
- * The functions below are used the create the page table mappings for
- * unity mapped regions.
- *
- ****************************************************************************/
+ return pte;
+}
/*
* Generic mapping functions. It maps a physical address into a DMA
@@ -654,28 +828,6 @@ static int iommu_for_unity_map(struct amd_iommu *iommu,
}
/*
- * Init the unity mappings for a specific IOMMU in the system
- *
- * Basically iterates over all unity mapping entries and applies them to
- * the default domain DMA of that IOMMU if necessary.
- */
-static int iommu_init_unity_mappings(struct amd_iommu *iommu)
-{
- struct unity_map_entry *entry;
- int ret;
-
- list_for_each_entry(entry, &amd_iommu_unity_map, list) {
- if (!iommu_for_unity_map(iommu, entry))
- continue;
- ret = dma_ops_unity_map(iommu->default_dom, entry);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/*
* This function actually applies the mapping to the page table of the
* dma_ops domain.
*/
@@ -704,6 +856,28 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
}
/*
+ * Init the unity mappings for a specific IOMMU in the system
+ *
+ * Basically iterates over all unity mapping entries and applies them to
+ * the default domain DMA of that IOMMU if necessary.
+ */
+static int iommu_init_unity_mappings(struct amd_iommu *iommu)
+{
+ struct unity_map_entry *entry;
+ int ret;
+
+ list_for_each_entry(entry, &amd_iommu_unity_map, list) {
+ if (!iommu_for_unity_map(iommu, entry))
+ continue;
+ ret = dma_ops_unity_map(iommu->default_dom, entry);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
* Inits the unity mappings required for a specific device
*/
static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom,
@@ -740,34 +914,23 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom,
*/
/*
- * This function checks if there is a PTE for a given dma address. If
- * there is one, it returns the pointer to it.
+ * Used to reserve address ranges in the aperture (e.g. for exclusion
+ * ranges.
*/
-static u64 *fetch_pte(struct protection_domain *domain,
- unsigned long address, int map_size)
+static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
+ unsigned long start_page,
+ unsigned int pages)
{
- int level;
- u64 *pte;
-
- level = domain->mode - 1;
- pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
-
- while (level > map_size) {
- if (!IOMMU_PTE_PRESENT(*pte))
- return NULL;
-
- level -= 1;
+ unsigned int i, last_page = dom->aperture_size >> PAGE_SHIFT;
- pte = IOMMU_PTE_PAGE(*pte);
- pte = &pte[PM_LEVEL_INDEX(level, address)];
+ if (start_page + pages > last_page)
+ pages = last_page - start_page;
- if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
- pte = NULL;
- break;
- }
+ for (i = start_page; i < start_page + pages; ++i) {
+ int index = i / APERTURE_RANGE_PAGES;
+ int page = i % APERTURE_RANGE_PAGES;
+ __set_bit(page, dom->aperture[index]->bitmap);
}
-
- return pte;
}
/*
@@ -775,11 +938,11 @@ static u64 *fetch_pte(struct protection_domain *domain,
* aperture in case of dma_ops domain allocation or address allocation
* failure.
*/
-static int alloc_new_range(struct amd_iommu *iommu,
- struct dma_ops_domain *dma_dom,
+static int alloc_new_range(struct dma_ops_domain *dma_dom,
bool populate, gfp_t gfp)
{
int index = dma_dom->aperture_size >> APERTURE_RANGE_SHIFT;
+ struct amd_iommu *iommu;
int i;
#ifdef CONFIG_IOMMU_STRESS
@@ -819,14 +982,17 @@ static int alloc_new_range(struct amd_iommu *iommu,
dma_dom->aperture_size += APERTURE_RANGE_SIZE;
/* Intialize the exclusion range if necessary */
- if (iommu->exclusion_start &&
- iommu->exclusion_start >= dma_dom->aperture[index]->offset &&
- iommu->exclusion_start < dma_dom->aperture_size) {
- unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT;
- int pages = iommu_num_pages(iommu->exclusion_start,
- iommu->exclusion_length,
- PAGE_SIZE);
- dma_ops_reserve_addresses(dma_dom, startpage, pages);
+ for_each_iommu(iommu) {
+ if (iommu->exclusion_start &&
+ iommu->exclusion_start >= dma_dom->aperture[index]->offset
+ && iommu->exclusion_start < dma_dom->aperture_size) {
+ unsigned long startpage;
+ int pages = iommu_num_pages(iommu->exclusion_start,
+ iommu->exclusion_length,
+ PAGE_SIZE);
+ startpage = iommu->exclusion_start >> PAGE_SHIFT;
+ dma_ops_reserve_addresses(dma_dom, startpage, pages);
+ }
}
/*
@@ -928,7 +1094,7 @@ static unsigned long dma_ops_alloc_addresses(struct device *dev,
}
if (unlikely(address == -1))
- address = bad_dma_address;
+ address = DMA_ERROR_CODE;
WARN_ON((address + (PAGE_SIZE*pages)) > dom->aperture_size);
@@ -973,6 +1139,31 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom,
*
****************************************************************************/
+/*
+ * This function adds a protection domain to the global protection domain list
+ */
+static void add_domain_to_list(struct protection_domain *domain)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+ list_add(&domain->list, &amd_iommu_pd_list);
+ spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+}
+
+/*
+ * This function removes a protection domain to the global
+ * protection domain list
+ */
+static void del_domain_from_list(struct protection_domain *domain)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+ list_del(&domain->list);
+ spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+}
+
static u16 domain_id_alloc(void)
{
unsigned long flags;
@@ -1000,26 +1191,6 @@ static void domain_id_free(int id)
write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
}
-/*
- * Used to reserve address ranges in the aperture (e.g. for exclusion
- * ranges.
- */
-static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
- unsigned long start_page,
- unsigned int pages)
-{
- unsigned int i, last_page = dom->aperture_size >> PAGE_SHIFT;
-
- if (start_page + pages > last_page)
- pages = last_page - start_page;
-
- for (i = start_page; i < start_page + pages; ++i) {
- int index = i / APERTURE_RANGE_PAGES;
- int page = i % APERTURE_RANGE_PAGES;
- __set_bit(page, dom->aperture[index]->bitmap);
- }
-}
-
static void free_pagetable(struct protection_domain *domain)
{
int i, j;
@@ -1061,6 +1232,8 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)
if (!dom)
return;
+ del_domain_from_list(&dom->domain);
+
free_pagetable(&dom->domain);
for (i = 0; i < APERTURE_MAX_RANGES; ++i) {
@@ -1078,7 +1251,7 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)
* It also intializes the page table and the address allocator data
* structures required for the dma_ops interface
*/
-static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu)
+static struct dma_ops_domain *dma_ops_domain_alloc(void)
{
struct dma_ops_domain *dma_dom;
@@ -1091,6 +1264,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu)
dma_dom->domain.id = domain_id_alloc();
if (dma_dom->domain.id == 0)
goto free_dma_dom;
+ INIT_LIST_HEAD(&dma_dom->domain.dev_list);
dma_dom->domain.mode = PAGE_MODE_2_LEVEL;
dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL);
dma_dom->domain.flags = PD_DMA_OPS_MASK;
@@ -1101,7 +1275,9 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu)
dma_dom->need_flush = false;
dma_dom->target_dev = 0xffff;
- if (alloc_new_range(iommu, dma_dom, true, GFP_KERNEL))
+ add_domain_to_list(&dma_dom->domain);
+
+ if (alloc_new_range(dma_dom, true, GFP_KERNEL))
goto free_dma_dom;
/*
@@ -1129,22 +1305,6 @@ static bool dma_ops_domain(struct protection_domain *domain)
return domain->flags & PD_DMA_OPS_MASK;
}
-/*
- * Find out the protection domain structure for a given PCI device. This
- * will give us the pointer to the page table root for example.
- */
-static struct protection_domain *domain_for_device(u16 devid)
-{
- struct protection_domain *dom;
- unsigned long flags;
-
- read_lock_irqsave(&amd_iommu_devtable_lock, flags);
- dom = amd_iommu_pd_table[devid];
- read_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
-
- return dom;
-}
-
static void set_dte_entry(u16 devid, struct protection_domain *domain)
{
u64 pte_root = virt_to_phys(domain->pt_root);
@@ -1156,42 +1316,123 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain)
amd_iommu_dev_table[devid].data[2] = domain->id;
amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root);
amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root);
+}
+
+static void clear_dte_entry(u16 devid)
+{
+ /* remove entry from the device table seen by the hardware */
+ amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
+ amd_iommu_dev_table[devid].data[1] = 0;
+ amd_iommu_dev_table[devid].data[2] = 0;
- amd_iommu_pd_table[devid] = domain;
+ amd_iommu_apply_erratum_63(devid);
+}
+
+static void do_attach(struct device *dev, struct protection_domain *domain)
+{
+ struct iommu_dev_data *dev_data;
+ struct amd_iommu *iommu;
+ u16 devid;
+
+ devid = get_device_id(dev);
+ iommu = amd_iommu_rlookup_table[devid];
+ dev_data = get_dev_data(dev);
+
+ /* Update data structures */
+ dev_data->domain = domain;
+ list_add(&dev_data->list, &domain->dev_list);
+ set_dte_entry(devid, domain);
+
+ /* Do reference counting */
+ domain->dev_iommu[iommu->index] += 1;
+ domain->dev_cnt += 1;
+
+ /* Flush the DTE entry */
+ iommu_flush_device(dev);
+}
+
+static void do_detach(struct device *dev)
+{
+ struct iommu_dev_data *dev_data;
+ struct amd_iommu *iommu;
+ u16 devid;
+
+ devid = get_device_id(dev);
+ iommu = amd_iommu_rlookup_table[devid];
+ dev_data = get_dev_data(dev);
+
+ /* decrease reference counters */
+ dev_data->domain->dev_iommu[iommu->index] -= 1;
+ dev_data->domain->dev_cnt -= 1;
+
+ /* Update data structures */
+ dev_data->domain = NULL;
+ list_del(&dev_data->list);
+ clear_dte_entry(devid);
+
+ /* Flush the DTE entry */
+ iommu_flush_device(dev);
}
/*
* If a device is not yet associated with a domain, this function does
* assigns it visible for the hardware
*/
-static void __attach_device(struct amd_iommu *iommu,
- struct protection_domain *domain,
- u16 devid)
+static int __attach_device(struct device *dev,
+ struct protection_domain *domain)
{
+ struct iommu_dev_data *dev_data, *alias_data;
+
+ dev_data = get_dev_data(dev);
+ alias_data = get_dev_data(dev_data->alias);
+
+ if (!alias_data)
+ return -EINVAL;
+
/* lock domain */
spin_lock(&domain->lock);
- /* update DTE entry */
- set_dte_entry(devid, domain);
+ /* Some sanity checks */
+ if (alias_data->domain != NULL &&
+ alias_data->domain != domain)
+ return -EBUSY;
+
+ if (dev_data->domain != NULL &&
+ dev_data->domain != domain)
+ return -EBUSY;
- domain->dev_cnt += 1;
+ /* Do real assignment */
+ if (dev_data->alias != dev) {
+ alias_data = get_dev_data(dev_data->alias);
+ if (alias_data->domain == NULL)
+ do_attach(dev_data->alias, domain);
+
+ atomic_inc(&alias_data->bind);
+ }
+
+ if (dev_data->domain == NULL)
+ do_attach(dev, domain);
+
+ atomic_inc(&dev_data->bind);
/* ready */
spin_unlock(&domain->lock);
+
+ return 0;
}
/*
* If a device is not yet associated with a domain, this function does
* assigns it visible for the hardware
*/
-static void attach_device(struct amd_iommu *iommu,
- struct protection_domain *domain,
- u16 devid)
+static int attach_device(struct device *dev,
+ struct protection_domain *domain)
{
unsigned long flags;
+ int ret;
write_lock_irqsave(&amd_iommu_devtable_lock, flags);
- __attach_device(iommu, domain, devid);
+ ret = __attach_device(dev, domain);
write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
/*
@@ -1199,96 +1440,125 @@ static void attach_device(struct amd_iommu *iommu,
* left the caches in the IOMMU dirty. So we have to flush
* here to evict all dirty stuff.
*/
- iommu_queue_inv_dev_entry(iommu, devid);
- iommu_flush_tlb_pde(iommu, domain->id);
+ iommu_flush_tlb_pde(domain);
+
+ return ret;
}
/*
* Removes a device from a protection domain (unlocked)
*/
-static void __detach_device(struct protection_domain *domain, u16 devid)
+static void __detach_device(struct device *dev)
{
+ struct iommu_dev_data *dev_data = get_dev_data(dev);
+ struct iommu_dev_data *alias_data;
+ unsigned long flags;
- /* lock domain */
- spin_lock(&domain->lock);
+ BUG_ON(!dev_data->domain);
- /* remove domain from the lookup table */
- amd_iommu_pd_table[devid] = NULL;
+ spin_lock_irqsave(&dev_data->domain->lock, flags);
- /* remove entry from the device table seen by the hardware */
- amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
- amd_iommu_dev_table[devid].data[1] = 0;
- amd_iommu_dev_table[devid].data[2] = 0;
+ if (dev_data->alias != dev) {
+ alias_data = get_dev_data(dev_data->alias);
+ if (atomic_dec_and_test(&alias_data->bind))
+ do_detach(dev_data->alias);
+ }
- /* decrease reference counter */
- domain->dev_cnt -= 1;
+ if (atomic_dec_and_test(&dev_data->bind))
+ do_detach(dev);
- /* ready */
- spin_unlock(&domain->lock);
+ spin_unlock_irqrestore(&dev_data->domain->lock, flags);
/*
* If we run in passthrough mode the device must be assigned to the
* passthrough domain if it is detached from any other domain
*/
- if (iommu_pass_through) {
- struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
- __attach_device(iommu, pt_domain, devid);
- }
+ if (iommu_pass_through && dev_data->domain == NULL)
+ __attach_device(dev, pt_domain);
}
/*
* Removes a device from a protection domain (with devtable_lock held)
*/
-static void detach_device(struct protection_domain *domain, u16 devid)
+static void detach_device(struct device *dev)
{
unsigned long flags;
/* lock device table */
write_lock_irqsave(&amd_iommu_devtable_lock, flags);
- __detach_device(domain, devid);
+ __detach_device(dev);
write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
}
+/*
+ * Find out the protection domain structure for a given PCI device. This
+ * will give us the pointer to the page table root for example.
+ */
+static struct protection_domain *domain_for_device(struct device *dev)
+{
+ struct protection_domain *dom;
+ struct iommu_dev_data *dev_data, *alias_data;
+ unsigned long flags;
+ u16 devid, alias;
+
+ devid = get_device_id(dev);
+ alias = amd_iommu_alias_table[devid];
+ dev_data = get_dev_data(dev);
+ alias_data = get_dev_data(dev_data->alias);
+ if (!alias_data)
+ return NULL;
+
+ read_lock_irqsave(&amd_iommu_devtable_lock, flags);
+ dom = dev_data->domain;
+ if (dom == NULL &&
+ alias_data->domain != NULL) {
+ __attach_device(dev, alias_data->domain);
+ dom = alias_data->domain;
+ }
+
+ read_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+
+ return dom;
+}
+
static int device_change_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
struct device *dev = data;
- struct pci_dev *pdev = to_pci_dev(dev);
- u16 devid = calc_devid(pdev->bus->number, pdev->devfn);
+ u16 devid;
struct protection_domain *domain;
struct dma_ops_domain *dma_domain;
struct amd_iommu *iommu;
unsigned long flags;
- if (devid > amd_iommu_last_bdf)
- goto out;
-
- devid = amd_iommu_alias_table[devid];
-
- iommu = amd_iommu_rlookup_table[devid];
- if (iommu == NULL)
- goto out;
-
- domain = domain_for_device(devid);
+ if (!check_device(dev))
+ return 0;
- if (domain && !dma_ops_domain(domain))
- WARN_ONCE(1, "AMD IOMMU WARNING: device %s already bound "
- "to a non-dma-ops domain\n", dev_name(dev));
+ devid = get_device_id(dev);
+ iommu = amd_iommu_rlookup_table[devid];
switch (action) {
case BUS_NOTIFY_UNBOUND_DRIVER:
+
+ domain = domain_for_device(dev);
+
if (!domain)
goto out;
if (iommu_pass_through)
break;
- detach_device(domain, devid);
+ detach_device(dev);
break;
case BUS_NOTIFY_ADD_DEVICE:
+
+ iommu_init_device(dev);
+
+ domain = domain_for_device(dev);
+
/* allocate a protection domain if a device is added */
dma_domain = find_protection_domain(devid);
if (dma_domain)
goto out;
- dma_domain = dma_ops_domain_alloc(iommu);
+ dma_domain = dma_ops_domain_alloc();
if (!dma_domain)
goto out;
dma_domain->target_dev = devid;
@@ -1298,11 +1568,15 @@ static int device_change_notifier(struct notifier_block *nb,
spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
break;
+ case BUS_NOTIFY_DEL_DEVICE:
+
+ iommu_uninit_device(dev);
+
default:
goto out;
}
- iommu_queue_inv_dev_entry(iommu, devid);
+ iommu_flush_device(dev);
iommu_completion_wait(iommu);
out:
@@ -1320,106 +1594,46 @@ static struct notifier_block device_nb = {
*****************************************************************************/
/*
- * This function checks if the driver got a valid device from the caller to
- * avoid dereferencing invalid pointers.
- */
-static bool check_device(struct device *dev)
-{
- if (!dev || !dev->dma_mask)
- return false;
-
- return true;
-}
-
-/*
- * In this function the list of preallocated protection domains is traversed to
- * find the domain for a specific device
- */
-static struct dma_ops_domain *find_protection_domain(u16 devid)
-{
- struct dma_ops_domain *entry, *ret = NULL;
- unsigned long flags;
-
- if (list_empty(&iommu_pd_list))
- return NULL;
-
- spin_lock_irqsave(&iommu_pd_list_lock, flags);
-
- list_for_each_entry(entry, &iommu_pd_list, list) {
- if (entry->target_dev == devid) {
- ret = entry;
- break;
- }
- }
-
- spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
-
- return ret;
-}
-
-/*
* In the dma_ops path we only have the struct device. This function
* finds the corresponding IOMMU, the protection domain and the
* requestor id for a given device.
* If the device is not yet associated with a domain this is also done
* in this function.
*/
-static int get_device_resources(struct device *dev,
- struct amd_iommu **iommu,
- struct protection_domain **domain,
- u16 *bdf)
+static struct protection_domain *get_domain(struct device *dev)
{
+ struct protection_domain *domain;
struct dma_ops_domain *dma_dom;
- struct pci_dev *pcidev;
- u16 _bdf;
-
- *iommu = NULL;
- *domain = NULL;
- *bdf = 0xffff;
-
- if (dev->bus != &pci_bus_type)
- return 0;
+ u16 devid = get_device_id(dev);
- pcidev = to_pci_dev(dev);
- _bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
-
- /* device not translated by any IOMMU in the system? */
- if (_bdf > amd_iommu_last_bdf)
- return 0;
+ if (!check_device(dev))
+ return ERR_PTR(-EINVAL);
- *bdf = amd_iommu_alias_table[_bdf];
+ domain = domain_for_device(dev);
+ if (domain != NULL && !dma_ops_domain(domain))
+ return ERR_PTR(-EBUSY);
- *iommu = amd_iommu_rlookup_table[*bdf];
- if (*iommu == NULL)
- return 0;
- *domain = domain_for_device(*bdf);
- if (*domain == NULL) {
- dma_dom = find_protection_domain(*bdf);
- if (!dma_dom)
- dma_dom = (*iommu)->default_dom;
- *domain = &dma_dom->domain;
- attach_device(*iommu, *domain, *bdf);
- DUMP_printk("Using protection domain %d for device %s\n",
- (*domain)->id, dev_name(dev));
- }
+ if (domain != NULL)
+ return domain;
- if (domain_for_device(_bdf) == NULL)
- attach_device(*iommu, *domain, _bdf);
+ /* Device not bount yet - bind it */
+ dma_dom = find_protection_domain(devid);
+ if (!dma_dom)
+ dma_dom = amd_iommu_rlookup_table[devid]->default_dom;
+ attach_device(dev, &dma_dom->domain);
+ DUMP_printk("Using protection domain %d for device %s\n",
+ dma_dom->domain.id, dev_name(dev));
- return 1;
+ return &dma_dom->domain;
}
static void update_device_table(struct protection_domain *domain)
{
- unsigned long flags;
- int i;
+ struct iommu_dev_data *dev_data;
- for (i = 0; i <= amd_iommu_last_bdf; ++i) {
- if (amd_iommu_pd_table[i] != domain)
- continue;
- write_lock_irqsave(&amd_iommu_devtable_lock, flags);
- set_dte_entry(i, domain);
- write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+ list_for_each_entry(dev_data, &domain->dev_list, list) {
+ u16 devid = get_device_id(dev_data->dev);
+ set_dte_entry(devid, domain);
}
}
@@ -1429,76 +1643,13 @@ static void update_domain(struct protection_domain *domain)
return;
update_device_table(domain);
- flush_devices_by_domain(domain);
- iommu_flush_domain(domain->id);
+ iommu_flush_domain_devices(domain);
+ iommu_flush_tlb_pde(domain);
domain->updated = false;
}
/*
- * This function is used to add another level to an IO page table. Adding
- * another level increases the size of the address space by 9 bits to a size up
- * to 64 bits.
- */
-static bool increase_address_space(struct protection_domain *domain,
- gfp_t gfp)
-{
- u64 *pte;
-
- if (domain->mode == PAGE_MODE_6_LEVEL)
- /* address space already 64 bit large */
- return false;
-
- pte = (void *)get_zeroed_page(gfp);
- if (!pte)
- return false;
-
- *pte = PM_LEVEL_PDE(domain->mode,
- virt_to_phys(domain->pt_root));
- domain->pt_root = pte;
- domain->mode += 1;
- domain->updated = true;
-
- return true;
-}
-
-static u64 *alloc_pte(struct protection_domain *domain,
- unsigned long address,
- int end_lvl,
- u64 **pte_page,
- gfp_t gfp)
-{
- u64 *pte, *page;
- int level;
-
- while (address > PM_LEVEL_SIZE(domain->mode))
- increase_address_space(domain, gfp);
-
- level = domain->mode - 1;
- pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
-
- while (level > end_lvl) {
- if (!IOMMU_PTE_PRESENT(*pte)) {
- page = (u64 *)get_zeroed_page(gfp);
- if (!page)
- return NULL;
- *pte = PM_LEVEL_PDE(level, virt_to_phys(page));
- }
-
- level -= 1;
-
- pte = IOMMU_PTE_PAGE(*pte);
-
- if (pte_page && level == end_lvl)
- *pte_page = pte;
-
- pte = &pte[PM_LEVEL_INDEX(level, address)];
- }
-
- return pte;
-}
-
-/*
* This function fetches the PTE for a given address in the aperture
*/
static u64* dma_ops_get_pte(struct dma_ops_domain *dom,
@@ -1528,8 +1679,7 @@ static u64* dma_ops_get_pte(struct dma_ops_domain *dom,
* This is the generic map function. It maps one 4kb page at paddr to
* the given address in the DMA address space for the domain.
*/
-static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu,
- struct dma_ops_domain *dom,
+static dma_addr_t dma_ops_domain_map(struct dma_ops_domain *dom,
unsigned long address,
phys_addr_t paddr,
int direction)
@@ -1542,7 +1692,7 @@ static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu,
pte = dma_ops_get_pte(dom, address);
if (!pte)
- return bad_dma_address;
+ return DMA_ERROR_CODE;
__pte = paddr | IOMMU_PTE_P | IOMMU_PTE_FC;
@@ -1563,8 +1713,7 @@ static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu,
/*
* The generic unmapping function for on page in the DMA address space.
*/
-static void dma_ops_domain_unmap(struct amd_iommu *iommu,
- struct dma_ops_domain *dom,
+static void dma_ops_domain_unmap(struct dma_ops_domain *dom,
unsigned long address)
{
struct aperture_range *aperture;
@@ -1595,7 +1744,6 @@ static void dma_ops_domain_unmap(struct amd_iommu *iommu,
* Must be called with the domain lock held.
*/
static dma_addr_t __map_single(struct device *dev,
- struct amd_iommu *iommu,
struct dma_ops_domain *dma_dom,
phys_addr_t paddr,
size_t size,
@@ -1623,7 +1771,7 @@ static dma_addr_t __map_single(struct device *dev,
retry:
address = dma_ops_alloc_addresses(dev, dma_dom, pages, align_mask,
dma_mask);
- if (unlikely(address == bad_dma_address)) {
+ if (unlikely(address == DMA_ERROR_CODE)) {
/*
* setting next_address here will let the address
* allocator only scan the new allocated range in the
@@ -1631,7 +1779,7 @@ retry:
*/
dma_dom->next_address = dma_dom->aperture_size;
- if (alloc_new_range(iommu, dma_dom, false, GFP_ATOMIC))
+ if (alloc_new_range(dma_dom, false, GFP_ATOMIC))
goto out;
/*
@@ -1643,8 +1791,8 @@ retry:
start = address;
for (i = 0; i < pages; ++i) {
- ret = dma_ops_domain_map(iommu, dma_dom, start, paddr, dir);
- if (ret == bad_dma_address)
+ ret = dma_ops_domain_map(dma_dom, start, paddr, dir);
+ if (ret == DMA_ERROR_CODE)
goto out_unmap;
paddr += PAGE_SIZE;
@@ -1655,10 +1803,10 @@ retry:
ADD_STATS_COUNTER(alloced_io_mem, size);
if (unlikely(dma_dom->need_flush && !amd_iommu_unmap_flush)) {
- iommu_flush_tlb(iommu, dma_dom->domain.id);
+ iommu_flush_tlb(&dma_dom->domain);
dma_dom->need_flush = false;
- } else if (unlikely(iommu_has_npcache(iommu)))
- iommu_flush_pages(iommu, dma_dom->domain.id, address, size);
+ } else if (unlikely(amd_iommu_np_cache))
+ iommu_flush_pages(&dma_dom->domain, address, size);
out:
return address;
@@ -1667,20 +1815,19 @@ out_unmap:
for (--i; i >= 0; --i) {
start -= PAGE_SIZE;
- dma_ops_domain_unmap(iommu, dma_dom, start);
+ dma_ops_domain_unmap(dma_dom, start);
}
dma_ops_free_addresses(dma_dom, address, pages);
- return bad_dma_address;
+ return DMA_ERROR_CODE;
}
/*
* Does the reverse of the __map_single function. Must be called with
* the domain lock held too
*/
-static void __unmap_single(struct amd_iommu *iommu,
- struct dma_ops_domain *dma_dom,
+static void __unmap_single(struct dma_ops_domain *dma_dom,
dma_addr_t dma_addr,
size_t size,
int dir)
@@ -1688,7 +1835,7 @@ static void __unmap_single(struct amd_iommu *iommu,
dma_addr_t i, start;
unsigned int pages;
- if ((dma_addr == bad_dma_address) ||
+ if ((dma_addr == DMA_ERROR_CODE) ||
(dma_addr + size > dma_dom->aperture_size))
return;
@@ -1697,7 +1844,7 @@ static void __unmap_single(struct amd_iommu *iommu,
start = dma_addr;
for (i = 0; i < pages; ++i) {
- dma_ops_domain_unmap(iommu, dma_dom, start);
+ dma_ops_domain_unmap(dma_dom, start);
start += PAGE_SIZE;
}
@@ -1706,7 +1853,7 @@ static void __unmap_single(struct amd_iommu *iommu,
dma_ops_free_addresses(dma_dom, dma_addr, pages);
if (amd_iommu_unmap_flush || dma_dom->need_flush) {
- iommu_flush_pages(iommu, dma_dom->domain.id, dma_addr, size);
+ iommu_flush_pages(&dma_dom->domain, dma_addr, size);
dma_dom->need_flush = false;
}
}
@@ -1720,36 +1867,29 @@ static dma_addr_t map_page(struct device *dev, struct page *page,
struct dma_attrs *attrs)
{
unsigned long flags;
- struct amd_iommu *iommu;
struct protection_domain *domain;
- u16 devid;
dma_addr_t addr;
u64 dma_mask;
phys_addr_t paddr = page_to_phys(page) + offset;
INC_STATS_COUNTER(cnt_map_single);
- if (!check_device(dev))
- return bad_dma_address;
-
- dma_mask = *dev->dma_mask;
-
- get_device_resources(dev, &iommu, &domain, &devid);
-
- if (iommu == NULL || domain == NULL)
- /* device not handled by any AMD IOMMU */
+ domain = get_domain(dev);
+ if (PTR_ERR(domain) == -EINVAL)
return (dma_addr_t)paddr;
+ else if (IS_ERR(domain))
+ return DMA_ERROR_CODE;
- if (!dma_ops_domain(domain))
- return bad_dma_address;
+ dma_mask = *dev->dma_mask;
spin_lock_irqsave(&domain->lock, flags);
- addr = __map_single(dev, iommu, domain->priv, paddr, size, dir, false,
+
+ addr = __map_single(dev, domain->priv, paddr, size, dir, false,
dma_mask);
- if (addr == bad_dma_address)
+ if (addr == DMA_ERROR_CODE)
goto out;
- iommu_completion_wait(iommu);
+ iommu_flush_complete(domain);
out:
spin_unlock_irqrestore(&domain->lock, flags);
@@ -1764,25 +1904,19 @@ static void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir, struct dma_attrs *attrs)
{
unsigned long flags;
- struct amd_iommu *iommu;
struct protection_domain *domain;
- u16 devid;
INC_STATS_COUNTER(cnt_unmap_single);
- if (!check_device(dev) ||
- !get_device_resources(dev, &iommu, &domain, &devid))
- /* device not handled by any AMD IOMMU */
- return;
-
- if (!dma_ops_domain(domain))
+ domain = get_domain(dev);
+ if (IS_ERR(domain))
return;
spin_lock_irqsave(&domain->lock, flags);
- __unmap_single(iommu, domain->priv, dma_addr, size, dir);
+ __unmap_single(domain->priv, dma_addr, size, dir);
- iommu_completion_wait(iommu);
+ iommu_flush_complete(domain);
spin_unlock_irqrestore(&domain->lock, flags);
}
@@ -1814,9 +1948,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
struct dma_attrs *attrs)
{
unsigned long flags;
- struct amd_iommu *iommu;
struct protection_domain *domain;
- u16 devid;
int i;
struct scatterlist *s;
phys_addr_t paddr;
@@ -1825,25 +1957,20 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
INC_STATS_COUNTER(cnt_map_sg);
- if (!check_device(dev))
+ domain = get_domain(dev);
+ if (PTR_ERR(domain) == -EINVAL)
+ return map_sg_no_iommu(dev, sglist, nelems, dir);
+ else if (IS_ERR(domain))
return 0;
dma_mask = *dev->dma_mask;
- get_device_resources(dev, &iommu, &domain, &devid);
-
- if (!iommu || !domain)
- return map_sg_no_iommu(dev, sglist, nelems, dir);
-
- if (!dma_ops_domain(domain))
- return 0;
-
spin_lock_irqsave(&domain->lock, flags);
for_each_sg(sglist, s, nelems, i) {
paddr = sg_phys(s);
- s->dma_address = __map_single(dev, iommu, domain->priv,
+ s->dma_address = __map_single(dev, domain->priv,
paddr, s->length, dir, false,
dma_mask);
@@ -1854,7 +1981,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
goto unmap;
}
- iommu_completion_wait(iommu);
+ iommu_flush_complete(domain);
out:
spin_unlock_irqrestore(&domain->lock, flags);
@@ -1863,7 +1990,7 @@ out:
unmap:
for_each_sg(sglist, s, mapped_elems, i) {
if (s->dma_address)
- __unmap_single(iommu, domain->priv, s->dma_address,
+ __unmap_single(domain->priv, s->dma_address,
s->dma_length, dir);
s->dma_address = s->dma_length = 0;
}
@@ -1882,30 +2009,25 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist,
struct dma_attrs *attrs)
{
unsigned long flags;
- struct amd_iommu *iommu;
struct protection_domain *domain;
struct scatterlist *s;
- u16 devid;
int i;
INC_STATS_COUNTER(cnt_unmap_sg);
- if (!check_device(dev) ||
- !get_device_resources(dev, &iommu, &domain, &devid))
- return;
-
- if (!dma_ops_domain(domain))
+ domain = get_domain(dev);
+ if (IS_ERR(domain))
return;
spin_lock_irqsave(&domain->lock, flags);
for_each_sg(sglist, s, nelems, i) {
- __unmap_single(iommu, domain->priv, s->dma_address,
+ __unmap_single(domain->priv, s->dma_address,
s->dma_length, dir);
s->dma_address = s->dma_length = 0;
}
- iommu_completion_wait(iommu);
+ iommu_flush_complete(domain);
spin_unlock_irqrestore(&domain->lock, flags);
}
@@ -1918,49 +2040,44 @@ static void *alloc_coherent(struct device *dev, size_t size,
{
unsigned long flags;
void *virt_addr;
- struct amd_iommu *iommu;
struct protection_domain *domain;
- u16 devid;
phys_addr_t paddr;
u64 dma_mask = dev->coherent_dma_mask;
INC_STATS_COUNTER(cnt_alloc_coherent);
- if (!check_device(dev))
+ domain = get_domain(dev);
+ if (PTR_ERR(domain) == -EINVAL) {
+ virt_addr = (void *)__get_free_pages(flag, get_order(size));
+ *dma_addr = __pa(virt_addr);
+ return virt_addr;
+ } else if (IS_ERR(domain))
return NULL;
- if (!get_device_resources(dev, &iommu, &domain, &devid))
- flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
+ dma_mask = dev->coherent_dma_mask;
+ flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
+ flag |= __GFP_ZERO;
- flag |= __GFP_ZERO;
virt_addr = (void *)__get_free_pages(flag, get_order(size));
if (!virt_addr)
return NULL;
paddr = virt_to_phys(virt_addr);
- if (!iommu || !domain) {
- *dma_addr = (dma_addr_t)paddr;
- return virt_addr;
- }
-
- if (!dma_ops_domain(domain))
- goto out_free;
-
if (!dma_mask)
dma_mask = *dev->dma_mask;
spin_lock_irqsave(&domain->lock, flags);
- *dma_addr = __map_single(dev, iommu, domain->priv, paddr,
+ *dma_addr = __map_single(dev, domain->priv, paddr,
size, DMA_BIDIRECTIONAL, true, dma_mask);
- if (*dma_addr == bad_dma_address) {
+ if (*dma_addr == DMA_ERROR_CODE) {
spin_unlock_irqrestore(&domain->lock, flags);
goto out_free;
}
- iommu_completion_wait(iommu);
+ iommu_flush_complete(domain);
spin_unlock_irqrestore(&domain->lock, flags);
@@ -1980,28 +2097,19 @@ static void free_coherent(struct device *dev, size_t size,
void *virt_addr, dma_addr_t dma_addr)
{
unsigned long flags;
- struct amd_iommu *iommu;
struct protection_domain *domain;
- u16 devid;
INC_STATS_COUNTER(cnt_free_coherent);
- if (!check_device(dev))
- return;
-
- get_device_resources(dev, &iommu, &domain, &devid);
-
- if (!iommu || !domain)
- goto free_mem;
-
- if (!dma_ops_domain(domain))
+ domain = get_domain(dev);
+ if (IS_ERR(domain))
goto free_mem;
spin_lock_irqsave(&domain->lock, flags);
- __unmap_single(iommu, domain->priv, dma_addr, size, DMA_BIDIRECTIONAL);
+ __unmap_single(domain->priv, dma_addr, size, DMA_BIDIRECTIONAL);
- iommu_completion_wait(iommu);
+ iommu_flush_complete(domain);
spin_unlock_irqrestore(&domain->lock, flags);
@@ -2015,22 +2123,7 @@ free_mem:
*/
static int amd_iommu_dma_supported(struct device *dev, u64 mask)
{
- u16 bdf;
- struct pci_dev *pcidev;
-
- /* No device or no PCI device */
- if (!dev || dev->bus != &pci_bus_type)
- return 0;
-
- pcidev = to_pci_dev(dev);
-
- bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
-
- /* Out of our scope? */
- if (bdf > amd_iommu_last_bdf)
- return 0;
-
- return 1;
+ return check_device(dev);
}
/*
@@ -2044,25 +2137,30 @@ static void prealloc_protection_domains(void)
{
struct pci_dev *dev = NULL;
struct dma_ops_domain *dma_dom;
- struct amd_iommu *iommu;
u16 devid;
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- devid = calc_devid(dev->bus->number, dev->devfn);
- if (devid > amd_iommu_last_bdf)
- continue;
- devid = amd_iommu_alias_table[devid];
- if (domain_for_device(devid))
+
+ /* Do we handle this device? */
+ if (!check_device(&dev->dev))
continue;
- iommu = amd_iommu_rlookup_table[devid];
- if (!iommu)
+
+ iommu_init_device(&dev->dev);
+
+ /* Is there already any domain for it? */
+ if (domain_for_device(&dev->dev))
continue;
- dma_dom = dma_ops_domain_alloc(iommu);
+
+ devid = get_device_id(&dev->dev);
+
+ dma_dom = dma_ops_domain_alloc();
if (!dma_dom)
continue;
init_unity_mappings_for_device(dma_dom, devid);
dma_dom->target_dev = devid;
+ attach_device(&dev->dev, &dma_dom->domain);
+
list_add_tail(&dma_dom->list, &iommu_pd_list);
}
}
@@ -2091,7 +2189,7 @@ int __init amd_iommu_init_dma_ops(void)
* protection domain will be assigned to the default one.
*/
for_each_iommu(iommu) {
- iommu->default_dom = dma_ops_domain_alloc(iommu);
+ iommu->default_dom = dma_ops_domain_alloc();
if (iommu->default_dom == NULL)
return -ENOMEM;
iommu->default_dom->domain.flags |= PD_DEFAULT_MASK;
@@ -2101,15 +2199,12 @@ int __init amd_iommu_init_dma_ops(void)
}
/*
- * If device isolation is enabled, pre-allocate the protection
- * domains for each device.
+ * Pre-allocate the protection domains for each device.
*/
- if (amd_iommu_isolate)
- prealloc_protection_domains();
+ prealloc_protection_domains();
iommu_detected = 1;
- force_iommu = 1;
- bad_dma_address = 0;
+ swiotlb = 0;
#ifdef CONFIG_GART_IOMMU
gart_iommu_aperture_disabled = 1;
gart_iommu_aperture = 0;
@@ -2148,14 +2243,17 @@ free_domains:
static void cleanup_domain(struct protection_domain *domain)
{
+ struct iommu_dev_data *dev_data, *next;
unsigned long flags;
- u16 devid;
write_lock_irqsave(&amd_iommu_devtable_lock, flags);
- for (devid = 0; devid <= amd_iommu_last_bdf; ++devid)
- if (amd_iommu_pd_table[devid] == domain)
- __detach_device(domain, devid);
+ list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
+ struct device *dev = dev_data->dev;
+
+ do_detach(dev);
+ atomic_set(&dev_data->bind, 0);
+ }
write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
}
@@ -2165,6 +2263,8 @@ static void protection_domain_free(struct protection_domain *domain)
if (!domain)
return;
+ del_domain_from_list(domain);
+
if (domain->id)
domain_id_free(domain->id);
@@ -2183,6 +2283,9 @@ static struct protection_domain *protection_domain_alloc(void)
domain->id = domain_id_alloc();
if (!domain->id)
goto out_err;
+ INIT_LIST_HEAD(&domain->dev_list);
+
+ add_domain_to_list(domain);
return domain;
@@ -2239,26 +2342,23 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom)
static void amd_iommu_detach_device(struct iommu_domain *dom,
struct device *dev)
{
- struct protection_domain *domain = dom->priv;
+ struct iommu_dev_data *dev_data = dev->archdata.iommu;
struct amd_iommu *iommu;
- struct pci_dev *pdev;
u16 devid;
- if (dev->bus != &pci_bus_type)
+ if (!check_device(dev))
return;
- pdev = to_pci_dev(dev);
-
- devid = calc_devid(pdev->bus->number, pdev->devfn);
+ devid = get_device_id(dev);
- if (devid > 0)
- detach_device(domain, devid);
+ if (dev_data->domain != NULL)
+ detach_device(dev);
iommu = amd_iommu_rlookup_table[devid];
if (!iommu)
return;
- iommu_queue_inv_dev_entry(iommu, devid);
+ iommu_flush_device(dev);
iommu_completion_wait(iommu);
}
@@ -2266,35 +2366,30 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
struct device *dev)
{
struct protection_domain *domain = dom->priv;
- struct protection_domain *old_domain;
+ struct iommu_dev_data *dev_data;
struct amd_iommu *iommu;
- struct pci_dev *pdev;
+ int ret;
u16 devid;
- if (dev->bus != &pci_bus_type)
+ if (!check_device(dev))
return -EINVAL;
- pdev = to_pci_dev(dev);
+ dev_data = dev->archdata.iommu;
- devid = calc_devid(pdev->bus->number, pdev->devfn);
-
- if (devid >= amd_iommu_last_bdf ||
- devid != amd_iommu_alias_table[devid])
- return -EINVAL;
+ devid = get_device_id(dev);
iommu = amd_iommu_rlookup_table[devid];
if (!iommu)
return -EINVAL;
- old_domain = domain_for_device(devid);
- if (old_domain)
- detach_device(old_domain, devid);
+ if (dev_data->domain)
+ detach_device(dev);
- attach_device(iommu, domain, devid);
+ ret = attach_device(dev, domain);
iommu_completion_wait(iommu);
- return 0;
+ return ret;
}
static int amd_iommu_map_range(struct iommu_domain *dom,
@@ -2340,7 +2435,7 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom,
iova += PAGE_SIZE;
}
- iommu_flush_domain(domain->id);
+ iommu_flush_tlb_pde(domain);
}
static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
@@ -2391,8 +2486,9 @@ static struct iommu_ops amd_iommu_ops = {
int __init amd_iommu_init_passthrough(void)
{
+ struct amd_iommu *iommu;
struct pci_dev *dev = NULL;
- u16 devid, devid2;
+ u16 devid;
/* allocate passthroug domain */
pt_domain = protection_domain_alloc();
@@ -2402,20 +2498,17 @@ int __init amd_iommu_init_passthrough(void)
pt_domain->mode |= PAGE_MODE_NONE;
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- struct amd_iommu *iommu;
- devid = calc_devid(dev->bus->number, dev->devfn);
- if (devid > amd_iommu_last_bdf)
+ if (!check_device(&dev->dev))
continue;
- devid2 = amd_iommu_alias_table[devid];
+ devid = get_device_id(&dev->dev);
- iommu = amd_iommu_rlookup_table[devid2];
+ iommu = amd_iommu_rlookup_table[devid];
if (!iommu)
continue;
- __attach_device(iommu, pt_domain, devid);
- __attach_device(iommu, pt_domain, devid2);
+ attach_device(&dev->dev, pt_domain);
}
pr_info("AMD-Vi: Initialized for Passthrough Mode\n");
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index b4b61d462dcc..7ffc39965233 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
* Leo Duran <leo.duran@amd.com>
*
@@ -25,10 +25,12 @@
#include <linux/interrupt.h>
#include <linux/msi.h>
#include <asm/pci-direct.h>
+#include <asm/amd_iommu_proto.h>
#include <asm/amd_iommu_types.h>
#include <asm/amd_iommu.h>
#include <asm/iommu.h>
#include <asm/gart.h>
+#include <asm/x86_init.h>
/*
* definitions for the ACPI scanning code
@@ -123,18 +125,24 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have
to handle */
LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings
we find in ACPI */
-#ifdef CONFIG_IOMMU_STRESS
-bool amd_iommu_isolate = false;
-#else
-bool amd_iommu_isolate = true; /* if true, device isolation is
- enabled */
-#endif
-
bool amd_iommu_unmap_flush; /* if true, flush on every unmap */
LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the
system */
+/* Array to assign indices to IOMMUs*/
+struct amd_iommu *amd_iommus[MAX_IOMMUS];
+int amd_iommus_present;
+
+/* IOMMUs have a non-present cache? */
+bool amd_iommu_np_cache __read_mostly;
+
+/*
+ * List of protection domains - used during resume
+ */
+LIST_HEAD(amd_iommu_pd_list);
+spinlock_t amd_iommu_pd_lock;
+
/*
* Pointer to the device table which is shared by all AMD IOMMUs
* it is indexed by the PCI device id or the HT unit id and contains
@@ -157,12 +165,6 @@ u16 *amd_iommu_alias_table;
struct amd_iommu **amd_iommu_rlookup_table;
/*
- * The pd table (protection domain table) is used to find the protection domain
- * data structure a device belongs to. Indexed with the PCI device id too.
- */
-struct protection_domain **amd_iommu_pd_table;
-
-/*
* AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap
* to know which ones are already in use.
*/
@@ -240,7 +242,7 @@ static void iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
}
-static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
+static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
{
u32 ctrl;
@@ -519,6 +521,26 @@ static void set_dev_entry_bit(u16 devid, u8 bit)
amd_iommu_dev_table[devid].data[i] |= (1 << _bit);
}
+static int get_dev_entry_bit(u16 devid, u8 bit)
+{
+ int i = (bit >> 5) & 0x07;
+ int _bit = bit & 0x1f;
+
+ return (amd_iommu_dev_table[devid].data[i] & (1 << _bit)) >> _bit;
+}
+
+
+void amd_iommu_apply_erratum_63(u16 devid)
+{
+ int sysmgt;
+
+ sysmgt = get_dev_entry_bit(devid, DEV_ENTRY_SYSMGT1) |
+ (get_dev_entry_bit(devid, DEV_ENTRY_SYSMGT2) << 1);
+
+ if (sysmgt == 0x01)
+ set_dev_entry_bit(devid, DEV_ENTRY_IW);
+}
+
/* Writes the specific IOMMU for a device into the rlookup table */
static void __init set_iommu_for_device(struct amd_iommu *iommu, u16 devid)
{
@@ -547,6 +569,8 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu,
if (flags & ACPI_DEVFLAG_LINT1)
set_dev_entry_bit(devid, DEV_ENTRY_LINT1_PASS);
+ amd_iommu_apply_erratum_63(devid);
+
set_iommu_for_device(iommu, devid);
}
@@ -816,7 +840,18 @@ static void __init free_iommu_all(void)
static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
{
spin_lock_init(&iommu->lock);
+
+ /* Add IOMMU to internal data structures */
list_add_tail(&iommu->list, &amd_iommu_list);
+ iommu->index = amd_iommus_present++;
+
+ if (unlikely(iommu->index >= MAX_IOMMUS)) {
+ WARN(1, "AMD-Vi: System has more IOMMUs than supported by this driver\n");
+ return -ENOSYS;
+ }
+
+ /* Index is fine - add IOMMU to the array */
+ amd_iommus[iommu->index] = iommu;
/*
* Copy data from ACPI table entry to the iommu struct
@@ -846,6 +881,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
init_iommu_from_acpi(iommu, h);
init_iommu_devices(iommu);
+ if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))
+ amd_iommu_np_cache = true;
+
return pci_enable_device(iommu->dev);
}
@@ -903,7 +941,7 @@ static int __init init_iommu_all(struct acpi_table_header *table)
*
****************************************************************************/
-static int __init iommu_setup_msi(struct amd_iommu *iommu)
+static int iommu_setup_msi(struct amd_iommu *iommu)
{
int r;
@@ -1154,19 +1192,10 @@ static struct sys_device device_amd_iommu = {
* functions. Finally it prints some information about AMD IOMMUs and
* the driver state and enables the hardware.
*/
-int __init amd_iommu_init(void)
+static int __init amd_iommu_init(void)
{
int i, ret = 0;
-
- if (no_iommu) {
- printk(KERN_INFO "AMD-Vi disabled by kernel command line\n");
- return 0;
- }
-
- if (!amd_iommu_detected)
- return -ENODEV;
-
/*
* First parse ACPI tables to find the largest Bus/Dev/Func
* we need to handle. Upon this information the shared data
@@ -1203,15 +1232,6 @@ int __init amd_iommu_init(void)
if (amd_iommu_rlookup_table == NULL)
goto free;
- /*
- * Protection Domain table - maps devices to protection domains
- * This table has the same size as the rlookup_table
- */
- amd_iommu_pd_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
- get_order(rlookup_table_size));
- if (amd_iommu_pd_table == NULL)
- goto free;
-
amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages(
GFP_KERNEL | __GFP_ZERO,
get_order(MAX_DOMAIN_ID/8));
@@ -1233,6 +1253,8 @@ int __init amd_iommu_init(void)
*/
amd_iommu_pd_alloc_bitmap[0] = 1;
+ spin_lock_init(&amd_iommu_pd_lock);
+
/*
* now the data structures are allocated and basically initialized
* start the real acpi table scan
@@ -1264,17 +1286,12 @@ int __init amd_iommu_init(void)
if (iommu_pass_through)
goto out;
- printk(KERN_INFO "AMD-Vi: device isolation ");
- if (amd_iommu_isolate)
- printk("enabled\n");
- else
- printk("disabled\n");
-
if (amd_iommu_unmap_flush)
printk(KERN_INFO "AMD-Vi: IO/TLB flush on unmap enabled\n");
else
printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n");
+ x86_platform.iommu_shutdown = disable_iommus;
out:
return ret;
@@ -1282,9 +1299,6 @@ free:
free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
get_order(MAX_DOMAIN_ID/8));
- free_pages((unsigned long)amd_iommu_pd_table,
- get_order(rlookup_table_size));
-
free_pages((unsigned long)amd_iommu_rlookup_table,
get_order(rlookup_table_size));
@@ -1301,11 +1315,6 @@ free:
goto out;
}
-void amd_iommu_shutdown(void)
-{
- disable_iommus();
-}
-
/****************************************************************************
*
* Early detect code. This code runs at IOMMU detection time in the DMA
@@ -1320,16 +1329,13 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table)
void __init amd_iommu_detect(void)
{
- if (swiotlb || no_iommu || (iommu_detected && !gart_iommu_aperture))
+ if (no_iommu || (iommu_detected && !gart_iommu_aperture))
return;
if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
iommu_detected = 1;
amd_iommu_detected = 1;
-#ifdef CONFIG_GART_IOMMU
- gart_iommu_aperture_disabled = 1;
- gart_iommu_aperture = 0;
-#endif
+ x86_init.iommu.iommu_init = amd_iommu_init;
}
}
@@ -1350,10 +1356,6 @@ static int __init parse_amd_iommu_dump(char *str)
static int __init parse_amd_iommu_options(char *str)
{
for (; *str; ++str) {
- if (strncmp(str, "isolate", 7) == 0)
- amd_iommu_isolate = true;
- if (strncmp(str, "share", 5) == 0)
- amd_iommu_isolate = false;
if (strncmp(str, "fullflush", 9) == 0)
amd_iommu_unmap_flush = true;
}
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 128111d8ffe0..e0dfb6856aa2 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -28,6 +28,7 @@
#include <asm/pci-direct.h>
#include <asm/dma.h>
#include <asm/k8.h>
+#include <asm/x86_init.h>
int gart_iommu_aperture;
int gart_iommu_aperture_disabled __initdata;
@@ -400,6 +401,7 @@ void __init gart_iommu_hole_init(void)
iommu_detected = 1;
gart_iommu_aperture = 1;
+ x86_init.iommu.iommu_init = gart_iommu_init;
aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
aper_size = (32 * 1024 * 1024) << aper_order;
@@ -456,7 +458,7 @@ out:
if (aper_alloc) {
/* Got the aperture from the AGP bridge */
- } else if (swiotlb && !valid_agp) {
+ } else if (!valid_agp) {
/* Do nothing */
} else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) ||
force_iommu ||
diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile
index da7b7b9f8bd8..565c1bfc507d 100644
--- a/arch/x86/kernel/apic/Makefile
+++ b/arch/x86/kernel/apic/Makefile
@@ -2,7 +2,7 @@
# Makefile for local APIC drivers and for the IO-APIC code
#
-obj-$(CONFIG_X86_LOCAL_APIC) += apic.o probe_$(BITS).o ipi.o nmi.o
+obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_noop.o probe_$(BITS).o ipi.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
obj-$(CONFIG_SMP) += ipi.o
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 894aa97f0717..ad8c75b9e453 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -241,28 +241,13 @@ static int modern_apic(void)
}
/*
- * bare function to substitute write operation
- * and it's _that_ fast :)
- */
-static void native_apic_write_dummy(u32 reg, u32 v)
-{
- WARN_ON_ONCE((cpu_has_apic || !disable_apic));
-}
-
-static u32 native_apic_read_dummy(u32 reg)
-{
- WARN_ON_ONCE((cpu_has_apic && !disable_apic));
- return 0;
-}
-
-/*
- * right after this call apic->write/read doesn't do anything
- * note that there is no restore operation it works one way
+ * right after this call apic become NOOP driven
+ * so apic->write/read doesn't do anything
*/
void apic_disable(void)
{
- apic->read = native_apic_read_dummy;
- apic->write = native_apic_write_dummy;
+ pr_info("APIC: switched to apic NOOP\n");
+ apic = &apic_noop;
}
void native_apic_wait_icr_idle(void)
@@ -459,7 +444,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
v = apic_read(APIC_LVTT);
v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
apic_write(APIC_LVTT, v);
- apic_write(APIC_TMICT, 0xffffffff);
+ apic_write(APIC_TMICT, 0);
break;
case CLOCK_EVT_MODE_RESUME:
/* Nothing to do here */
@@ -1392,14 +1377,11 @@ void __init enable_IR_x2apic(void)
unsigned long flags;
struct IO_APIC_route_entry **ioapic_entries = NULL;
int ret, x2apic_enabled = 0;
- int dmar_table_init_ret = 0;
+ int dmar_table_init_ret;
-#ifdef CONFIG_INTR_REMAP
dmar_table_init_ret = dmar_table_init();
- if (dmar_table_init_ret)
- pr_debug("dmar_table_init() failed with %d:\n",
- dmar_table_init_ret);
-#endif
+ if (dmar_table_init_ret && !x2apic_supported())
+ return;
ioapic_entries = alloc_ioapic_entries();
if (!ioapic_entries) {
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c
new file mode 100644
index 000000000000..d9acc3bee0f4
--- /dev/null
+++ b/arch/x86/kernel/apic/apic_noop.c
@@ -0,0 +1,200 @@
+/*
+ * NOOP APIC driver.
+ *
+ * Does almost nothing and should be substituted by a real apic driver via
+ * probe routine.
+ *
+ * Though in case if apic is disabled (for some reason) we try
+ * to not uglify the caller's code and allow to call (some) apic routines
+ * like self-ipi, etc...
+ */
+
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/apicdef.h>
+#include <asm/apic.h>
+#include <asm/setup.h>
+
+#include <linux/smp.h>
+#include <asm/ipi.h>
+
+#include <linux/interrupt.h>
+#include <asm/acpi.h>
+#include <asm/e820.h>
+
+static void noop_init_apic_ldr(void) { }
+static void noop_send_IPI_mask(const struct cpumask *cpumask, int vector) { }
+static void noop_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) { }
+static void noop_send_IPI_allbutself(int vector) { }
+static void noop_send_IPI_all(int vector) { }
+static void noop_send_IPI_self(int vector) { }
+static void noop_apic_wait_icr_idle(void) { }
+static void noop_apic_icr_write(u32 low, u32 id) { }
+
+static int noop_wakeup_secondary_cpu(int apicid, unsigned long start_eip)
+{
+ return -1;
+}
+
+static u32 noop_safe_apic_wait_icr_idle(void)
+{
+ return 0;
+}
+
+static u64 noop_apic_icr_read(void)
+{
+ return 0;
+}
+
+static int noop_cpu_to_logical_apicid(int cpu)
+{
+ return 0;
+}
+
+static int noop_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+ return 0;
+}
+
+static unsigned int noop_get_apic_id(unsigned long x)
+{
+ return 0;
+}
+
+static int noop_probe(void)
+{
+ /*
+ * NOOP apic should not ever be
+ * enabled via probe routine
+ */
+ return 0;
+}
+
+static int noop_apic_id_registered(void)
+{
+ /*
+ * if we would be really "pedantic"
+ * we should pass read_apic_id() here
+ * but since NOOP suppose APIC ID = 0
+ * lets save a few cycles
+ */
+ return physid_isset(0, phys_cpu_present_map);
+}
+
+static const struct cpumask *noop_target_cpus(void)
+{
+ /* only BSP here */
+ return cpumask_of(0);
+}
+
+static unsigned long noop_check_apicid_used(physid_mask_t *map, int apicid)
+{
+ return physid_isset(apicid, *map);
+}
+
+static unsigned long noop_check_apicid_present(int bit)
+{
+ return physid_isset(bit, phys_cpu_present_map);
+}
+
+static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+ if (cpu != 0)
+ pr_warning("APIC: Vector allocated for non-BSP cpu\n");
+ cpumask_clear(retmask);
+ cpumask_set_cpu(cpu, retmask);
+}
+
+int noop_apicid_to_node(int logical_apicid)
+{
+ /* we're always on node 0 */
+ return 0;
+}
+
+static u32 noop_apic_read(u32 reg)
+{
+ WARN_ON_ONCE((cpu_has_apic && !disable_apic));
+ return 0;
+}
+
+static void noop_apic_write(u32 reg, u32 v)
+{
+ WARN_ON_ONCE((cpu_has_apic || !disable_apic));
+}
+
+struct apic apic_noop = {
+ .name = "noop",
+ .probe = noop_probe,
+ .acpi_madt_oem_check = NULL,
+
+ .apic_id_registered = noop_apic_id_registered,
+
+ .irq_delivery_mode = dest_LowestPrio,
+ /* logical delivery broadcast to all CPUs: */
+ .irq_dest_mode = 1,
+
+ .target_cpus = noop_target_cpus,
+ .disable_esr = 0,
+ .dest_logical = APIC_DEST_LOGICAL,
+ .check_apicid_used = noop_check_apicid_used,
+ .check_apicid_present = noop_check_apicid_present,
+
+ .vector_allocation_domain = noop_vector_allocation_domain,
+ .init_apic_ldr = noop_init_apic_ldr,
+
+ .ioapic_phys_id_map = default_ioapic_phys_id_map,
+ .setup_apic_routing = NULL,
+ .multi_timer_check = NULL,
+ .apicid_to_node = noop_apicid_to_node,
+
+ .cpu_to_logical_apicid = noop_cpu_to_logical_apicid,
+ .cpu_present_to_apicid = default_cpu_present_to_apicid,
+ .apicid_to_cpu_present = physid_set_mask_of_physid,
+
+ .setup_portio_remap = NULL,
+ .check_phys_apicid_present = default_check_phys_apicid_present,
+ .enable_apic_mode = NULL,
+
+ .phys_pkg_id = noop_phys_pkg_id,
+
+ .mps_oem_check = NULL,
+
+ .get_apic_id = noop_get_apic_id,
+ .set_apic_id = NULL,
+ .apic_id_mask = 0x0F << 24,
+
+ .cpu_mask_to_apicid = default_cpu_mask_to_apicid,
+ .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
+
+ .send_IPI_mask = noop_send_IPI_mask,
+ .send_IPI_mask_allbutself = noop_send_IPI_mask_allbutself,
+ .send_IPI_allbutself = noop_send_IPI_allbutself,
+ .send_IPI_all = noop_send_IPI_all,
+ .send_IPI_self = noop_send_IPI_self,
+
+ .wakeup_secondary_cpu = noop_wakeup_secondary_cpu,
+
+ /* should be safe */
+ .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW,
+ .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
+
+ .wait_for_init_deassert = NULL,
+
+ .smp_callin_clear_local_apic = NULL,
+ .inquire_remote_apic = NULL,
+
+ .read = noop_apic_read,
+ .write = noop_apic_write,
+ .icr_read = noop_apic_icr_read,
+ .icr_write = noop_apic_icr_write,
+ .wait_icr_idle = noop_apic_wait_icr_idle,
+ .safe_wait_icr_idle = noop_safe_apic_wait_icr_idle,
+};
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index 77a06413b6b2..38dcecfa5818 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -35,7 +35,7 @@ static const struct cpumask *bigsmp_target_cpus(void)
#endif
}
-static unsigned long bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid)
+static unsigned long bigsmp_check_apicid_used(physid_mask_t *map, int apicid)
{
return 0;
}
@@ -93,11 +93,6 @@ static int bigsmp_cpu_present_to_apicid(int mps_cpu)
return BAD_APICID;
}
-static physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid)
-{
- return physid_mask_of_physid(phys_apicid);
-}
-
/* Mapping from cpu number to logical apicid */
static inline int bigsmp_cpu_to_logical_apicid(int cpu)
{
@@ -106,10 +101,10 @@ static inline int bigsmp_cpu_to_logical_apicid(int cpu)
return cpu_physical_id(cpu);
}
-static physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map)
+static void bigsmp_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
{
/* For clustered we don't have a good way to do this yet - hack */
- return physids_promote(0xFFL);
+ physids_promote(0xFFL, retmap);
}
static int bigsmp_check_phys_apicid_present(int phys_apicid)
@@ -230,7 +225,7 @@ struct apic apic_bigsmp = {
.apicid_to_node = bigsmp_apicid_to_node,
.cpu_to_logical_apicid = bigsmp_cpu_to_logical_apicid,
.cpu_present_to_apicid = bigsmp_cpu_present_to_apicid,
- .apicid_to_cpu_present = bigsmp_apicid_to_cpu_present,
+ .apicid_to_cpu_present = physid_set_mask_of_physid,
.setup_portio_remap = NULL,
.check_phys_apicid_present = bigsmp_check_phys_apicid_present,
.enable_apic_mode = NULL,
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index 89174f847b49..e85f8fb7f8e7 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -466,11 +466,11 @@ static const struct cpumask *es7000_target_cpus(void)
return cpumask_of(smp_processor_id());
}
-static unsigned long
-es7000_check_apicid_used(physid_mask_t bitmap, int apicid)
+static unsigned long es7000_check_apicid_used(physid_mask_t *map, int apicid)
{
return 0;
}
+
static unsigned long es7000_check_apicid_present(int bit)
{
return physid_isset(bit, phys_cpu_present_map);
@@ -539,14 +539,10 @@ static int es7000_cpu_present_to_apicid(int mps_cpu)
static int cpu_id;
-static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid)
+static void es7000_apicid_to_cpu_present(int phys_apicid, physid_mask_t *retmap)
{
- physid_mask_t mask;
-
- mask = physid_mask_of_physid(cpu_id);
+ physid_set_mask_of_physid(cpu_id, retmap);
++cpu_id;
-
- return mask;
}
/* Mapping from cpu number to logical apicid */
@@ -561,10 +557,10 @@ static int es7000_cpu_to_logical_apicid(int cpu)
#endif
}
-static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map)
+static void es7000_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
{
/* For clustered we don't have a good way to do this yet - hack */
- return physids_promote(0xff);
+ physids_promote(0xFFL, retmap);
}
static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index dc69f28489f5..c0b4468683f9 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -60,8 +60,6 @@
#include <asm/irq_remapping.h>
#include <asm/hpet.h>
#include <asm/hw_irq.h>
-#include <asm/uv/uv_hub.h>
-#include <asm/uv/uv_irq.h>
#include <asm/apic.h>
@@ -140,20 +138,6 @@ static struct irq_pin_list *get_one_free_irq_2_pin(int node)
return pin;
}
-/*
- * This is performance-critical, we want to do it O(1)
- *
- * Most irqs are mapped 1:1 with pins.
- */
-struct irq_cfg {
- struct irq_pin_list *irq_2_pin;
- cpumask_var_t domain;
- cpumask_var_t old_domain;
- unsigned move_cleanup_count;
- u8 vector;
- u8 move_in_progress : 1;
-};
-
/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
#ifdef CONFIG_SPARSE_IRQ
static struct irq_cfg irq_cfgx[] = {
@@ -209,7 +193,7 @@ int __init arch_early_irq_init(void)
}
#ifdef CONFIG_SPARSE_IRQ
-static struct irq_cfg *irq_cfg(unsigned int irq)
+struct irq_cfg *irq_cfg(unsigned int irq)
{
struct irq_cfg *cfg = NULL;
struct irq_desc *desc;
@@ -361,7 +345,7 @@ void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
/* end for move_irq_desc */
#else
-static struct irq_cfg *irq_cfg(unsigned int irq)
+struct irq_cfg *irq_cfg(unsigned int irq)
{
return irq < nr_irqs ? irq_cfgx + irq : NULL;
}
@@ -555,23 +539,41 @@ static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node,
add_pin_to_irq_node(cfg, node, newapic, newpin);
}
+static void __io_apic_modify_irq(struct irq_pin_list *entry,
+ int mask_and, int mask_or,
+ void (*final)(struct irq_pin_list *entry))
+{
+ unsigned int reg, pin;
+
+ pin = entry->pin;
+ reg = io_apic_read(entry->apic, 0x10 + pin * 2);
+ reg &= mask_and;
+ reg |= mask_or;
+ io_apic_modify(entry->apic, 0x10 + pin * 2, reg);
+ if (final)
+ final(entry);
+}
+
static void io_apic_modify_irq(struct irq_cfg *cfg,
int mask_and, int mask_or,
void (*final)(struct irq_pin_list *entry))
{
- int pin;
struct irq_pin_list *entry;
- for_each_irq_pin(entry, cfg->irq_2_pin) {
- unsigned int reg;
- pin = entry->pin;
- reg = io_apic_read(entry->apic, 0x10 + pin * 2);
- reg &= mask_and;
- reg |= mask_or;
- io_apic_modify(entry->apic, 0x10 + pin * 2, reg);
- if (final)
- final(entry);
- }
+ for_each_irq_pin(entry, cfg->irq_2_pin)
+ __io_apic_modify_irq(entry, mask_and, mask_or, final);
+}
+
+static void __mask_and_edge_IO_APIC_irq(struct irq_pin_list *entry)
+{
+ __io_apic_modify_irq(entry, ~IO_APIC_REDIR_LEVEL_TRIGGER,
+ IO_APIC_REDIR_MASKED, NULL);
+}
+
+static void __unmask_and_level_IO_APIC_irq(struct irq_pin_list *entry)
+{
+ __io_apic_modify_irq(entry, ~IO_APIC_REDIR_MASKED,
+ IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
}
static void __unmask_IO_APIC_irq(struct irq_cfg *cfg)
@@ -595,18 +597,6 @@ static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
}
-static void __mask_and_edge_IO_APIC_irq(struct irq_cfg *cfg)
-{
- io_apic_modify_irq(cfg, ~IO_APIC_REDIR_LEVEL_TRIGGER,
- IO_APIC_REDIR_MASKED, NULL);
-}
-
-static void __unmask_and_level_IO_APIC_irq(struct irq_cfg *cfg)
-{
- io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED,
- IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
-}
-
static void mask_IO_APIC_irq_desc(struct irq_desc *desc)
{
struct irq_cfg *cfg = desc->chip_data;
@@ -1177,7 +1167,7 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
int cpu, err;
cpumask_var_t tmp_mask;
- if ((cfg->move_in_progress) || cfg->move_cleanup_count)
+ if (cfg->move_in_progress)
return -EBUSY;
if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC))
@@ -1237,8 +1227,7 @@ next:
return err;
}
-static int
-assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
+int assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
{
int err;
unsigned long flags;
@@ -1599,9 +1588,6 @@ __apicdebuginit(void) print_IO_APIC(void)
struct irq_desc *desc;
unsigned int irq;
- if (apic_verbosity == APIC_QUIET)
- return;
-
printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
for (i = 0; i < nr_ioapics; i++)
printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
@@ -1708,9 +1694,6 @@ __apicdebuginit(void) print_APIC_field(int base)
{
int i;
- if (apic_verbosity == APIC_QUIET)
- return;
-
printk(KERN_DEBUG);
for (i = 0; i < 8; i++)
@@ -1724,9 +1707,6 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
unsigned int i, v, ver, maxlvt;
u64 icr;
- if (apic_verbosity == APIC_QUIET)
- return;
-
printk(KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
smp_processor_id(), hard_smp_processor_id());
v = apic_read(APIC_ID);
@@ -1824,13 +1804,19 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
printk("\n");
}
-__apicdebuginit(void) print_all_local_APICs(void)
+__apicdebuginit(void) print_local_APICs(int maxcpu)
{
int cpu;
+ if (!maxcpu)
+ return;
+
preempt_disable();
- for_each_online_cpu(cpu)
+ for_each_online_cpu(cpu) {
+ if (cpu >= maxcpu)
+ break;
smp_call_function_single(cpu, print_local_APIC, NULL, 1);
+ }
preempt_enable();
}
@@ -1839,7 +1825,7 @@ __apicdebuginit(void) print_PIC(void)
unsigned int v;
unsigned long flags;
- if (apic_verbosity == APIC_QUIET || !nr_legacy_irqs)
+ if (!nr_legacy_irqs)
return;
printk(KERN_DEBUG "\nprinting PIC contents\n");
@@ -1866,21 +1852,41 @@ __apicdebuginit(void) print_PIC(void)
printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
}
-__apicdebuginit(int) print_all_ICs(void)
+static int __initdata show_lapic = 1;
+static __init int setup_show_lapic(char *arg)
{
+ int num = -1;
+
+ if (strcmp(arg, "all") == 0) {
+ show_lapic = CONFIG_NR_CPUS;
+ } else {
+ get_option(&arg, &num);
+ if (num >= 0)
+ show_lapic = num;
+ }
+
+ return 1;
+}
+__setup("show_lapic=", setup_show_lapic);
+
+__apicdebuginit(int) print_ICs(void)
+{
+ if (apic_verbosity == APIC_QUIET)
+ return 0;
+
print_PIC();
/* don't print out if apic is not there */
if (!cpu_has_apic && !apic_from_smp_config())
return 0;
- print_all_local_APICs();
+ print_local_APICs(show_lapic);
print_IO_APIC();
return 0;
}
-fs_initcall(print_all_ICs);
+fs_initcall(print_ICs);
/* Where if anywhere is the i8259 connect in external int mode */
@@ -2031,7 +2037,7 @@ void __init setup_ioapic_ids_from_mpc(void)
* This is broken; anything with a real cpu count has to
* circumvent this idiocy regardless.
*/
- phys_id_present_map = apic->ioapic_phys_id_map(phys_cpu_present_map);
+ apic->ioapic_phys_id_map(&phys_cpu_present_map, &phys_id_present_map);
/*
* Set the IOAPIC ID to the value stored in the MPC table.
@@ -2058,7 +2064,7 @@ void __init setup_ioapic_ids_from_mpc(void)
* system must have a unique ID or we get lots of nice
* 'stuck on smp_invalidate_needed IPI wait' messages.
*/
- if (apic->check_apicid_used(phys_id_present_map,
+ if (apic->check_apicid_used(&phys_id_present_map,
mp_ioapics[apic_id].apicid)) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
apic_id, mp_ioapics[apic_id].apicid);
@@ -2073,7 +2079,7 @@ void __init setup_ioapic_ids_from_mpc(void)
mp_ioapics[apic_id].apicid = i;
} else {
physid_mask_t tmp;
- tmp = apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid);
+ apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid, &tmp);
apic_printk(APIC_VERBOSE, "Setting %d in the "
"phys_id_present_map\n",
mp_ioapics[apic_id].apicid);
@@ -2228,20 +2234,16 @@ static int ioapic_retrigger_irq(unsigned int irq)
*/
#ifdef CONFIG_SMP
-static void send_cleanup_vector(struct irq_cfg *cfg)
+void send_cleanup_vector(struct irq_cfg *cfg)
{
cpumask_var_t cleanup_mask;
if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) {
unsigned int i;
- cfg->move_cleanup_count = 0;
- for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
- cfg->move_cleanup_count++;
for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR);
} else {
cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask);
- cfg->move_cleanup_count = cpumask_weight(cleanup_mask);
apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
free_cpumask_var(cleanup_mask);
}
@@ -2272,15 +2274,12 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
}
}
-static int
-assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask);
-
/*
* Either sets desc->affinity to a valid value, and returns
* ->cpu_mask_to_apicid of that, or returns BAD_APICID and
* leaves desc->affinity untouched.
*/
-static unsigned int
+unsigned int
set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
{
struct irq_cfg *cfg;
@@ -2433,8 +2432,6 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
cfg = irq_cfg(irq);
spin_lock(&desc->lock);
- if (!cfg->move_cleanup_count)
- goto unlock;
if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
goto unlock;
@@ -2452,7 +2449,6 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
goto unlock;
}
__get_cpu_var(vector_irq)[vector] = -1;
- cfg->move_cleanup_count--;
unlock:
spin_unlock(&desc->lock);
}
@@ -2460,21 +2456,33 @@ unlock:
irq_exit();
}
-static void irq_complete_move(struct irq_desc **descp)
+static void __irq_complete_move(struct irq_desc **descp, unsigned vector)
{
struct irq_desc *desc = *descp;
struct irq_cfg *cfg = desc->chip_data;
- unsigned vector, me;
+ unsigned me;
if (likely(!cfg->move_in_progress))
return;
- vector = ~get_irq_regs()->orig_ax;
me = smp_processor_id();
if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
send_cleanup_vector(cfg);
}
+
+static void irq_complete_move(struct irq_desc **descp)
+{
+ __irq_complete_move(descp, ~get_irq_regs()->orig_ax);
+}
+
+void irq_force_complete_move(int irq)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_cfg *cfg = desc->chip_data;
+
+ __irq_complete_move(&desc, cfg->vector);
+}
#else
static inline void irq_complete_move(struct irq_desc **descp) {}
#endif
@@ -2490,6 +2498,59 @@ static void ack_apic_edge(unsigned int irq)
atomic_t irq_mis_count;
+/*
+ * IO-APIC versions below 0x20 don't support EOI register.
+ * For the record, here is the information about various versions:
+ * 0Xh 82489DX
+ * 1Xh I/OAPIC or I/O(x)APIC which are not PCI 2.2 Compliant
+ * 2Xh I/O(x)APIC which is PCI 2.2 Compliant
+ * 30h-FFh Reserved
+ *
+ * Some of the Intel ICH Specs (ICH2 to ICH5) documents the io-apic
+ * version as 0x2. This is an error with documentation and these ICH chips
+ * use io-apic's of version 0x20.
+ *
+ * For IO-APIC's with EOI register, we use that to do an explicit EOI.
+ * Otherwise, we simulate the EOI message manually by changing the trigger
+ * mode to edge and then back to level, with RTE being masked during this.
+*/
+static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
+{
+ struct irq_pin_list *entry;
+
+ for_each_irq_pin(entry, cfg->irq_2_pin) {
+ if (mp_ioapics[entry->apic].apicver >= 0x20) {
+ /*
+ * Intr-remapping uses pin number as the virtual vector
+ * in the RTE. Actual vector is programmed in
+ * intr-remapping table entry. Hence for the io-apic
+ * EOI we use the pin number.
+ */
+ if (irq_remapped(irq))
+ io_apic_eoi(entry->apic, entry->pin);
+ else
+ io_apic_eoi(entry->apic, cfg->vector);
+ } else {
+ __mask_and_edge_IO_APIC_irq(entry);
+ __unmask_and_level_IO_APIC_irq(entry);
+ }
+ }
+}
+
+static void eoi_ioapic_irq(struct irq_desc *desc)
+{
+ struct irq_cfg *cfg;
+ unsigned long flags;
+ unsigned int irq;
+
+ irq = desc->irq;
+ cfg = desc->chip_data;
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+ __eoi_ioapic_irq(irq, cfg);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
static void ack_apic_level(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
@@ -2525,6 +2586,19 @@ static void ack_apic_level(unsigned int irq)
* level-triggered interrupt. We mask the source for the time of the
* operation to prevent an edge-triggered interrupt escaping meanwhile.
* The idea is from Manfred Spraul. --macro
+ *
+ * Also in the case when cpu goes offline, fixup_irqs() will forward
+ * any unhandled interrupt on the offlined cpu to the new cpu
+ * destination that is handling the corresponding interrupt. This
+ * interrupt forwarding is done via IPI's. Hence, in this case also
+ * level-triggered io-apic interrupt will be seen as an edge
+ * interrupt in the IRR. And we can't rely on the cpu's EOI
+ * to be broadcasted to the IO-APIC's which will clear the remoteIRR
+ * corresponding to the level-triggered interrupt. Hence on IO-APIC's
+ * supporting EOI register, we do an explicit EOI to clear the
+ * remote IRR and on IO-APIC's which don't have an EOI register,
+ * we use the above logic (mask+edge followed by unmask+level) from
+ * Manfred Spraul to clear the remote IRR.
*/
cfg = desc->chip_data;
i = cfg->vector;
@@ -2536,6 +2610,19 @@ static void ack_apic_level(unsigned int irq)
*/
ack_APIC_irq();
+ /*
+ * Tail end of clearing remote IRR bit (either by delivering the EOI
+ * message via io-apic EOI register write or simulating it using
+ * mask+edge followed by unnask+level logic) manually when the
+ * level triggered interrupt is seen as the edge triggered interrupt
+ * at the cpu.
+ */
+ if (!(v & (1 << (i & 0x1f)))) {
+ atomic_inc(&irq_mis_count);
+
+ eoi_ioapic_irq(desc);
+ }
+
/* Now we can move and renable the irq */
if (unlikely(do_unmask_irq)) {
/* Only migrate the irq if the ack has been received.
@@ -2569,41 +2656,9 @@ static void ack_apic_level(unsigned int irq)
move_masked_irq(irq);
unmask_IO_APIC_irq_desc(desc);
}
-
- /* Tail end of version 0x11 I/O APIC bug workaround */
- if (!(v & (1 << (i & 0x1f)))) {
- atomic_inc(&irq_mis_count);
- spin_lock(&ioapic_lock);
- __mask_and_edge_IO_APIC_irq(cfg);
- __unmask_and_level_IO_APIC_irq(cfg);
- spin_unlock(&ioapic_lock);
- }
}
#ifdef CONFIG_INTR_REMAP
-static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
-{
- struct irq_pin_list *entry;
-
- for_each_irq_pin(entry, cfg->irq_2_pin)
- io_apic_eoi(entry->apic, entry->pin);
-}
-
-static void
-eoi_ioapic_irq(struct irq_desc *desc)
-{
- struct irq_cfg *cfg;
- unsigned long flags;
- unsigned int irq;
-
- irq = desc->irq;
- cfg = desc->chip_data;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- __eoi_ioapic_irq(irq, cfg);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
static void ir_ack_apic_edge(unsigned int irq)
{
ack_APIC_irq();
@@ -3157,6 +3212,7 @@ unsigned int create_irq_nr(unsigned int irq_want, int node)
continue;
desc_new = move_irq_desc(desc_new, node);
+ cfg_new = desc_new->chip_data;
if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
irq = new;
@@ -3708,75 +3764,6 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
}
#endif /* CONFIG_HT_IRQ */
-#ifdef CONFIG_X86_UV
-/*
- * Re-target the irq to the specified CPU and enable the specified MMR located
- * on the specified blade to allow the sending of MSIs to the specified CPU.
- */
-int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
- unsigned long mmr_offset)
-{
- const struct cpumask *eligible_cpu = cpumask_of(cpu);
- struct irq_cfg *cfg;
- int mmr_pnode;
- unsigned long mmr_value;
- struct uv_IO_APIC_route_entry *entry;
- unsigned long flags;
- int err;
-
- BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
- cfg = irq_cfg(irq);
-
- err = assign_irq_vector(irq, cfg, eligible_cpu);
- if (err != 0)
- return err;
-
- spin_lock_irqsave(&vector_lock, flags);
- set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
- irq_name);
- spin_unlock_irqrestore(&vector_lock, flags);
-
- mmr_value = 0;
- entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
- entry->vector = cfg->vector;
- entry->delivery_mode = apic->irq_delivery_mode;
- entry->dest_mode = apic->irq_dest_mode;
- entry->polarity = 0;
- entry->trigger = 0;
- entry->mask = 0;
- entry->dest = apic->cpu_mask_to_apicid(eligible_cpu);
-
- mmr_pnode = uv_blade_to_pnode(mmr_blade);
- uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
-
- if (cfg->move_in_progress)
- send_cleanup_vector(cfg);
-
- return irq;
-}
-
-/*
- * Disable the specified MMR located on the specified blade so that MSIs are
- * longer allowed to be sent.
- */
-void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset)
-{
- unsigned long mmr_value;
- struct uv_IO_APIC_route_entry *entry;
- int mmr_pnode;
-
- BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
- mmr_value = 0;
- entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
- entry->mask = 1;
-
- mmr_pnode = uv_blade_to_pnode(mmr_blade);
- uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
-}
-#endif /* CONFIG_X86_64 */
-
int __init io_apic_get_redir_entries (int ioapic)
{
union IO_APIC_reg_01 reg_01;
@@ -3944,7 +3931,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id)
*/
if (physids_empty(apic_id_map))
- apic_id_map = apic->ioapic_phys_id_map(phys_cpu_present_map);
+ apic->ioapic_phys_id_map(&phys_cpu_present_map, &apic_id_map);
spin_lock_irqsave(&ioapic_lock, flags);
reg_00.raw = io_apic_read(ioapic, 0);
@@ -3960,10 +3947,10 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id)
* Every APIC in a system must have a unique ID or we get lots of nice
* 'stuck on smp_invalidate_needed IPI wait' messages.
*/
- if (apic->check_apicid_used(apic_id_map, apic_id)) {
+ if (apic->check_apicid_used(&apic_id_map, apic_id)) {
for (i = 0; i < get_physical_broadcast(); i++) {
- if (!apic->check_apicid_used(apic_id_map, i))
+ if (!apic->check_apicid_used(&apic_id_map, i))
break;
}
@@ -3976,7 +3963,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id)
apic_id = i;
}
- tmp = apic->apicid_to_cpu_present(apic_id);
+ apic->apicid_to_cpu_present(apic_id, &tmp);
physids_or(apic_id_map, apic_id_map, tmp);
if (reg_00.bits.ID != apic_id) {
@@ -4106,7 +4093,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics)
for (i = 0; i < nr_ioapics; i++) {
res[i].name = mem;
res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- sprintf(mem, "IOAPIC %u", i);
+ snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
mem += IOAPIC_RESOURCE_NAME_SIZE;
}
@@ -4140,18 +4127,17 @@ void __init ioapic_init_mappings(void)
#ifdef CONFIG_X86_32
fake_ioapic_page:
#endif
- ioapic_phys = (unsigned long)
- alloc_bootmem_pages(PAGE_SIZE);
+ ioapic_phys = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
ioapic_phys = __pa(ioapic_phys);
}
set_fixmap_nocache(idx, ioapic_phys);
- apic_printk(APIC_VERBOSE,
- "mapped IOAPIC to %08lx (%08lx)\n",
- __fix_to_virt(idx), ioapic_phys);
+ apic_printk(APIC_VERBOSE, "mapped IOAPIC to %08lx (%08lx)\n",
+ __fix_to_virt(idx) + (ioapic_phys & ~PAGE_MASK),
+ ioapic_phys);
idx++;
ioapic_res->start = ioapic_phys;
- ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
+ ioapic_res->end = ioapic_phys + IO_APIC_SLOT_SIZE - 1;
ioapic_res++;
}
}
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index 7ff61d6a188a..6389432a9dbf 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -39,7 +39,8 @@
int unknown_nmi_panic;
int nmi_watchdog_enabled;
-static cpumask_t backtrace_mask __read_mostly;
+/* For reliability, we're prepared to waste bits here. */
+static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly;
/* nmi_active:
* >0: the lapic NMI watchdog is active, but can be disabled
@@ -414,7 +415,7 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
}
/* We can be called before check_nmi_watchdog, hence NULL check. */
- if (cpumask_test_cpu(cpu, &backtrace_mask)) {
+ if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
static DEFINE_SPINLOCK(lock); /* Serialise the printks */
spin_lock(&lock);
@@ -422,7 +423,7 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
show_regs(regs);
dump_stack();
spin_unlock(&lock);
- cpumask_clear_cpu(cpu, &backtrace_mask);
+ cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
rc = 1;
}
@@ -558,14 +559,14 @@ void arch_trigger_all_cpu_backtrace(void)
{
int i;
- cpumask_copy(&backtrace_mask, cpu_online_mask);
+ cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask);
printk(KERN_INFO "sending NMI to all CPUs:\n");
apic->send_IPI_all(NMI_VECTOR);
/* Wait for up to 10 seconds for all CPUs to do the backtrace */
for (i = 0; i < 10 * 1000; i++) {
- if (cpumask_empty(&backtrace_mask))
+ if (cpumask_empty(to_cpumask(backtrace_mask)))
break;
mdelay(1);
}
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
index efa00e2b8505..07cdbdcd7a92 100644
--- a/arch/x86/kernel/apic/numaq_32.c
+++ b/arch/x86/kernel/apic/numaq_32.c
@@ -334,10 +334,9 @@ static inline const struct cpumask *numaq_target_cpus(void)
return cpu_all_mask;
}
-static inline unsigned long
-numaq_check_apicid_used(physid_mask_t bitmap, int apicid)
+static unsigned long numaq_check_apicid_used(physid_mask_t *map, int apicid)
{
- return physid_isset(apicid, bitmap);
+ return physid_isset(apicid, *map);
}
static inline unsigned long numaq_check_apicid_present(int bit)
@@ -371,10 +370,10 @@ static inline int numaq_multi_timer_check(int apic, int irq)
return apic != 0 && irq == 0;
}
-static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map)
+static inline void numaq_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
{
/* We don't have a good way to do this yet - hack */
- return physids_promote(0xFUL);
+ return physids_promote(0xFUL, retmap);
}
static inline int numaq_cpu_to_logical_apicid(int cpu)
@@ -402,12 +401,12 @@ static inline int numaq_apicid_to_node(int logical_apicid)
return logical_apicid >> 4;
}
-static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid)
+static void numaq_apicid_to_cpu_present(int logical_apicid, physid_mask_t *retmap)
{
int node = numaq_apicid_to_node(logical_apicid);
int cpu = __ffs(logical_apicid & 0xf);
- return physid_mask_of_physid(cpu + 4*node);
+ physid_set_mask_of_physid(cpu + 4*node, retmap);
}
/* Where the IO area was mapped on multiquad, always 0 otherwise */
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 0c0182cc947d..1a6559f6768c 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -108,7 +108,7 @@ struct apic apic_default = {
.apicid_to_node = default_apicid_to_node,
.cpu_to_logical_apicid = default_cpu_to_logical_apicid,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .apicid_to_cpu_present = default_apicid_to_cpu_present,
+ .apicid_to_cpu_present = physid_set_mask_of_physid,
.setup_portio_remap = NULL,
.check_phys_apicid_present = default_check_phys_apicid_present,
.enable_apic_mode = NULL,
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
index 645ecc4ff0be..9b419263d90d 100644
--- a/arch/x86/kernel/apic/summit_32.c
+++ b/arch/x86/kernel/apic/summit_32.c
@@ -183,7 +183,7 @@ static const struct cpumask *summit_target_cpus(void)
return cpumask_of(0);
}
-static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid)
+static unsigned long summit_check_apicid_used(physid_mask_t *map, int apicid)
{
return 0;
}
@@ -261,15 +261,15 @@ static int summit_cpu_present_to_apicid(int mps_cpu)
return BAD_APICID;
}
-static physid_mask_t summit_ioapic_phys_id_map(physid_mask_t phys_id_map)
+static void summit_ioapic_phys_id_map(physid_mask_t *phys_id_map, physid_mask_t *retmap)
{
/* For clustered we don't have a good way to do this yet - hack */
- return physids_promote(0x0F);
+ physids_promote(0x0FL, retmap);
}
-static physid_mask_t summit_apicid_to_cpu_present(int apicid)
+static void summit_apicid_to_cpu_present(int apicid, physid_mask_t *retmap)
{
- return physid_mask_of_physid(0);
+ physid_set_mask_of_physid(0, retmap);
}
static int summit_check_phys_apicid_present(int physical_apicid)
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index f5f5886a6b53..130c4b934877 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -352,14 +352,14 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) {
alias.v = uv_read_local_mmr(redir_addrs[i].alias);
- if (alias.s.base == 0) {
+ if (alias.s.enable && alias.s.base == 0) {
*size = (1UL << alias.s.m_alias);
redirect.v = uv_read_local_mmr(redir_addrs[i].redirect);
*base = (unsigned long)redirect.s.dest_base << DEST_SHIFT;
return;
}
}
- BUG();
+ *base = *size = 0;
}
enum map_type {map_wb, map_uc};
@@ -409,6 +409,12 @@ static __init void map_mmioh_high(int max_pnode)
map_high("MMIOH", mmioh.s.base, shift, max_pnode, map_uc);
}
+static __init void map_low_mmrs(void)
+{
+ init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE);
+ init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE);
+}
+
static __init void uv_rtc_init(void)
{
long status;
@@ -550,6 +556,8 @@ void __init uv_system_init(void)
unsigned long mmr_base, present, paddr;
unsigned short pnode_mask;
+ map_low_mmrs();
+
m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG);
m_val = m_n_config.s.m_skt;
n_val = m_n_config.s.n_skt;
@@ -619,12 +627,12 @@ void __init uv_system_init(void)
uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base;
uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size;
uv_cpu_hub_info(cpu)->m_val = m_val;
- uv_cpu_hub_info(cpu)->n_val = m_val;
+ uv_cpu_hub_info(cpu)->n_val = n_val;
uv_cpu_hub_info(cpu)->numa_blade_id = blade;
uv_cpu_hub_info(cpu)->blade_processor_id = lcpu;
uv_cpu_hub_info(cpu)->pnode = pnode;
uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask;
- uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
+ uv_cpu_hub_info(cpu)->gpa_mask = (1UL << (m_val + n_val)) - 1;
uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 151ace69a5aa..b5b6b23bce53 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -204,7 +204,6 @@
#include <linux/module.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/timer.h>
@@ -403,6 +402,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
static struct apm_user *user_list;
static DEFINE_SPINLOCK(user_list_lock);
+static DEFINE_MUTEX(apm_mutex);
/*
* Set up a segment that references the real mode segment 0x40
@@ -1531,7 +1531,7 @@ static long do_ioctl(struct file *filp, u_int cmd, u_long arg)
return -EPERM;
switch (cmd) {
case APM_IOC_STANDBY:
- lock_kernel();
+ mutex_lock(&apm_mutex);
if (as->standbys_read > 0) {
as->standbys_read--;
as->standbys_pending--;
@@ -1540,10 +1540,10 @@ static long do_ioctl(struct file *filp, u_int cmd, u_long arg)
queue_event(APM_USER_STANDBY, as);
if (standbys_pending <= 0)
standby();
- unlock_kernel();
+ mutex_unlock(&apm_mutex);
break;
case APM_IOC_SUSPEND:
- lock_kernel();
+ mutex_lock(&apm_mutex);
if (as->suspends_read > 0) {
as->suspends_read--;
as->suspends_pending--;
@@ -1552,13 +1552,14 @@ static long do_ioctl(struct file *filp, u_int cmd, u_long arg)
queue_event(APM_USER_SUSPEND, as);
if (suspends_pending <= 0) {
ret = suspend(1);
+ mutex_unlock(&apm_mutex);
} else {
as->suspend_wait = 1;
+ mutex_unlock(&apm_mutex);
wait_event_interruptible(apm_suspend_waitqueue,
as->suspend_wait == 0);
ret = as->suspend_result;
}
- unlock_kernel();
return ret;
default:
return -ENOTTY;
@@ -1608,12 +1609,10 @@ static int do_open(struct inode *inode, struct file *filp)
{
struct apm_user *as;
- lock_kernel();
as = kmalloc(sizeof(*as), GFP_KERNEL);
if (as == NULL) {
printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
sizeof(*as));
- unlock_kernel();
return -ENOMEM;
}
as->magic = APM_BIOS_MAGIC;
@@ -1635,7 +1634,6 @@ static int do_open(struct inode *inode, struct file *filp)
user_list = as;
spin_unlock(&user_list_lock);
filp->private_data = as;
- unlock_kernel();
return 0;
}
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 68537e957a9b..1d2cb383410e 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -5,6 +5,7 @@
# Don't trace early stages of a secondary CPU boot
ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_common.o = -pg
+CFLAGS_REMOVE_perf_event.o = -pg
endif
# Make sure load_percpu_segment has no stackprotector
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index c910a716a71c..7128b3799cec 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -535,7 +535,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
}
}
- display_cacheinfo(c);
+ cpu_detect_cache_sizes(c);
/* Multi core CPU? */
if (c->extended_cpuid_level >= 0x80000008) {
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index c95e831bb095..e58d978e0758 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -294,7 +294,7 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_REP_GOOD);
}
- display_cacheinfo(c);
+ cpu_detect_cache_sizes(c);
}
enum {
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index cc25c2b4a567..a4ec8b647544 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -61,7 +61,7 @@ void __init setup_cpu_local_masks(void)
static void __cpuinit default_init(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_X86_64
- display_cacheinfo(c);
+ cpu_detect_cache_sizes(c);
#else
/* Not much we can do here... */
/* Check if at least it has cpuid */
@@ -383,7 +383,7 @@ static void __cpuinit get_model_name(struct cpuinfo_x86 *c)
}
}
-void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
+void __cpuinit cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
{
unsigned int n, dummy, ebx, ecx, edx, l2size;
@@ -391,8 +391,6 @@ void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
if (n >= 0x80000005) {
cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
- printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
- edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
c->x86_cache_size = (ecx>>24) + (edx>>24);
#ifdef CONFIG_X86_64
/* On K8 L1 TLB is inclusive, so don't count it */
@@ -422,9 +420,6 @@ void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
#endif
c->x86_cache_size = l2size;
-
- printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
- l2size, ecx & 0xFF);
}
void __cpuinit detect_ht(struct cpuinfo_x86 *c)
@@ -659,24 +654,31 @@ void __init early_cpu_init(void)
const struct cpu_dev *const *cdev;
int count = 0;
+#ifdef PROCESSOR_SELECT
printk(KERN_INFO "KERNEL supported cpus:\n");
+#endif
+
for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) {
const struct cpu_dev *cpudev = *cdev;
- unsigned int j;
if (count >= X86_VENDOR_NUM)
break;
cpu_devs[count] = cpudev;
count++;
- for (j = 0; j < 2; j++) {
- if (!cpudev->c_ident[j])
- continue;
- printk(KERN_INFO " %s %s\n", cpudev->c_vendor,
- cpudev->c_ident[j]);
+#ifdef PROCESSOR_SELECT
+ {
+ unsigned int j;
+
+ for (j = 0; j < 2; j++) {
+ if (!cpudev->c_ident[j])
+ continue;
+ printk(KERN_INFO " %s %s\n", cpudev->c_vendor,
+ cpudev->c_ident[j]);
+ }
}
+#endif
}
-
early_identify_cpu(&boot_cpu_data);
}
@@ -837,10 +839,8 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
}
-#ifdef CONFIG_X86_MCE
/* Init Machine Check Exception if available. */
- mcheck_init(c);
-#endif
+ mcheck_cpu_init(c);
select_idle_routine(c);
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index 6de9a908e400..3624e8a0f71b 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -32,6 +32,6 @@ struct cpu_dev {
extern const struct cpu_dev *const __x86_cpu_dev_start[],
*const __x86_cpu_dev_end[];
-extern void display_cacheinfo(struct cpuinfo_x86 *c);
+extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
#endif
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 7d5c3b0ea8da..8b581d3905cb 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -526,15 +526,21 @@ static const struct dmi_system_id sw_any_bug_dmi_table[] = {
static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
{
- /* http://www.intel.com/Assets/PDF/specupdate/314554.pdf
+ /* Intel Xeon Processor 7100 Series Specification Update
+ * http://www.intel.com/Assets/PDF/specupdate/314554.pdf
* AL30: A Machine Check Exception (MCE) Occurring during an
* Enhanced Intel SpeedStep Technology Ratio Change May Cause
- * Both Processor Cores to Lock Up when HT is enabled*/
+ * Both Processor Cores to Lock Up. */
if (c->x86_vendor == X86_VENDOR_INTEL) {
if ((c->x86 == 15) &&
(c->x86_model == 6) &&
- (c->x86_mask == 8) && smt_capable())
+ (c->x86_mask == 8)) {
+ printk(KERN_INFO "acpi-cpufreq: Intel(R) "
+ "Xeon(R) 7100 Errata AL30, processors may "
+ "lock up on frequency changes: disabling "
+ "acpi-cpufreq.\n");
return -ENODEV;
+ }
}
return 0;
}
@@ -549,13 +555,18 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
unsigned int result = 0;
struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
struct acpi_processor_performance *perf;
+#ifdef CONFIG_SMP
+ static int blacklisted;
+#endif
dprintk("acpi_cpufreq_cpu_init\n");
#ifdef CONFIG_SMP
- result = acpi_cpufreq_blacklist(c);
- if (result)
- return result;
+ if (blacklisted)
+ return blacklisted;
+ blacklisted = acpi_cpufreq_blacklist(c);
+ if (blacklisted)
+ return blacklisted;
#endif
data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index ce2ed3e4aad9..cabd2fa3fc93 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -813,7 +813,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr));
break;
case 1 ... 15:
- longhaul_version = TYPE_LONGHAUL_V1;
+ longhaul_version = TYPE_LONGHAUL_V2;
if (c->x86_mask < 8) {
cpu_model = CPU_SAMUEL2;
cpuname = "C3 'Samuel 2' [C5B]";
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 6394aa5c7985..3f12dabeab52 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -1022,7 +1022,7 @@ static int get_transition_latency(struct powernow_k8_data *data)
* set it to 1 to avoid problems in the future.
* For all others it's a BIOS bug.
*/
- if (!boot_cpu_data.x86 == 0x11)
+ if (boot_cpu_data.x86 != 0x11)
printk(KERN_ERR FW_WARN PFX "Invalid zero transition "
"latency\n");
max_latency = 1;
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index 6911e91fb4f6..3ae5a7a3a500 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -232,28 +232,23 @@ static unsigned int speedstep_detect_chipset(void)
return 0;
}
-struct get_freq_data {
- unsigned int speed;
- unsigned int processor;
-};
-
-static void get_freq_data(void *_data)
+static void get_freq_data(void *_speed)
{
- struct get_freq_data *data = _data;
+ unsigned int *speed = _speed;
- data->speed = speedstep_get_frequency(data->processor);
+ *speed = speedstep_get_frequency(speedstep_processor);
}
static unsigned int speedstep_get(unsigned int cpu)
{
- struct get_freq_data data = { .processor = cpu };
+ unsigned int speed;
/* You're supposed to ensure CPU is online. */
- if (smp_call_function_single(cpu, get_freq_data, &data, 1) != 0)
+ if (smp_call_function_single(cpu, get_freq_data, &speed, 1) != 0)
BUG();
- dprintk("detected %u kHz as current frequency\n", data.speed);
- return data.speed;
+ dprintk("detected %u kHz as current frequency\n", speed);
+ return speed;
}
/**
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index 19807b89f058..4fbd384fb645 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -373,7 +373,7 @@ static void __cpuinit init_nsc(struct cpuinfo_x86 *c)
/* Handle the GX (Formally known as the GX2) */
if (c->x86 == 5 && c->x86_model == 5)
- display_cacheinfo(c);
+ cpu_detect_cache_sizes(c);
else
init_cyrix(c);
}
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 804c40e2bc3e..0df4c2b7107f 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -488,22 +488,6 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
#endif
}
- if (trace)
- printk(KERN_INFO "CPU: Trace cache: %dK uops", trace);
- else if (l1i)
- printk(KERN_INFO "CPU: L1 I cache: %dK", l1i);
-
- if (l1d)
- printk(KERN_CONT ", L1 D cache: %dK\n", l1d);
- else
- printk(KERN_CONT "\n");
-
- if (l2)
- printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
-
- if (l3)
- printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
-
c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
return l2;
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index b1598a9436d0..0bcaa3875863 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -46,6 +46,9 @@
#include "mce-internal.h"
+#define CREATE_TRACE_POINTS
+#include <trace/events/mce.h>
+
int mce_disabled __read_mostly;
#define MISC_MCELOG_MINOR 227
@@ -85,18 +88,26 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
static DEFINE_PER_CPU(struct mce, mces_seen);
static int cpu_missing;
-static void default_decode_mce(struct mce *m)
+/*
+ * CPU/chipset specific EDAC code can register a notifier call here to print
+ * MCE errors in a human-readable form.
+ */
+ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain);
+EXPORT_SYMBOL_GPL(x86_mce_decoder_chain);
+
+static int default_decode_mce(struct notifier_block *nb, unsigned long val,
+ void *data)
{
pr_emerg("No human readable MCE decoding support on this CPU type.\n");
pr_emerg("Run the message through 'mcelog --ascii' to decode.\n");
+
+ return NOTIFY_STOP;
}
-/*
- * CPU/chipset specific EDAC code can register a callback here to print
- * MCE errors in a human-readable form:
- */
-void (*x86_mce_decode_callback)(struct mce *m) = default_decode_mce;
-EXPORT_SYMBOL(x86_mce_decode_callback);
+static struct notifier_block mce_dec_nb = {
+ .notifier_call = default_decode_mce,
+ .priority = -1,
+};
/* MCA banks polled by the period polling timer for corrected events */
DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
@@ -141,6 +152,9 @@ void mce_log(struct mce *mce)
{
unsigned next, entry;
+ /* Emit the trace record: */
+ trace_mce_record(mce);
+
mce->finished = 0;
wmb();
for (;;) {
@@ -204,9 +218,9 @@ static void print_mce(struct mce *m)
/*
* Print out human-readable details about the MCE error,
- * (if the CPU has an implementation for that):
+ * (if the CPU has an implementation for that)
*/
- x86_mce_decode_callback(m);
+ atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
}
static void print_mce_head(void)
@@ -1122,7 +1136,7 @@ static int check_interval = 5 * 60; /* 5 minutes */
static DEFINE_PER_CPU(int, mce_next_interval); /* in jiffies */
static DEFINE_PER_CPU(struct timer_list, mce_timer);
-static void mcheck_timer(unsigned long data)
+static void mce_start_timer(unsigned long data)
{
struct timer_list *t = &per_cpu(mce_timer, data);
int *n;
@@ -1187,7 +1201,7 @@ int mce_notify_irq(void)
}
EXPORT_SYMBOL_GPL(mce_notify_irq);
-static int mce_banks_init(void)
+static int __cpuinit __mcheck_cpu_mce_banks_init(void)
{
int i;
@@ -1206,7 +1220,7 @@ static int mce_banks_init(void)
/*
* Initialize Machine Checks for a CPU.
*/
-static int __cpuinit mce_cap_init(void)
+static int __cpuinit __mcheck_cpu_cap_init(void)
{
unsigned b;
u64 cap;
@@ -1214,7 +1228,8 @@ static int __cpuinit mce_cap_init(void)
rdmsrl(MSR_IA32_MCG_CAP, cap);
b = cap & MCG_BANKCNT_MASK;
- printk(KERN_INFO "mce: CPU supports %d MCE banks\n", b);
+ if (!banks)
+ printk(KERN_INFO "mce: CPU supports %d MCE banks\n", b);
if (b > MAX_NR_BANKS) {
printk(KERN_WARNING
@@ -1227,7 +1242,7 @@ static int __cpuinit mce_cap_init(void)
WARN_ON(banks != 0 && b != banks);
banks = b;
if (!mce_banks) {
- int err = mce_banks_init();
+ int err = __mcheck_cpu_mce_banks_init();
if (err)
return err;
@@ -1243,7 +1258,7 @@ static int __cpuinit mce_cap_init(void)
return 0;
}
-static void mce_init(void)
+static void __mcheck_cpu_init_generic(void)
{
mce_banks_t all_banks;
u64 cap;
@@ -1272,7 +1287,7 @@ static void mce_init(void)
}
/* Add per CPU specific workarounds here */
-static int __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c)
+static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
{
if (c->x86_vendor == X86_VENDOR_UNKNOWN) {
pr_info("MCE: unknown CPU type - not enabling MCE support.\n");
@@ -1340,7 +1355,7 @@ static int __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c)
return 0;
}
-static void __cpuinit mce_ancient_init(struct cpuinfo_x86 *c)
+static void __cpuinit __mcheck_cpu_ancient_init(struct cpuinfo_x86 *c)
{
if (c->x86 != 5)
return;
@@ -1354,7 +1369,7 @@ static void __cpuinit mce_ancient_init(struct cpuinfo_x86 *c)
}
}
-static void mce_cpu_features(struct cpuinfo_x86 *c)
+static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
{
switch (c->x86_vendor) {
case X86_VENDOR_INTEL:
@@ -1368,7 +1383,7 @@ static void mce_cpu_features(struct cpuinfo_x86 *c)
}
}
-static void mce_init_timer(void)
+static void __mcheck_cpu_init_timer(void)
{
struct timer_list *t = &__get_cpu_var(mce_timer);
int *n = &__get_cpu_var(mce_next_interval);
@@ -1379,7 +1394,7 @@ static void mce_init_timer(void)
*n = check_interval * HZ;
if (!*n)
return;
- setup_timer(t, mcheck_timer, smp_processor_id());
+ setup_timer(t, mce_start_timer, smp_processor_id());
t->expires = round_jiffies(jiffies + *n);
add_timer_on(t, smp_processor_id());
}
@@ -1399,27 +1414,28 @@ void (*machine_check_vector)(struct pt_regs *, long error_code) =
* Called for each booted CPU to set up machine checks.
* Must be called with preempt off:
*/
-void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
+void __cpuinit mcheck_cpu_init(struct cpuinfo_x86 *c)
{
if (mce_disabled)
return;
- mce_ancient_init(c);
+ __mcheck_cpu_ancient_init(c);
if (!mce_available(c))
return;
- if (mce_cap_init() < 0 || mce_cpu_quirks(c) < 0) {
+ if (__mcheck_cpu_cap_init() < 0 || __mcheck_cpu_apply_quirks(c) < 0) {
mce_disabled = 1;
return;
}
machine_check_vector = do_machine_check;
- mce_init();
- mce_cpu_features(c);
- mce_init_timer();
+ __mcheck_cpu_init_generic();
+ __mcheck_cpu_init_vendor(c);
+ __mcheck_cpu_init_timer();
INIT_WORK(&__get_cpu_var(mce_work), mce_process_work);
+
}
/*
@@ -1639,6 +1655,15 @@ static int __init mcheck_enable(char *str)
}
__setup("mce", mcheck_enable);
+int __init mcheck_init(void)
+{
+ atomic_notifier_chain_register(&x86_mce_decoder_chain, &mce_dec_nb);
+
+ mcheck_intel_therm_init();
+
+ return 0;
+}
+
/*
* Sysfs support
*/
@@ -1647,7 +1672,7 @@ __setup("mce", mcheck_enable);
* Disable machine checks on suspend and shutdown. We can't really handle
* them later.
*/
-static int mce_disable(void)
+static int mce_disable_error_reporting(void)
{
int i;
@@ -1662,12 +1687,12 @@ static int mce_disable(void)
static int mce_suspend(struct sys_device *dev, pm_message_t state)
{
- return mce_disable();
+ return mce_disable_error_reporting();
}
static int mce_shutdown(struct sys_device *dev)
{
- return mce_disable();
+ return mce_disable_error_reporting();
}
/*
@@ -1677,8 +1702,8 @@ static int mce_shutdown(struct sys_device *dev)
*/
static int mce_resume(struct sys_device *dev)
{
- mce_init();
- mce_cpu_features(&current_cpu_data);
+ __mcheck_cpu_init_generic();
+ __mcheck_cpu_init_vendor(&current_cpu_data);
return 0;
}
@@ -1688,8 +1713,8 @@ static void mce_cpu_restart(void *data)
del_timer_sync(&__get_cpu_var(mce_timer));
if (!mce_available(&current_cpu_data))
return;
- mce_init();
- mce_init_timer();
+ __mcheck_cpu_init_generic();
+ __mcheck_cpu_init_timer();
}
/* Reinit MCEs after user configuration changes */
@@ -1715,7 +1740,7 @@ static void mce_enable_ce(void *all)
cmci_reenable();
cmci_recheck();
if (all)
- mce_init_timer();
+ __mcheck_cpu_init_timer();
}
static struct sysdev_class mce_sysclass = {
@@ -1928,13 +1953,14 @@ static __cpuinit void mce_remove_device(unsigned int cpu)
}
/* Make sure there are no machine checks on offlined CPUs. */
-static void mce_disable_cpu(void *h)
+static void __cpuinit mce_disable_cpu(void *h)
{
unsigned long action = *(unsigned long *)h;
int i;
if (!mce_available(&current_cpu_data))
return;
+
if (!(action & CPU_TASKS_FROZEN))
cmci_clear();
for (i = 0; i < banks; i++) {
@@ -1945,7 +1971,7 @@ static void mce_disable_cpu(void *h)
}
}
-static void mce_reenable_cpu(void *h)
+static void __cpuinit mce_reenable_cpu(void *h)
{
unsigned long action = *(unsigned long *)h;
int i;
@@ -2024,7 +2050,7 @@ static __init void mce_init_banks(void)
}
}
-static __init int mce_init_device(void)
+static __init int mcheck_init_device(void)
{
int err;
int i = 0;
@@ -2052,7 +2078,7 @@ static __init int mce_init_device(void)
return err;
}
-device_initcall(mce_init_device);
+device_initcall(mcheck_init_device);
/*
* Old style boot options parsing. Only for compatibility.
@@ -2100,7 +2126,7 @@ static int fake_panic_set(void *data, u64 val)
DEFINE_SIMPLE_ATTRIBUTE(fake_panic_fops, fake_panic_get,
fake_panic_set, "%llu\n");
-static int __init mce_debugfs_init(void)
+static int __init mcheck_debugfs_init(void)
{
struct dentry *dmce, *ffake_panic;
@@ -2114,5 +2140,5 @@ static int __init mce_debugfs_init(void)
return 0;
}
-late_initcall(mce_debugfs_init);
+late_initcall(mcheck_debugfs_init);
#endif
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index b3a1dba75330..4fef985fc221 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -49,6 +49,8 @@ static DEFINE_PER_CPU(struct thermal_state, thermal_state);
static atomic_t therm_throt_en = ATOMIC_INIT(0);
+static u32 lvtthmr_init __read_mostly;
+
#ifdef CONFIG_SYSFS
#define define_therm_throt_sysdev_one_ro(_name) \
static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL)
@@ -254,6 +256,18 @@ asmlinkage void smp_thermal_interrupt(struct pt_regs *regs)
ack_APIC_irq();
}
+void __init mcheck_intel_therm_init(void)
+{
+ /*
+ * This function is only called on boot CPU. Save the init thermal
+ * LVT value on BSP and use that value to restore APs' thermal LVT
+ * entry BIOS programmed later
+ */
+ if (cpu_has(&boot_cpu_data, X86_FEATURE_ACPI) &&
+ cpu_has(&boot_cpu_data, X86_FEATURE_ACC))
+ lvtthmr_init = apic_read(APIC_LVTTHMR);
+}
+
void intel_init_thermal(struct cpuinfo_x86 *c)
{
unsigned int cpu = smp_processor_id();
@@ -270,7 +284,20 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
* since it might be delivered via SMI already:
*/
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
- h = apic_read(APIC_LVTTHMR);
+
+ /*
+ * The initial value of thermal LVT entries on all APs always reads
+ * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI
+ * sequence to them and LVT registers are reset to 0s except for
+ * the mask bits which are set to 1s when APs receive INIT IPI.
+ * Always restore the value that BIOS has programmed on AP based on
+ * BSP's info we saved since BIOS is always setting the same value
+ * for all threads/cores
+ */
+ apic_write(APIC_LVTTHMR, lvtthmr_init);
+
+ h = lvtthmr_init;
+
if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
printk(KERN_DEBUG
"CPU%d: Thermal monitoring handled by SMI\n", cpu);
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
index 315738c74aad..73c86db5acbe 100644
--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -846,7 +846,7 @@ int __init mtrr_cleanup(unsigned address_bits)
sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
range_sums = sum_ranges(range, nr_range);
- printk(KERN_INFO "total RAM coverred: %ldM\n",
+ printk(KERN_INFO "total RAM covered: %ldM\n",
range_sums >> (20 - PAGE_SHIFT));
if (mtrr_chunk_size && mtrr_gran_size) {
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index b5801c311846..c1bbed1021d9 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -77,6 +77,18 @@ struct cpu_hw_events {
struct debug_store *ds;
};
+struct event_constraint {
+ unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ int code;
+};
+
+#define EVENT_CONSTRAINT(c, m) { .code = (c), .idxmsk[0] = (m) }
+#define EVENT_CONSTRAINT_END { .code = 0, .idxmsk[0] = 0 }
+
+#define for_each_event_constraint(e, c) \
+ for ((e) = (c); (e)->idxmsk[0]; (e)++)
+
+
/*
* struct x86_pmu - generic x86 pmu
*/
@@ -102,6 +114,8 @@ struct x86_pmu {
u64 intel_ctrl;
void (*enable_bts)(u64 config);
void (*disable_bts)(void);
+ int (*get_event_idx)(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *hwc);
};
static struct x86_pmu x86_pmu __read_mostly;
@@ -110,6 +124,8 @@ static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
.enabled = 1,
};
+static const struct event_constraint *event_constraints;
+
/*
* Not sure about some of these
*/
@@ -155,6 +171,16 @@ static u64 p6_pmu_raw_event(u64 hw_event)
return hw_event & P6_EVNTSEL_MASK;
}
+static const struct event_constraint intel_p6_event_constraints[] =
+{
+ EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */
+ EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
+ EVENT_CONSTRAINT(0x11, 0x1), /* FP_ASSIST */
+ EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
+ EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
+ EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
+ EVENT_CONSTRAINT_END
+};
/*
* Intel PerfMon v3. Used on Core2 and later.
@@ -170,6 +196,35 @@ static const u64 intel_perfmon_event_map[] =
[PERF_COUNT_HW_BUS_CYCLES] = 0x013c,
};
+static const struct event_constraint intel_core_event_constraints[] =
+{
+ EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
+ EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
+ EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
+ EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
+ EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
+ EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */
+ EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
+ EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */
+ EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */
+ EVENT_CONSTRAINT_END
+};
+
+static const struct event_constraint intel_nehalem_event_constraints[] =
+{
+ EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */
+ EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */
+ EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */
+ EVENT_CONSTRAINT(0x43, 0x3), /* L1D_ALL_REF */
+ EVENT_CONSTRAINT(0x4e, 0x3), /* L1D_PREFETCH */
+ EVENT_CONSTRAINT(0x4c, 0x3), /* LOAD_HIT_PRE */
+ EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
+ EVENT_CONSTRAINT(0x52, 0x3), /* L1D_CACHE_PREFETCH_LOCK_FB_HIT */
+ EVENT_CONSTRAINT(0x53, 0x3), /* L1D_CACHE_LOCK_FB_HIT */
+ EVENT_CONSTRAINT(0xc5, 0x3), /* CACHE_LOCK_CYCLES */
+ EVENT_CONSTRAINT_END
+};
+
static u64 intel_pmu_event_map(int hw_event)
{
return intel_perfmon_event_map[hw_event];
@@ -190,7 +245,7 @@ static u64 __read_mostly hw_cache_event_ids
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX];
-static const u64 nehalem_hw_cache_event_ids
+static __initconst u64 nehalem_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -281,7 +336,7 @@ static const u64 nehalem_hw_cache_event_ids
},
};
-static const u64 core2_hw_cache_event_ids
+static __initconst u64 core2_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -372,7 +427,7 @@ static const u64 core2_hw_cache_event_ids
},
};
-static const u64 atom_hw_cache_event_ids
+static __initconst u64 atom_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -469,7 +524,7 @@ static u64 intel_pmu_raw_event(u64 hw_event)
#define CORE_EVNTSEL_UNIT_MASK 0x0000FF00ULL
#define CORE_EVNTSEL_EDGE_MASK 0x00040000ULL
#define CORE_EVNTSEL_INV_MASK 0x00800000ULL
-#define CORE_EVNTSEL_REG_MASK 0xFF000000ULL
+#define CORE_EVNTSEL_REG_MASK 0xFF000000ULL
#define CORE_EVNTSEL_MASK \
(CORE_EVNTSEL_EVENT_MASK | \
@@ -481,7 +536,7 @@ static u64 intel_pmu_raw_event(u64 hw_event)
return hw_event & CORE_EVNTSEL_MASK;
}
-static const u64 amd_hw_cache_event_ids
+static __initconst u64 amd_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -932,6 +987,8 @@ static int __hw_perf_event_init(struct perf_event *event)
*/
hwc->config = ARCH_PERFMON_EVENTSEL_INT;
+ hwc->idx = -1;
+
/*
* Count user and OS events unless requested not to.
*/
@@ -1334,8 +1391,7 @@ static void amd_pmu_enable_event(struct hw_perf_event *hwc, int idx)
x86_pmu_enable_event(hwc, idx);
}
-static int
-fixed_mode_idx(struct perf_event *event, struct hw_perf_event *hwc)
+static int fixed_mode_idx(struct hw_perf_event *hwc)
{
unsigned int hw_event;
@@ -1349,6 +1405,12 @@ fixed_mode_idx(struct perf_event *event, struct hw_perf_event *hwc)
if (!x86_pmu.num_events_fixed)
return -1;
+ /*
+ * fixed counters do not take all possible filters
+ */
+ if (hwc->config & ARCH_PERFMON_EVENT_FILTER_MASK)
+ return -1;
+
if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS)))
return X86_PMC_IDX_FIXED_INSTRUCTIONS;
if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES)))
@@ -1360,22 +1422,57 @@ fixed_mode_idx(struct perf_event *event, struct hw_perf_event *hwc)
}
/*
- * Find a PMC slot for the freshly enabled / scheduled in event:
+ * generic counter allocator: get next free counter
*/
-static int x86_pmu_enable(struct perf_event *event)
+static int
+gen_get_event_idx(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
+{
+ int idx;
+
+ idx = find_first_zero_bit(cpuc->used_mask, x86_pmu.num_events);
+ return idx == x86_pmu.num_events ? -1 : idx;
+}
+
+/*
+ * intel-specific counter allocator: check event constraints
+ */
+static int
+intel_get_event_idx(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
+{
+ const struct event_constraint *event_constraint;
+ int i, code;
+
+ if (!event_constraints)
+ goto skip;
+
+ code = hwc->config & CORE_EVNTSEL_EVENT_MASK;
+
+ for_each_event_constraint(event_constraint, event_constraints) {
+ if (code == event_constraint->code) {
+ for_each_bit(i, event_constraint->idxmsk, X86_PMC_IDX_MAX) {
+ if (!test_and_set_bit(i, cpuc->used_mask))
+ return i;
+ }
+ return -1;
+ }
+ }
+skip:
+ return gen_get_event_idx(cpuc, hwc);
+}
+
+static int
+x86_schedule_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
int idx;
- idx = fixed_mode_idx(event, hwc);
+ idx = fixed_mode_idx(hwc);
if (idx == X86_PMC_IDX_FIXED_BTS) {
/* BTS is already occupied. */
if (test_and_set_bit(idx, cpuc->used_mask))
return -EAGAIN;
hwc->config_base = 0;
- hwc->event_base = 0;
+ hwc->event_base = 0;
hwc->idx = idx;
} else if (idx >= 0) {
/*
@@ -1396,20 +1493,35 @@ static int x86_pmu_enable(struct perf_event *event)
} else {
idx = hwc->idx;
/* Try to get the previous generic event again */
- if (test_and_set_bit(idx, cpuc->used_mask)) {
+ if (idx == -1 || test_and_set_bit(idx, cpuc->used_mask)) {
try_generic:
- idx = find_first_zero_bit(cpuc->used_mask,
- x86_pmu.num_events);
- if (idx == x86_pmu.num_events)
+ idx = x86_pmu.get_event_idx(cpuc, hwc);
+ if (idx == -1)
return -EAGAIN;
set_bit(idx, cpuc->used_mask);
hwc->idx = idx;
}
- hwc->config_base = x86_pmu.eventsel;
- hwc->event_base = x86_pmu.perfctr;
+ hwc->config_base = x86_pmu.eventsel;
+ hwc->event_base = x86_pmu.perfctr;
}
+ return idx;
+}
+
+/*
+ * Find a PMC slot for the freshly enabled / scheduled in event:
+ */
+static int x86_pmu_enable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx;
+
+ idx = x86_schedule_event(cpuc, hwc);
+ if (idx < 0)
+ return idx;
+
perf_events_lapic_init();
x86_pmu.disable(hwc, idx);
@@ -1852,7 +1964,7 @@ static __read_mostly struct notifier_block perf_event_nmi_notifier = {
.priority = 1
};
-static struct x86_pmu p6_pmu = {
+static __initconst struct x86_pmu p6_pmu = {
.name = "p6",
.handle_irq = p6_pmu_handle_irq,
.disable_all = p6_pmu_disable_all,
@@ -1877,9 +1989,10 @@ static struct x86_pmu p6_pmu = {
*/
.event_bits = 32,
.event_mask = (1ULL << 32) - 1,
+ .get_event_idx = intel_get_event_idx,
};
-static struct x86_pmu intel_pmu = {
+static __initconst struct x86_pmu intel_pmu = {
.name = "Intel",
.handle_irq = intel_pmu_handle_irq,
.disable_all = intel_pmu_disable_all,
@@ -1900,9 +2013,10 @@ static struct x86_pmu intel_pmu = {
.max_period = (1ULL << 31) - 1,
.enable_bts = intel_pmu_enable_bts,
.disable_bts = intel_pmu_disable_bts,
+ .get_event_idx = intel_get_event_idx,
};
-static struct x86_pmu amd_pmu = {
+static __initconst struct x86_pmu amd_pmu = {
.name = "AMD",
.handle_irq = amd_pmu_handle_irq,
.disable_all = amd_pmu_disable_all,
@@ -1920,9 +2034,10 @@ static struct x86_pmu amd_pmu = {
.apic = 1,
/* use highest bit to detect overflow */
.max_period = (1ULL << 47) - 1,
+ .get_event_idx = gen_get_event_idx,
};
-static int p6_pmu_init(void)
+static __init int p6_pmu_init(void)
{
switch (boot_cpu_data.x86_model) {
case 1:
@@ -1932,10 +2047,12 @@ static int p6_pmu_init(void)
case 7:
case 8:
case 11: /* Pentium III */
+ event_constraints = intel_p6_event_constraints;
break;
case 9:
case 13:
/* Pentium M */
+ event_constraints = intel_p6_event_constraints;
break;
default:
pr_cont("unsupported p6 CPU model %d ",
@@ -1954,7 +2071,7 @@ static int p6_pmu_init(void)
return 0;
}
-static int intel_pmu_init(void)
+static __init int intel_pmu_init(void)
{
union cpuid10_edx edx;
union cpuid10_eax eax;
@@ -2007,12 +2124,14 @@ static int intel_pmu_init(void)
sizeof(hw_cache_event_ids));
pr_cont("Core2 events, ");
+ event_constraints = intel_core_event_constraints;
break;
default:
case 26:
memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
+ event_constraints = intel_nehalem_event_constraints;
pr_cont("Nehalem/Corei7 events, ");
break;
case 28:
@@ -2025,7 +2144,7 @@ static int intel_pmu_init(void)
return 0;
}
-static int amd_pmu_init(void)
+static __init int amd_pmu_init(void)
{
/* Performance-monitoring supported from K7 and later: */
if (boot_cpu_data.x86 < 6)
@@ -2105,11 +2224,47 @@ static const struct pmu pmu = {
.unthrottle = x86_pmu_unthrottle,
};
+static int
+validate_event(struct cpu_hw_events *cpuc, struct perf_event *event)
+{
+ struct hw_perf_event fake_event = event->hw;
+
+ if (event->pmu && event->pmu != &pmu)
+ return 0;
+
+ return x86_schedule_event(cpuc, &fake_event) >= 0;
+}
+
+static int validate_group(struct perf_event *event)
+{
+ struct perf_event *sibling, *leader = event->group_leader;
+ struct cpu_hw_events fake_pmu;
+
+ memset(&fake_pmu, 0, sizeof(fake_pmu));
+
+ if (!validate_event(&fake_pmu, leader))
+ return -ENOSPC;
+
+ list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ if (!validate_event(&fake_pmu, sibling))
+ return -ENOSPC;
+ }
+
+ if (!validate_event(&fake_pmu, event))
+ return -ENOSPC;
+
+ return 0;
+}
+
const struct pmu *hw_perf_event_init(struct perf_event *event)
{
int err;
err = __hw_perf_event_init(event);
+ if (!err) {
+ if (event->group_leader != event)
+ err = validate_group(event);
+ }
if (err) {
if (event->destroy)
event->destroy(event);
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index fab786f60ed6..898df9719afb 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -712,7 +712,7 @@ static void probe_nmi_watchdog(void)
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD:
if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 &&
- boot_cpu_data.x86 != 16)
+ boot_cpu_data.x86 != 16 && boot_cpu_data.x86 != 17)
return;
wd_ops = &k7_wd_ops;
break;
diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c
index bb62b3e5caad..28000743bbb0 100644
--- a/arch/x86/kernel/cpu/transmeta.c
+++ b/arch/x86/kernel/cpu/transmeta.c
@@ -26,7 +26,7 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c)
early_init_transmeta(c);
- display_cacheinfo(c);
+ cpu_detect_cache_sizes(c);
/* Print CMS and CPU revision */
max = cpuid_eax(0x80860000);
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index 6a52d4b36a30..7ef24a796992 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -116,21 +116,16 @@ static int cpuid_open(struct inode *inode, struct file *file)
{
unsigned int cpu;
struct cpuinfo_x86 *c;
- int ret = 0;
-
- lock_kernel();
cpu = iminor(file->f_path.dentry->d_inode);
- if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
- ret = -ENXIO; /* No such CPU */
- goto out;
- }
+ if (cpu >= nr_cpu_ids || !cpu_online(cpu))
+ return -ENXIO; /* No such CPU */
+
c = &cpu_data(cpu);
if (c->cpuid_level < 0)
- ret = -EIO; /* CPUID not supported */
-out:
- unlock_kernel();
- return ret;
+ return -EIO; /* CPUID not supported */
+
+ return 0;
}
/*
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 5e409dc298a4..a4849c10a77e 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -27,8 +27,7 @@
#include <asm/cpu.h>
#include <asm/reboot.h>
#include <asm/virtext.h>
-#include <asm/iommu.h>
-
+#include <asm/x86_init.h>
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
@@ -106,7 +105,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
#endif
#ifdef CONFIG_X86_64
- pci_iommu_shutdown();
+ x86_platform.iommu_shutdown();
#endif
crash_save_cpu(regs, safe_smp_processor_id());
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c
index f7cdb3b457aa..cd97ce18c29d 100644
--- a/arch/x86/kernel/crash_dump_32.c
+++ b/arch/x86/kernel/crash_dump_32.c
@@ -16,6 +16,22 @@ static void *kdump_buf_page;
/* Stores the physical address of elf header of crash image. */
unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+static inline bool is_crashed_pfn_valid(unsigned long pfn)
+{
+#ifndef CONFIG_X86_PAE
+ /*
+ * non-PAE kdump kernel executed from a PAE one will crop high pte
+ * bits and poke unwanted space counting again from address 0, we
+ * don't want that. pte must fit into unsigned long. In fact the
+ * test checks high 12 bits for being zero (pfn will be shifted left
+ * by PAGE_SHIFT).
+ */
+ return pte_pfn(pfn_pte(pfn, __pgprot(0))) == pfn;
+#else
+ return true;
+#endif
+}
+
/**
* copy_oldmem_page - copy one page from "oldmem"
* @pfn: page frame number to be copied
@@ -41,6 +57,9 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
if (!csize)
return 0;
+ if (!is_crashed_pfn_valid(pfn))
+ return -EFAULT;
+
vaddr = kmap_atomic_pfn(pfn, KM_PTE0);
if (!userbuf) {
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 2d8a371d4339..b8ce165dde5d 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -268,11 +268,12 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
show_registers(regs);
#ifdef CONFIG_X86_32
- sp = (unsigned long) (&regs->sp);
- savesegment(ss, ss);
- if (user_mode(regs)) {
+ if (user_mode_vm(regs)) {
sp = regs->sp;
ss = regs->ss & 0xffff;
+ } else {
+ sp = kernel_stack_pointer(regs);
+ savesegment(ss, ss);
}
printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
print_symbol("%s", regs->ip);
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index f7dd2a7c3bf4..e0ed4c7abb62 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -10,9 +10,9 @@
#include <linux/module.h>
#include <linux/ptrace.h>
#include <linux/kexec.h>
+#include <linux/sysfs.h>
#include <linux/bug.h>
#include <linux/nmi.h>
-#include <linux/sysfs.h>
#include <asm/stacktrace.h>
@@ -35,6 +35,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
if (!stack) {
unsigned long dummy;
+
stack = &dummy;
if (task && task != current)
stack = (unsigned long *)task->thread.sp;
@@ -57,8 +58,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
context = (struct thread_info *)
((unsigned long)stack & (~(THREAD_SIZE - 1)));
- bp = print_context_stack(context, stack, bp, ops,
- data, NULL, &graph);
+ bp = print_context_stack(context, stack, bp, ops, data, NULL, &graph);
stack = (unsigned long *)context->previous_esp;
if (!stack)
@@ -72,7 +72,7 @@ EXPORT_SYMBOL(dump_trace);
void
show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
- unsigned long *sp, unsigned long bp, char *log_lvl)
+ unsigned long *sp, unsigned long bp, char *log_lvl)
{
unsigned long *stack;
int i;
@@ -156,4 +156,3 @@ int is_valid_bugaddr(unsigned long ip)
return ud2 == 0x0b0f;
}
-
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index a071e6be177e..8e740934bd1f 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -10,26 +10,28 @@
#include <linux/module.h>
#include <linux/ptrace.h>
#include <linux/kexec.h>
+#include <linux/sysfs.h>
#include <linux/bug.h>
#include <linux/nmi.h>
-#include <linux/sysfs.h>
#include <asm/stacktrace.h>
#include "dumpstack.h"
+#define N_EXCEPTION_STACKS_END \
+ (N_EXCEPTION_STACKS + DEBUG_STKSZ/EXCEPTION_STKSZ - 2)
static char x86_stack_ids[][8] = {
- [DEBUG_STACK - 1] = "#DB",
- [NMI_STACK - 1] = "NMI",
- [DOUBLEFAULT_STACK - 1] = "#DF",
- [STACKFAULT_STACK - 1] = "#SS",
- [MCE_STACK - 1] = "#MC",
+ [ DEBUG_STACK-1 ] = "#DB",
+ [ NMI_STACK-1 ] = "NMI",
+ [ DOUBLEFAULT_STACK-1 ] = "#DF",
+ [ STACKFAULT_STACK-1 ] = "#SS",
+ [ MCE_STACK-1 ] = "#MC",
#if DEBUG_STKSZ > EXCEPTION_STKSZ
- [N_EXCEPTION_STACKS ...
- N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
+ [ N_EXCEPTION_STACKS ...
+ N_EXCEPTION_STACKS_END ] = "#DB[?]"
#endif
- };
+};
int x86_is_stack_id(int id, char *name)
{
@@ -37,7 +39,7 @@ int x86_is_stack_id(int id, char *name)
}
static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
- unsigned *usedp, char **idp)
+ unsigned *usedp, char **idp)
{
unsigned k;
@@ -202,21 +204,24 @@ EXPORT_SYMBOL(dump_trace);
void
show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
- unsigned long *sp, unsigned long bp, char *log_lvl)
+ unsigned long *sp, unsigned long bp, char *log_lvl)
{
+ unsigned long *irq_stack_end;
+ unsigned long *irq_stack;
unsigned long *stack;
+ int cpu;
int i;
- const int cpu = smp_processor_id();
- unsigned long *irq_stack_end =
- (unsigned long *)(per_cpu(irq_stack_ptr, cpu));
- unsigned long *irq_stack =
- (unsigned long *)(per_cpu(irq_stack_ptr, cpu) - IRQ_STACK_SIZE);
+
+ preempt_disable();
+ cpu = smp_processor_id();
+
+ irq_stack_end = (unsigned long *)(per_cpu(irq_stack_ptr, cpu));
+ irq_stack = (unsigned long *)(per_cpu(irq_stack_ptr, cpu) - IRQ_STACK_SIZE);
/*
- * debugging aid: "show_stack(NULL, NULL);" prints the
- * back trace for this cpu.
+ * Debugging aid: "show_stack(NULL, NULL);" prints the
+ * back trace for this cpu:
*/
-
if (sp == NULL) {
if (task)
sp = (unsigned long *)task->thread.sp;
@@ -240,6 +245,8 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
printk(" %016lx", *stack++);
touch_nmi_watchdog();
}
+ preempt_enable();
+
printk("\n");
show_trace_log_lvl(task, regs, sp, bp, log_lvl);
}
@@ -303,4 +310,3 @@ int is_valid_bugaddr(unsigned long ip)
return ud2 == 0x0b0f;
}
-
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c
index ad5bd988fb79..cdcfb122f256 100644
--- a/arch/x86/kernel/efi.c
+++ b/arch/x86/kernel/efi.c
@@ -454,8 +454,10 @@ void __init efi_init(void)
if (add_efi_memmap)
do_add_efi_memmap();
+#ifdef CONFIG_X86_32
x86_platform.get_wallclock = efi_get_time;
x86_platform.set_wallclock = efi_set_rtc_mmss;
+#endif
/* Setup for EFI runtime service */
reboot_type = BOOT_EFI;
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index c097e7d607c6..50b9c220e121 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -334,6 +334,10 @@ ENTRY(ret_from_fork)
END(ret_from_fork)
/*
+ * Interrupt exit functions should be protected against kprobes
+ */
+ .pushsection .kprobes.text, "ax"
+/*
* Return to user mode is not as complex as all this looks,
* but we want the default path for a system call return to
* go as quickly as possible which is why some of this is
@@ -383,6 +387,10 @@ need_resched:
END(resume_kernel)
#endif
CFI_ENDPROC
+/*
+ * End of kprobes section
+ */
+ .popsection
/* SYSENTER_RETURN points to after the "sysenter" instruction in
the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */
@@ -513,6 +521,10 @@ sysexit_audit:
PTGS_TO_GS_EX
ENDPROC(ia32_sysenter_target)
+/*
+ * syscall stub including irq exit should be protected against kprobes
+ */
+ .pushsection .kprobes.text, "ax"
# system call handler stub
ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway
@@ -705,6 +717,10 @@ syscall_badsys:
jmp resume_userspace
END(syscall_badsys)
CFI_ENDPROC
+/*
+ * End of kprobes section
+ */
+ .popsection
/*
* System calls that need a pt_regs pointer.
@@ -814,6 +830,10 @@ common_interrupt:
ENDPROC(common_interrupt)
CFI_ENDPROC
+/*
+ * Irq entries should be protected against kprobes
+ */
+ .pushsection .kprobes.text, "ax"
#define BUILD_INTERRUPT3(name, nr, fn) \
ENTRY(name) \
RING0_INT_FRAME; \
@@ -980,6 +1000,10 @@ ENTRY(spurious_interrupt_bug)
jmp error_code
CFI_ENDPROC
END(spurious_interrupt_bug)
+/*
+ * End of kprobes section
+ */
+ .popsection
ENTRY(kernel_thread_helper)
pushl $0 # fake return address for unwinder
@@ -1185,17 +1209,14 @@ END(ftrace_graph_caller)
.globl return_to_handler
return_to_handler:
- pushl $0
pushl %eax
- pushl %ecx
pushl %edx
movl %ebp, %eax
call ftrace_return_to_handler
- movl %eax, 0xc(%esp)
+ movl %eax, %ecx
popl %edx
- popl %ecx
popl %eax
- ret
+ jmp *%ecx
#endif
.section .rodata,"a"
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index b5c061f8f358..4deb8fc849dd 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -155,11 +155,11 @@ GLOBAL(return_to_handler)
call ftrace_return_to_handler
- movq %rax, 16(%rsp)
+ movq %rax, %rdi
movq 8(%rsp), %rdx
movq (%rsp), %rax
- addq $16, %rsp
- retq
+ addq $24, %rsp
+ jmp *%rdi
#endif
@@ -803,6 +803,10 @@ END(interrupt)
call \func
.endm
+/*
+ * Interrupt entry/exit should be protected against kprobes
+ */
+ .pushsection .kprobes.text, "ax"
/*
* The interrupt stubs push (~vector+0x80) onto the stack and
* then jump to common_interrupt.
@@ -941,6 +945,10 @@ ENTRY(retint_kernel)
CFI_ENDPROC
END(common_interrupt)
+/*
+ * End of kprobes section
+ */
+ .popsection
/*
* APIC interrupts.
@@ -1491,12 +1499,17 @@ error_kernelspace:
leaq irq_return(%rip),%rcx
cmpq %rcx,RIP+8(%rsp)
je error_swapgs
- movl %ecx,%ecx /* zero extend */
- cmpq %rcx,RIP+8(%rsp)
- je error_swapgs
+ movl %ecx,%eax /* zero extend */
+ cmpq %rax,RIP+8(%rsp)
+ je bstep_iret
cmpq $gs_change,RIP+8(%rsp)
je error_swapgs
jmp error_sti
+
+bstep_iret:
+ /* Fix truncated RIP */
+ movq %rcx,RIP+8(%rsp)
+ jmp error_swapgs
END(error_entry)
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 9dbb527e1652..5a1b9758fd62 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -9,6 +9,8 @@
* the dangers of modifying code on the run.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/spinlock.h>
#include <linux/hardirq.h>
#include <linux/uaccess.h>
@@ -336,15 +338,15 @@ int __init ftrace_dyn_arch_init(void *data)
switch (faulted) {
case 0:
- pr_info("ftrace: converting mcount calls to 0f 1f 44 00 00\n");
+ pr_info("converting mcount calls to 0f 1f 44 00 00\n");
memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE);
break;
case 1:
- pr_info("ftrace: converting mcount calls to 66 66 66 66 90\n");
+ pr_info("converting mcount calls to 66 66 66 66 90\n");
memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE);
break;
case 2:
- pr_info("ftrace: converting mcount calls to jmp . + 5\n");
+ pr_info("converting mcount calls to jmp . + 5\n");
memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE);
break;
}
@@ -468,82 +470,10 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
#ifdef CONFIG_FTRACE_SYSCALLS
-extern unsigned long __start_syscalls_metadata[];
-extern unsigned long __stop_syscalls_metadata[];
extern unsigned long *sys_call_table;
-static struct syscall_metadata **syscalls_metadata;
-
-static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
-{
- struct syscall_metadata *start;
- struct syscall_metadata *stop;
- char str[KSYM_SYMBOL_LEN];
-
-
- start = (struct syscall_metadata *)__start_syscalls_metadata;
- stop = (struct syscall_metadata *)__stop_syscalls_metadata;
- kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
-
- for ( ; start < stop; start++) {
- if (start->name && !strcmp(start->name, str))
- return start;
- }
- return NULL;
-}
-
-struct syscall_metadata *syscall_nr_to_meta(int nr)
-{
- if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
- return NULL;
-
- return syscalls_metadata[nr];
-}
-
-int syscall_name_to_nr(char *name)
+unsigned long __init arch_syscall_addr(int nr)
{
- int i;
-
- if (!syscalls_metadata)
- return -1;
-
- for (i = 0; i < NR_syscalls; i++) {
- if (syscalls_metadata[i]) {
- if (!strcmp(syscalls_metadata[i]->name, name))
- return i;
- }
- }
- return -1;
-}
-
-void set_syscall_enter_id(int num, int id)
-{
- syscalls_metadata[num]->enter_id = id;
-}
-
-void set_syscall_exit_id(int num, int id)
-{
- syscalls_metadata[num]->exit_id = id;
-}
-
-static int __init arch_init_ftrace_syscalls(void)
-{
- int i;
- struct syscall_metadata *meta;
- unsigned long **psys_syscall_table = &sys_call_table;
-
- syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
- NR_syscalls, GFP_KERNEL);
- if (!syscalls_metadata) {
- WARN_ON(1);
- return -ENOMEM;
- }
-
- for (i = 0; i < NR_syscalls; i++) {
- meta = find_syscall_meta(psys_syscall_table[i]);
- syscalls_metadata[i] = meta;
- }
- return 0;
+ return (unsigned long)(&sys_call_table)[nr];
}
-arch_initcall(arch_init_ftrace_syscalls);
#endif
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 780cd928fcd5..22db86a37643 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -212,8 +212,8 @@ ENTRY(secondary_startup_64)
*/
lgdt early_gdt_descr(%rip)
- /* set up data segments. actually 0 would do too */
- movl $__KERNEL_DS,%eax
+ /* set up data segments */
+ xorl %eax,%eax
movl %eax,%ds
movl %eax,%ss
movl %eax,%es
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
new file mode 100644
index 000000000000..d42f65ac4927
--- /dev/null
+++ b/arch/x86/kernel/hw_breakpoint.c
@@ -0,0 +1,555 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2007 Alan Stern
+ * Copyright (C) 2009 IBM Corporation
+ * Copyright (C) 2009 Frederic Weisbecker <fweisbec@gmail.com>
+ *
+ * Authors: Alan Stern <stern@rowland.harvard.edu>
+ * K.Prasad <prasad@linux.vnet.ibm.com>
+ * Frederic Weisbecker <fweisbec@gmail.com>
+ */
+
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/hw_breakpoint.h>
+#include <linux/irqflags.h>
+#include <linux/notifier.h>
+#include <linux/kallsyms.h>
+#include <linux/kprobes.h>
+#include <linux/percpu.h>
+#include <linux/kdebug.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/hw_breakpoint.h>
+#include <asm/processor.h>
+#include <asm/debugreg.h>
+
+/* Per cpu debug control register value */
+DEFINE_PER_CPU(unsigned long, cpu_dr7);
+EXPORT_PER_CPU_SYMBOL(cpu_dr7);
+
+/* Per cpu debug address registers values */
+static DEFINE_PER_CPU(unsigned long, cpu_debugreg[HBP_NUM]);
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for each cpus
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
+
+
+static inline unsigned long
+__encode_dr7(int drnum, unsigned int len, unsigned int type)
+{
+ unsigned long bp_info;
+
+ bp_info = (len | type) & 0xf;
+ bp_info <<= (DR_CONTROL_SHIFT + drnum * DR_CONTROL_SIZE);
+ bp_info |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE));
+
+ return bp_info;
+}
+
+/*
+ * Encode the length, type, Exact, and Enable bits for a particular breakpoint
+ * as stored in debug register 7.
+ */
+unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type)
+{
+ return __encode_dr7(drnum, len, type) | DR_GLOBAL_SLOWDOWN;
+}
+
+/*
+ * Decode the length and type bits for a particular breakpoint as
+ * stored in debug register 7. Return the "enabled" status.
+ */
+int decode_dr7(unsigned long dr7, int bpnum, unsigned *len, unsigned *type)
+{
+ int bp_info = dr7 >> (DR_CONTROL_SHIFT + bpnum * DR_CONTROL_SIZE);
+
+ *len = (bp_info & 0xc) | 0x40;
+ *type = (bp_info & 0x3) | 0x80;
+
+ return (dr7 >> (bpnum * DR_ENABLE_SIZE)) & 0x3;
+}
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint. Eventually we enable it in the debug control register.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ unsigned long *dr7;
+ int i;
+
+ for (i = 0; i < HBP_NUM; i++) {
+ struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+ if (!*slot) {
+ *slot = bp;
+ break;
+ }
+ }
+
+ if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot"))
+ return -EBUSY;
+
+ set_debugreg(info->address, i);
+ __get_cpu_var(cpu_debugreg[i]) = info->address;
+
+ dr7 = &__get_cpu_var(cpu_dr7);
+ *dr7 |= encode_dr7(i, info->len, info->type);
+
+ set_debugreg(*dr7, 7);
+
+ return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.
+ *
+ * First we search the debug address register it uses and then we disable
+ * it.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+void arch_uninstall_hw_breakpoint(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ unsigned long *dr7;
+ int i;
+
+ for (i = 0; i < HBP_NUM; i++) {
+ struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+ if (*slot == bp) {
+ *slot = NULL;
+ break;
+ }
+ }
+
+ if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot"))
+ return;
+
+ dr7 = &__get_cpu_var(cpu_dr7);
+ *dr7 &= ~__encode_dr7(i, info->len, info->type);
+
+ set_debugreg(*dr7, 7);
+}
+
+static int get_hbp_len(u8 hbp_len)
+{
+ unsigned int len_in_bytes = 0;
+
+ switch (hbp_len) {
+ case X86_BREAKPOINT_LEN_1:
+ len_in_bytes = 1;
+ break;
+ case X86_BREAKPOINT_LEN_2:
+ len_in_bytes = 2;
+ break;
+ case X86_BREAKPOINT_LEN_4:
+ len_in_bytes = 4;
+ break;
+#ifdef CONFIG_X86_64
+ case X86_BREAKPOINT_LEN_8:
+ len_in_bytes = 8;
+ break;
+#endif
+ }
+ return len_in_bytes;
+}
+
+/*
+ * Check for virtual address in user space.
+ */
+int arch_check_va_in_userspace(unsigned long va, u8 hbp_len)
+{
+ unsigned int len;
+
+ len = get_hbp_len(hbp_len);
+
+ return (va <= TASK_SIZE - len);
+}
+
+/*
+ * Check for virtual address in kernel space.
+ */
+static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
+{
+ unsigned int len;
+
+ len = get_hbp_len(hbp_len);
+
+ return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
+}
+
+/*
+ * Store a breakpoint's encoded address, length, and type.
+ */
+static int arch_store_info(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ /*
+ * For kernel-addresses, either the address or symbol name can be
+ * specified.
+ */
+ if (info->name)
+ info->address = (unsigned long)
+ kallsyms_lookup_name(info->name);
+ if (info->address)
+ return 0;
+
+ return -EINVAL;
+}
+
+int arch_bp_generic_fields(int x86_len, int x86_type,
+ int *gen_len, int *gen_type)
+{
+ /* Len */
+ switch (x86_len) {
+ case X86_BREAKPOINT_LEN_1:
+ *gen_len = HW_BREAKPOINT_LEN_1;
+ break;
+ case X86_BREAKPOINT_LEN_2:
+ *gen_len = HW_BREAKPOINT_LEN_2;
+ break;
+ case X86_BREAKPOINT_LEN_4:
+ *gen_len = HW_BREAKPOINT_LEN_4;
+ break;
+#ifdef CONFIG_X86_64
+ case X86_BREAKPOINT_LEN_8:
+ *gen_len = HW_BREAKPOINT_LEN_8;
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+
+ /* Type */
+ switch (x86_type) {
+ case X86_BREAKPOINT_EXECUTE:
+ *gen_type = HW_BREAKPOINT_X;
+ break;
+ case X86_BREAKPOINT_WRITE:
+ *gen_type = HW_BREAKPOINT_W;
+ break;
+ case X86_BREAKPOINT_RW:
+ *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+static int arch_build_bp_info(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ info->address = bp->attr.bp_addr;
+
+ /* Len */
+ switch (bp->attr.bp_len) {
+ case HW_BREAKPOINT_LEN_1:
+ info->len = X86_BREAKPOINT_LEN_1;
+ break;
+ case HW_BREAKPOINT_LEN_2:
+ info->len = X86_BREAKPOINT_LEN_2;
+ break;
+ case HW_BREAKPOINT_LEN_4:
+ info->len = X86_BREAKPOINT_LEN_4;
+ break;
+#ifdef CONFIG_X86_64
+ case HW_BREAKPOINT_LEN_8:
+ info->len = X86_BREAKPOINT_LEN_8;
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+
+ /* Type */
+ switch (bp->attr.bp_type) {
+ case HW_BREAKPOINT_W:
+ info->type = X86_BREAKPOINT_WRITE;
+ break;
+ case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
+ info->type = X86_BREAKPOINT_RW;
+ break;
+ case HW_BREAKPOINT_X:
+ info->type = X86_BREAKPOINT_EXECUTE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+/*
+ * Validate the arch-specific HW Breakpoint register settings
+ */
+int arch_validate_hwbkpt_settings(struct perf_event *bp,
+ struct task_struct *tsk)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ unsigned int align;
+ int ret;
+
+
+ ret = arch_build_bp_info(bp);
+ if (ret)
+ return ret;
+
+ ret = -EINVAL;
+
+ if (info->type == X86_BREAKPOINT_EXECUTE)
+ /*
+ * Ptrace-refactoring code
+ * For now, we'll allow instruction breakpoint only for user-space
+ * addresses
+ */
+ if ((!arch_check_va_in_userspace(info->address, info->len)) &&
+ info->len != X86_BREAKPOINT_EXECUTE)
+ return ret;
+
+ switch (info->len) {
+ case X86_BREAKPOINT_LEN_1:
+ align = 0;
+ break;
+ case X86_BREAKPOINT_LEN_2:
+ align = 1;
+ break;
+ case X86_BREAKPOINT_LEN_4:
+ align = 3;
+ break;
+#ifdef CONFIG_X86_64
+ case X86_BREAKPOINT_LEN_8:
+ align = 7;
+ break;
+#endif
+ default:
+ return ret;
+ }
+
+ if (bp->callback)
+ ret = arch_store_info(bp);
+
+ if (ret < 0)
+ return ret;
+ /*
+ * Check that the low-order bits of the address are appropriate
+ * for the alignment implied by len.
+ */
+ if (info->address & align)
+ return -EINVAL;
+
+ /* Check that the virtual address is in the proper range */
+ if (tsk) {
+ if (!arch_check_va_in_userspace(info->address, info->len))
+ return -EFAULT;
+ } else {
+ if (!arch_check_va_in_kernelspace(info->address, info->len))
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/*
+ * Dump the debug register contents to the user.
+ * We can't dump our per cpu values because it
+ * may contain cpu wide breakpoint, something that
+ * doesn't belong to the current task.
+ *
+ * TODO: include non-ptrace user breakpoints (perf)
+ */
+void aout_dump_debugregs(struct user *dump)
+{
+ int i;
+ int dr7 = 0;
+ struct perf_event *bp;
+ struct arch_hw_breakpoint *info;
+ struct thread_struct *thread = &current->thread;
+
+ for (i = 0; i < HBP_NUM; i++) {
+ bp = thread->ptrace_bps[i];
+
+ if (bp && !bp->attr.disabled) {
+ dump->u_debugreg[i] = bp->attr.bp_addr;
+ info = counter_arch_bp(bp);
+ dr7 |= encode_dr7(i, info->len, info->type);
+ } else {
+ dump->u_debugreg[i] = 0;
+ }
+ }
+
+ dump->u_debugreg[4] = 0;
+ dump->u_debugreg[5] = 0;
+ dump->u_debugreg[6] = current->thread.debugreg6;
+
+ dump->u_debugreg[7] = dr7;
+}
+EXPORT_SYMBOL_GPL(aout_dump_debugregs);
+
+/*
+ * Release the user breakpoints used by ptrace
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+ int i;
+ struct thread_struct *t = &tsk->thread;
+
+ for (i = 0; i < HBP_NUM; i++) {
+ unregister_hw_breakpoint(t->ptrace_bps[i]);
+ t->ptrace_bps[i] = NULL;
+ }
+}
+
+void hw_breakpoint_restore(void)
+{
+ set_debugreg(__get_cpu_var(cpu_debugreg[0]), 0);
+ set_debugreg(__get_cpu_var(cpu_debugreg[1]), 1);
+ set_debugreg(__get_cpu_var(cpu_debugreg[2]), 2);
+ set_debugreg(__get_cpu_var(cpu_debugreg[3]), 3);
+ set_debugreg(current->thread.debugreg6, 6);
+ set_debugreg(__get_cpu_var(cpu_dr7), 7);
+}
+EXPORT_SYMBOL_GPL(hw_breakpoint_restore);
+
+/*
+ * Handle debug exception notifications.
+ *
+ * Return value is either NOTIFY_STOP or NOTIFY_DONE as explained below.
+ *
+ * NOTIFY_DONE returned if one of the following conditions is true.
+ * i) When the causative address is from user-space and the exception
+ * is a valid one, i.e. not triggered as a result of lazy debug register
+ * switching
+ * ii) When there are more bits than trap<n> set in DR6 register (such
+ * as BD, BS or BT) indicating that more than one debug condition is
+ * met and requires some more action in do_debug().
+ *
+ * NOTIFY_STOP returned for all other cases
+ *
+ */
+static int __kprobes hw_breakpoint_handler(struct die_args *args)
+{
+ int i, cpu, rc = NOTIFY_STOP;
+ struct perf_event *bp;
+ unsigned long dr7, dr6;
+ unsigned long *dr6_p;
+
+ /* The DR6 value is pointed by args->err */
+ dr6_p = (unsigned long *)ERR_PTR(args->err);
+ dr6 = *dr6_p;
+
+ /* Do an early return if no trap bits are set in DR6 */
+ if ((dr6 & DR_TRAP_BITS) == 0)
+ return NOTIFY_DONE;
+
+ get_debugreg(dr7, 7);
+ /* Disable breakpoints during exception handling */
+ set_debugreg(0UL, 7);
+ /*
+ * Assert that local interrupts are disabled
+ * Reset the DRn bits in the virtualized register value.
+ * The ptrace trigger routine will add in whatever is needed.
+ */
+ current->thread.debugreg6 &= ~DR_TRAP_BITS;
+ cpu = get_cpu();
+
+ /* Handle all the breakpoints that were triggered */
+ for (i = 0; i < HBP_NUM; ++i) {
+ if (likely(!(dr6 & (DR_TRAP0 << i))))
+ continue;
+
+ /*
+ * The counter may be concurrently released but that can only
+ * occur from a call_rcu() path. We can then safely fetch
+ * the breakpoint, use its callback, touch its counter
+ * while we are in an rcu_read_lock() path.
+ */
+ rcu_read_lock();
+
+ bp = per_cpu(bp_per_reg[i], cpu);
+ if (bp)
+ rc = NOTIFY_DONE;
+ /*
+ * Reset the 'i'th TRAP bit in dr6 to denote completion of
+ * exception handling
+ */
+ (*dr6_p) &= ~(DR_TRAP0 << i);
+ /*
+ * bp can be NULL due to lazy debug register switching
+ * or due to concurrent perf counter removing.
+ */
+ if (!bp) {
+ rcu_read_unlock();
+ break;
+ }
+
+ (bp->callback)(bp, args->regs);
+
+ rcu_read_unlock();
+ }
+ if (dr6 & (~DR_TRAP_BITS))
+ rc = NOTIFY_DONE;
+
+ set_debugreg(dr7, 7);
+ put_cpu();
+
+ return rc;
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_exceptions_notify(
+ struct notifier_block *unused, unsigned long val, void *data)
+{
+ if (val != DIE_DEBUG)
+ return NOTIFY_DONE;
+
+ return hw_breakpoint_handler(data);
+}
+
+void hw_breakpoint_pmu_read(struct perf_event *bp)
+{
+ /* TODO */
+}
+
+void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
+{
+ /* TODO */
+}
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 391206199515..fee6cc2b2079 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -63,10 +63,10 @@ static int show_other_interrupts(struct seq_file *p, int prec)
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
seq_printf(p, " Spurious interrupts\n");
- seq_printf(p, "%*s: ", prec, "CNT");
+ seq_printf(p, "%*s: ", prec, "PMI");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs);
- seq_printf(p, " Performance counter interrupts\n");
+ seq_printf(p, " Performance monitoring interrupts\n");
seq_printf(p, "%*s: ", prec, "PND");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs);
@@ -92,17 +92,17 @@ static int show_other_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
seq_printf(p, " TLB shootdowns\n");
#endif
-#ifdef CONFIG_X86_MCE
+#ifdef CONFIG_X86_THERMAL_VECTOR
seq_printf(p, "%*s: ", prec, "TRM");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
seq_printf(p, " Thermal event interrupts\n");
-# ifdef CONFIG_X86_MCE_THRESHOLD
+#endif
+#ifdef CONFIG_X86_MCE_THRESHOLD
seq_printf(p, "%*s: ", prec, "THR");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
seq_printf(p, " Threshold APIC interrupts\n");
-# endif
#endif
#ifdef CONFIG_X86_MCE
seq_printf(p, "%*s: ", prec, "MCE");
@@ -194,11 +194,11 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
sum += irq_stats(cpu)->irq_call_count;
sum += irq_stats(cpu)->irq_tlb_count;
#endif
-#ifdef CONFIG_X86_MCE
+#ifdef CONFIG_X86_THERMAL_VECTOR
sum += irq_stats(cpu)->irq_thermal_count;
-# ifdef CONFIG_X86_MCE_THRESHOLD
+#endif
+#ifdef CONFIG_X86_MCE_THRESHOLD
sum += irq_stats(cpu)->irq_threshold_count;
-# endif
#endif
#ifdef CONFIG_X86_MCE
sum += per_cpu(mce_exception_count, cpu);
@@ -244,7 +244,6 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
__func__, smp_processor_id(), vector, irq);
}
- run_local_timers();
irq_exit();
set_irq_regs(old_regs);
@@ -269,10 +268,99 @@ void smp_generic_interrupt(struct pt_regs *regs)
if (generic_interrupt_extension)
generic_interrupt_extension();
- run_local_timers();
irq_exit();
set_irq_regs(old_regs);
}
EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
+
+#ifdef CONFIG_HOTPLUG_CPU
+/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
+void fixup_irqs(void)
+{
+ unsigned int irq, vector;
+ static int warned;
+ struct irq_desc *desc;
+
+ for_each_irq_desc(irq, desc) {
+ int break_affinity = 0;
+ int set_affinity = 1;
+ const struct cpumask *affinity;
+
+ if (!desc)
+ continue;
+ if (irq == 2)
+ continue;
+
+ /* interrupt's are disabled at this point */
+ spin_lock(&desc->lock);
+
+ affinity = desc->affinity;
+ if (!irq_has_action(irq) ||
+ cpumask_equal(affinity, cpu_online_mask)) {
+ spin_unlock(&desc->lock);
+ continue;
+ }
+
+ /*
+ * Complete the irq move. This cpu is going down and for
+ * non intr-remapping case, we can't wait till this interrupt
+ * arrives at this cpu before completing the irq move.
+ */
+ irq_force_complete_move(irq);
+
+ if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+ break_affinity = 1;
+ affinity = cpu_all_mask;
+ }
+
+ if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->mask)
+ desc->chip->mask(irq);
+
+ if (desc->chip->set_affinity)
+ desc->chip->set_affinity(irq, affinity);
+ else if (!(warned++))
+ set_affinity = 0;
+
+ if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->unmask)
+ desc->chip->unmask(irq);
+
+ spin_unlock(&desc->lock);
+
+ if (break_affinity && set_affinity)
+ printk("Broke affinity for irq %i\n", irq);
+ else if (!set_affinity)
+ printk("Cannot set affinity for irq %i\n", irq);
+ }
+
+ /*
+ * We can remove mdelay() and then send spuriuous interrupts to
+ * new cpu targets for all the irqs that were handled previously by
+ * this cpu. While it works, I have seen spurious interrupt messages
+ * (nothing wrong but still...).
+ *
+ * So for now, retain mdelay(1) and check the IRR and then send those
+ * interrupts to new targets as this cpu is already offlined...
+ */
+ mdelay(1);
+
+ for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
+ unsigned int irr;
+
+ if (__get_cpu_var(vector_irq)[vector] < 0)
+ continue;
+
+ irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
+ if (irr & (1 << (vector % 32))) {
+ irq = __get_cpu_var(vector_irq)[vector];
+
+ desc = irq_to_desc(irq);
+ spin_lock(&desc->lock);
+ if (desc->chip->retrigger)
+ desc->chip->retrigger(irq);
+ spin_unlock(&desc->lock);
+ }
+ }
+}
+#endif
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 7d35d0fe2329..10709f29d166 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -211,48 +211,3 @@ bool handle_irq(unsigned irq, struct pt_regs *regs)
return true;
}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
-void fixup_irqs(void)
-{
- unsigned int irq;
- struct irq_desc *desc;
-
- for_each_irq_desc(irq, desc) {
- const struct cpumask *affinity;
-
- if (!desc)
- continue;
- if (irq == 2)
- continue;
-
- affinity = desc->affinity;
- if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
- printk("Breaking affinity for irq %i\n", irq);
- affinity = cpu_all_mask;
- }
- if (desc->chip->set_affinity)
- desc->chip->set_affinity(irq, affinity);
- else if (desc->action)
- printk_once("Cannot set affinity for irq %i\n", irq);
- }
-
-#if 0
- barrier();
- /* Ingo Molnar says: "after the IO-APIC masks have been redirected
- [note the nop - the interrupt-enable boundary on x86 is two
- instructions from sti] - to flush out pending hardirqs and
- IPIs. After this point nothing is supposed to reach this CPU." */
- __asm__ __volatile__("sti; nop; cli");
- barrier();
-#else
- /* That doesn't seem sufficient. Give it 1ms. */
- local_irq_enable();
- mdelay(1);
- local_irq_disable();
-#endif
-}
-#endif
-
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 977d8b43a0dd..acf8fbf8fbda 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -62,64 +62,6 @@ bool handle_irq(unsigned irq, struct pt_regs *regs)
return true;
}
-#ifdef CONFIG_HOTPLUG_CPU
-/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
-void fixup_irqs(void)
-{
- unsigned int irq;
- static int warned;
- struct irq_desc *desc;
-
- for_each_irq_desc(irq, desc) {
- int break_affinity = 0;
- int set_affinity = 1;
- const struct cpumask *affinity;
-
- if (!desc)
- continue;
- if (irq == 2)
- continue;
-
- /* interrupt's are disabled at this point */
- spin_lock(&desc->lock);
-
- affinity = desc->affinity;
- if (!irq_has_action(irq) ||
- cpumask_equal(affinity, cpu_online_mask)) {
- spin_unlock(&desc->lock);
- continue;
- }
-
- if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
- break_affinity = 1;
- affinity = cpu_all_mask;
- }
-
- if (desc->chip->mask)
- desc->chip->mask(irq);
-
- if (desc->chip->set_affinity)
- desc->chip->set_affinity(irq, affinity);
- else if (!(warned++))
- set_affinity = 0;
-
- if (desc->chip->unmask)
- desc->chip->unmask(irq);
-
- spin_unlock(&desc->lock);
-
- if (break_affinity && set_affinity)
- printk("Broke affinity for irq %i\n", irq);
- else if (!set_affinity)
- printk("Cannot set affinity for irq %i\n", irq);
- }
-
- /* That doesn't seem sufficient. Give it 1ms. */
- local_irq_enable();
- mdelay(1);
- local_irq_disable();
-}
-#endif
extern void call_softirq(void);
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 8d82a77a3f3b..20a5b3689463 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -43,6 +43,7 @@
#include <linux/smp.h>
#include <linux/nmi.h>
+#include <asm/debugreg.h>
#include <asm/apicdef.h>
#include <asm/system.h>
@@ -88,7 +89,6 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
gdb_regs[GDB_SS] = __KERNEL_DS;
gdb_regs[GDB_FS] = 0xFFFF;
gdb_regs[GDB_GS] = 0xFFFF;
- gdb_regs[GDB_SP] = (int)&regs->sp;
#else
gdb_regs[GDB_R8] = regs->r8;
gdb_regs[GDB_R9] = regs->r9;
@@ -101,8 +101,8 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
gdb_regs32[GDB_PS] = regs->flags;
gdb_regs32[GDB_CS] = regs->cs;
gdb_regs32[GDB_SS] = regs->ss;
- gdb_regs[GDB_SP] = regs->sp;
#endif
+ gdb_regs[GDB_SP] = kernel_stack_pointer(regs);
}
/**
@@ -434,6 +434,11 @@ single_step_cont(struct pt_regs *regs, struct die_args *args)
"resuming...\n");
kgdb_arch_handle_exception(args->trapnr, args->signr,
args->err, "c", "", regs);
+ /*
+ * Reset the BS bit in dr6 (pointed by args->err) to
+ * denote completion of processing
+ */
+ (*(unsigned long *)ERR_PTR(args->err)) &= ~DR_STEP;
return NOTIFY_STOP;
}
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 7b5169d2b000..1f3186ce213c 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -48,31 +48,22 @@
#include <linux/preempt.h>
#include <linux/module.h>
#include <linux/kdebug.h>
+#include <linux/kallsyms.h>
#include <asm/cacheflush.h>
#include <asm/desc.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/alternative.h>
+#include <asm/insn.h>
+#include <asm/debugreg.h>
void jprobe_return_end(void);
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
-#ifdef CONFIG_X86_64
-#define stack_addr(regs) ((unsigned long *)regs->sp)
-#else
-/*
- * "&regs->sp" looks wrong, but it's correct for x86_32. x86_32 CPUs
- * don't save the ss and esp registers if the CPU is already in kernel
- * mode when it traps. So for kprobes, regs->sp and regs->ss are not
- * the [nonexistent] saved stack pointer and ss register, but rather
- * the top 8 bytes of the pre-int3 stack. So &regs->sp happens to
- * point to the top of the pre-int3 stack.
- */
-#define stack_addr(regs) ((unsigned long *)&regs->sp)
-#endif
+#define stack_addr(regs) ((unsigned long *)kernel_stack_pointer(regs))
#define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
(((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \
@@ -106,50 +97,6 @@ static const u32 twobyte_is_boostable[256 / 32] = {
/* ----------------------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
-static const u32 onebyte_has_modrm[256 / 32] = {
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* ----------------------------------------------- */
- W(0x00, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 00 */
- W(0x10, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) , /* 10 */
- W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 20 */
- W(0x30, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) , /* 30 */
- W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */
- W(0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 50 */
- W(0x60, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0) | /* 60 */
- W(0x70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 70 */
- W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
- W(0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 90 */
- W(0xa0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* a0 */
- W(0xb0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* b0 */
- W(0xc0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0) | /* c0 */
- W(0xd0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
- W(0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* e0 */
- W(0xf0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1) /* f0 */
- /* ----------------------------------------------- */
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-};
-static const u32 twobyte_has_modrm[256 / 32] = {
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* ----------------------------------------------- */
- W(0x00, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1) | /* 0f */
- W(0x10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0) , /* 1f */
- W(0x20, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* 2f */
- W(0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 3f */
- W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 4f */
- W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 5f */
- W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 6f */
- W(0x70, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1) , /* 7f */
- W(0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 8f */
- W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 9f */
- W(0xa0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1) | /* af */
- W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) , /* bf */
- W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0) | /* cf */
- W(0xd0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* df */
- W(0xe0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* ef */
- W(0xf0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) /* ff */
- /* ----------------------------------------------- */
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-};
#undef W
struct kretprobe_blackpoint kretprobe_blacklist[] = {
@@ -244,6 +191,75 @@ retry:
}
}
+/* Recover the probed instruction at addr for further analysis. */
+static int recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr)
+{
+ struct kprobe *kp;
+ kp = get_kprobe((void *)addr);
+ if (!kp)
+ return -EINVAL;
+
+ /*
+ * Basically, kp->ainsn.insn has an original instruction.
+ * However, RIP-relative instruction can not do single-stepping
+ * at different place, fix_riprel() tweaks the displacement of
+ * that instruction. In that case, we can't recover the instruction
+ * from the kp->ainsn.insn.
+ *
+ * On the other hand, kp->opcode has a copy of the first byte of
+ * the probed instruction, which is overwritten by int3. And
+ * the instruction at kp->addr is not modified by kprobes except
+ * for the first byte, we can recover the original instruction
+ * from it and kp->opcode.
+ */
+ memcpy(buf, kp->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+ buf[0] = kp->opcode;
+ return 0;
+}
+
+/* Dummy buffers for kallsyms_lookup */
+static char __dummy_buf[KSYM_NAME_LEN];
+
+/* Check if paddr is at an instruction boundary */
+static int __kprobes can_probe(unsigned long paddr)
+{
+ int ret;
+ unsigned long addr, offset = 0;
+ struct insn insn;
+ kprobe_opcode_t buf[MAX_INSN_SIZE];
+
+ if (!kallsyms_lookup(paddr, NULL, &offset, NULL, __dummy_buf))
+ return 0;
+
+ /* Decode instructions */
+ addr = paddr - offset;
+ while (addr < paddr) {
+ kernel_insn_init(&insn, (void *)addr);
+ insn_get_opcode(&insn);
+
+ /*
+ * Check if the instruction has been modified by another
+ * kprobe, in which case we replace the breakpoint by the
+ * original instruction in our buffer.
+ */
+ if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) {
+ ret = recover_probed_instruction(buf, addr);
+ if (ret)
+ /*
+ * Another debugging subsystem might insert
+ * this breakpoint. In that case, we can't
+ * recover it.
+ */
+ return 0;
+ kernel_insn_init(&insn, buf);
+ }
+ insn_get_length(&insn);
+ addr += insn.length;
+ }
+
+ return (addr == paddr);
+}
+
/*
* Returns non-zero if opcode modifies the interrupt flag.
*/
@@ -277,68 +293,30 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
static void __kprobes fix_riprel(struct kprobe *p)
{
#ifdef CONFIG_X86_64
- u8 *insn = p->ainsn.insn;
- s64 disp;
- int need_modrm;
-
- /* Skip legacy instruction prefixes. */
- while (1) {
- switch (*insn) {
- case 0x66:
- case 0x67:
- case 0x2e:
- case 0x3e:
- case 0x26:
- case 0x64:
- case 0x65:
- case 0x36:
- case 0xf0:
- case 0xf3:
- case 0xf2:
- ++insn;
- continue;
- }
- break;
- }
+ struct insn insn;
+ kernel_insn_init(&insn, p->ainsn.insn);
- /* Skip REX instruction prefix. */
- if (is_REX_prefix(insn))
- ++insn;
-
- if (*insn == 0x0f) {
- /* Two-byte opcode. */
- ++insn;
- need_modrm = test_bit(*insn,
- (unsigned long *)twobyte_has_modrm);
- } else
- /* One-byte opcode. */
- need_modrm = test_bit(*insn,
- (unsigned long *)onebyte_has_modrm);
-
- if (need_modrm) {
- u8 modrm = *++insn;
- if ((modrm & 0xc7) == 0x05) {
- /* %rip+disp32 addressing mode */
- /* Displacement follows ModRM byte. */
- ++insn;
- /*
- * The copied instruction uses the %rip-relative
- * addressing mode. Adjust the displacement for the
- * difference between the original location of this
- * instruction and the location of the copy that will
- * actually be run. The tricky bit here is making sure
- * that the sign extension happens correctly in this
- * calculation, since we need a signed 32-bit result to
- * be sign-extended to 64 bits when it's added to the
- * %rip value and yield the same 64-bit result that the
- * sign-extension of the original signed 32-bit
- * displacement would have given.
- */
- disp = (u8 *) p->addr + *((s32 *) insn) -
- (u8 *) p->ainsn.insn;
- BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
- *(s32 *)insn = (s32) disp;
- }
+ if (insn_rip_relative(&insn)) {
+ s64 newdisp;
+ u8 *disp;
+ insn_get_displacement(&insn);
+ /*
+ * The copied instruction uses the %rip-relative addressing
+ * mode. Adjust the displacement for the difference between
+ * the original location of this instruction and the location
+ * of the copy that will actually be run. The tricky bit here
+ * is making sure that the sign extension happens correctly in
+ * this calculation, since we need a signed 32-bit result to
+ * be sign-extended to 64 bits when it's added to the %rip
+ * value and yield the same 64-bit result that the sign-
+ * extension of the original signed 32-bit displacement would
+ * have given.
+ */
+ newdisp = (u8 *) p->addr + (s64) insn.displacement.value -
+ (u8 *) p->ainsn.insn;
+ BUG_ON((s64) (s32) newdisp != newdisp); /* Sanity check. */
+ disp = (u8 *) p->ainsn.insn + insn_offset_displacement(&insn);
+ *(s32 *) disp = (s32) newdisp;
}
#endif
}
@@ -359,6 +337,8 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p)
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
+ if (!can_probe((unsigned long)p->addr))
+ return -EILSEQ;
/* insn: must be on special executable page on x86. */
p->ainsn.insn = get_insn_slot();
if (!p->ainsn.insn)
@@ -472,17 +452,6 @@ static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
{
switch (kcb->kprobe_status) {
case KPROBE_HIT_SSDONE:
-#ifdef CONFIG_X86_64
- /* TODO: Provide re-entrancy from post_kprobes_handler() and
- * avoid exception stack corruption while single-stepping on
- * the instruction of the new probe.
- */
- arch_disarm_kprobe(p);
- regs->ip = (unsigned long)p->addr;
- reset_current_kprobe();
- preempt_enable_no_resched();
- break;
-#endif
case KPROBE_HIT_ACTIVE:
save_previous_kprobe(kcb);
set_current_kprobe(p, regs, kcb);
@@ -491,18 +460,16 @@ static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
kcb->kprobe_status = KPROBE_REENTER;
break;
case KPROBE_HIT_SS:
- if (p == kprobe_running()) {
- regs->flags &= ~X86_EFLAGS_TF;
- regs->flags |= kcb->kprobe_saved_flags;
- return 0;
- } else {
- /* A probe has been hit in the codepath leading up
- * to, or just after, single-stepping of a probed
- * instruction. This entire codepath should strictly
- * reside in .kprobes.text section. Raise a warning
- * to highlight this peculiar case.
- */
- }
+ /* A probe has been hit in the codepath leading up to, or just
+ * after, single-stepping of a probed instruction. This entire
+ * codepath should strictly reside in .kprobes.text section.
+ * Raise a BUG or we'll continue in an endless reentering loop
+ * and eventually a stack overflow.
+ */
+ printk(KERN_WARNING "Unrecoverable kprobe detected at %p.\n",
+ p->addr);
+ dump_kprobe(p);
+ BUG();
default:
/* impossible cases */
WARN_ON(1);
@@ -967,8 +934,14 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
ret = NOTIFY_STOP;
break;
case DIE_DEBUG:
- if (post_kprobe_handler(args->regs))
+ if (post_kprobe_handler(args->regs)) {
+ /*
+ * Reset the BS bit in dr6 (pointed by args->err) to
+ * denote completion of processing
+ */
+ (*(unsigned long *)ERR_PTR(args->err)) &= ~DR_STEP;
ret = NOTIFY_STOP;
+ }
break;
case DIE_GPF:
/*
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index c1c429d00130..c843f8406da2 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -25,6 +25,7 @@
#include <asm/desc.h>
#include <asm/system.h>
#include <asm/cacheflush.h>
+#include <asm/debugreg.h>
static void set_idt(void *newidt, __u16 limit)
{
@@ -202,6 +203,7 @@ void machine_kexec(struct kimage *image)
/* Interrupts aren't acceptable while we reboot */
local_irq_disable();
+ hw_breakpoint_disable();
if (image->preserve_context) {
#ifdef CONFIG_X86_IO_APIC
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 84c3bf209e98..4a8bb82248ae 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -18,6 +18,7 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/mmu_context.h>
+#include <asm/debugreg.h>
static int init_one_level2_page(struct kimage *image, pgd_t *pgd,
unsigned long addr)
@@ -282,6 +283,7 @@ void machine_kexec(struct kimage *image)
/* Interrupts aren't acceptable while we reboot */
local_irq_disable();
+ hw_breakpoint_disable();
if (image->preserve_context) {
#ifdef CONFIG_X86_IO_APIC
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index 366baa179913..f4c538b681ca 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -317,6 +317,12 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device)
return UCODE_NFOUND;
}
+ if (*(u32 *)firmware->data != UCODE_MAGIC) {
+ printk(KERN_ERR "microcode: invalid UCODE_MAGIC (0x%08x)\n",
+ *(u32 *)firmware->data);
+ return UCODE_ERROR;
+ }
+
ret = generic_load_microcode(cpu, firmware->data, firmware->size);
release_firmware(firmware);
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index 378e9a8f1bf8..2bcad3926edb 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -73,7 +73,6 @@
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/capability.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -201,7 +200,6 @@ static int do_microcode_update(const void __user *buf, size_t size)
static int microcode_open(struct inode *unused1, struct file *unused2)
{
- cycle_kernel_lock();
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
}
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 6a3cefc7dda1..553449951b84 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -174,21 +174,17 @@ static int msr_open(struct inode *inode, struct file *file)
{
unsigned int cpu = iminor(file->f_path.dentry->d_inode);
struct cpuinfo_x86 *c = &cpu_data(cpu);
- int ret = 0;
- lock_kernel();
cpu = iminor(file->f_path.dentry->d_inode);
- if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
- ret = -ENXIO; /* No such CPU */
- goto out;
- }
+ if (cpu >= nr_cpu_ids || !cpu_online(cpu))
+ return -ENXIO; /* No such CPU */
+
c = &cpu_data(cpu);
if (!cpu_has(c, X86_FEATURE_MSR))
- ret = -EIO; /* MSR not supported */
-out:
- unlock_kernel();
- return ret;
+ return -EIO; /* MSR not supported */
+
+ return 0;
}
/*
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 971a3bec47a8..c563e4c8ff39 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -46,6 +46,7 @@
#include <asm/dma.h>
#include <asm/rio.h>
#include <asm/bios_ebda.h>
+#include <asm/x86_init.h>
#ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT
int use_calgary __read_mostly = 1;
@@ -244,7 +245,7 @@ static unsigned long iommu_range_alloc(struct device *dev,
if (panic_on_overflow)
panic("Calgary: fix the allocator.\n");
else
- return bad_dma_address;
+ return DMA_ERROR_CODE;
}
}
@@ -260,12 +261,15 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
void *vaddr, unsigned int npages, int direction)
{
unsigned long entry;
- dma_addr_t ret = bad_dma_address;
+ dma_addr_t ret;
entry = iommu_range_alloc(dev, tbl, npages);
- if (unlikely(entry == bad_dma_address))
- goto error;
+ if (unlikely(entry == DMA_ERROR_CODE)) {
+ printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
+ "iommu %p\n", npages, tbl);
+ return DMA_ERROR_CODE;
+ }
/* set the return dma address */
ret = (entry << PAGE_SHIFT) | ((unsigned long)vaddr & ~PAGE_MASK);
@@ -273,13 +277,7 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
/* put the TCEs in the HW table */
tce_build(tbl, entry, npages, (unsigned long)vaddr & PAGE_MASK,
direction);
-
return ret;
-
-error:
- printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
- "iommu %p\n", npages, tbl);
- return bad_dma_address;
}
static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
@@ -290,8 +288,8 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
unsigned long flags;
/* were we called with bad_dma_address? */
- badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE);
- if (unlikely((dma_addr >= bad_dma_address) && (dma_addr < badend))) {
+ badend = DMA_ERROR_CODE + (EMERGENCY_PAGES * PAGE_SIZE);
+ if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) {
WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
"address 0x%Lx\n", dma_addr);
return;
@@ -318,13 +316,15 @@ static inline struct iommu_table *find_iommu_table(struct device *dev)
pdev = to_pci_dev(dev);
+ /* search up the device tree for an iommu */
pbus = pdev->bus;
-
- /* is the device behind a bridge? Look for the root bus */
- while (pbus->parent)
+ do {
+ tbl = pci_iommu(pbus);
+ if (tbl && tbl->it_busno == pbus->number)
+ break;
+ tbl = NULL;
pbus = pbus->parent;
-
- tbl = pci_iommu(pbus);
+ } while (pbus);
BUG_ON(tbl && (tbl->it_busno != pbus->number));
@@ -373,7 +373,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
npages = iommu_num_pages(vaddr, s->length, PAGE_SIZE);
entry = iommu_range_alloc(dev, tbl, npages);
- if (entry == bad_dma_address) {
+ if (entry == DMA_ERROR_CODE) {
/* makes sure unmap knows to stop */
s->dma_length = 0;
goto error;
@@ -391,7 +391,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
error:
calgary_unmap_sg(dev, sg, nelems, dir, NULL);
for_each_sg(sg, s, nelems, i) {
- sg->dma_address = bad_dma_address;
+ sg->dma_address = DMA_ERROR_CODE;
sg->dma_length = 0;
}
return 0;
@@ -446,7 +446,7 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size,
/* set up tces to cover the allocated range */
mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL);
- if (mapping == bad_dma_address)
+ if (mapping == DMA_ERROR_CODE)
goto free;
*dma_handle = mapping;
return ret;
@@ -727,7 +727,7 @@ static void __init calgary_reserve_regions(struct pci_dev *dev)
struct iommu_table *tbl = pci_iommu(dev->bus);
/* reserve EMERGENCY_PAGES from bad_dma_address and up */
- iommu_range_reserve(tbl, bad_dma_address, EMERGENCY_PAGES);
+ iommu_range_reserve(tbl, DMA_ERROR_CODE, EMERGENCY_PAGES);
/* avoid the BIOS/VGA first 640KB-1MB region */
/* for CalIOC2 - avoid the entire first MB */
@@ -1344,6 +1344,23 @@ static void __init get_tce_space_from_tar(void)
return;
}
+static int __init calgary_iommu_init(void)
+{
+ int ret;
+
+ /* ok, we're trying to use Calgary - let's roll */
+ printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
+
+ ret = calgary_init();
+ if (ret) {
+ printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
+ "falling back to no_iommu\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
void __init detect_calgary(void)
{
int bus;
@@ -1357,7 +1374,7 @@ void __init detect_calgary(void)
* if the user specified iommu=off or iommu=soft or we found
* another HW IOMMU already, bail out.
*/
- if (swiotlb || no_iommu || iommu_detected)
+ if (no_iommu || iommu_detected)
return;
if (!use_calgary)
@@ -1442,9 +1459,7 @@ void __init detect_calgary(void)
printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d\n",
specified_table_size);
- /* swiotlb for devices that aren't behind the Calgary. */
- if (max_pfn > MAX_DMA32_PFN)
- swiotlb = 1;
+ x86_init.iommu.iommu_init = calgary_iommu_init;
}
return;
@@ -1457,35 +1472,6 @@ cleanup:
}
}
-int __init calgary_iommu_init(void)
-{
- int ret;
-
- if (no_iommu || (swiotlb && !calgary_detected))
- return -ENODEV;
-
- if (!calgary_detected)
- return -ENODEV;
-
- /* ok, we're trying to use Calgary - let's roll */
- printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
-
- ret = calgary_init();
- if (ret) {
- printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
- "falling back to no_iommu\n", ret);
- return ret;
- }
-
- force_iommu = 1;
- bad_dma_address = 0x0;
- /* dma_ops is set to swiotlb or nommu */
- if (!dma_ops)
- dma_ops = &nommu_dma_ops;
-
- return 0;
-}
-
static int __init calgary_parse_options(char *p)
{
unsigned int bridge;
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index b2a71dca5642..afcc58b69c7c 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -11,10 +11,11 @@
#include <asm/gart.h>
#include <asm/calgary.h>
#include <asm/amd_iommu.h>
+#include <asm/x86_init.h>
static int forbid_dac __read_mostly;
-struct dma_map_ops *dma_ops;
+struct dma_map_ops *dma_ops = &nommu_dma_ops;
EXPORT_SYMBOL(dma_ops);
static int iommu_sac_force __read_mostly;
@@ -42,15 +43,10 @@ int iommu_detected __read_mostly = 0;
*/
int iommu_pass_through __read_mostly;
-dma_addr_t bad_dma_address __read_mostly = 0;
-EXPORT_SYMBOL(bad_dma_address);
-
-/* Dummy device used for NULL arguments (normally ISA). Better would
- be probably a smaller DMA mask, but this is bug-to-bug compatible
- to older i386. */
+/* Dummy device used for NULL arguments (normally ISA). */
struct device x86_dma_fallback_dev = {
.init_name = "fallback device",
- .coherent_dma_mask = DMA_BIT_MASK(32),
+ .coherent_dma_mask = ISA_DMA_BIT_MASK,
.dma_mask = &x86_dma_fallback_dev.coherent_dma_mask,
};
EXPORT_SYMBOL(x86_dma_fallback_dev);
@@ -128,20 +124,17 @@ void __init pci_iommu_alloc(void)
/* free the range so iommu could get some range less than 4G */
dma32_free_bootmem();
#endif
+ if (pci_swiotlb_init())
+ return;
- /*
- * The order of these functions is important for
- * fall-back/fail-over reasons
- */
gart_iommu_hole_init();
detect_calgary();
detect_intel_iommu();
+ /* needs to be called after gart_iommu_hole_init */
amd_iommu_detect();
-
- pci_swiotlb_init();
}
void *dma_generic_alloc_coherent(struct device *dev, size_t size,
@@ -216,7 +209,7 @@ static __init int iommu_setup(char *p)
if (!strncmp(p, "allowdac", 8))
forbid_dac = 0;
if (!strncmp(p, "nodac", 5))
- forbid_dac = -1;
+ forbid_dac = 1;
if (!strncmp(p, "usedac", 6)) {
forbid_dac = -1;
return 1;
@@ -291,25 +284,17 @@ static int __init pci_iommu_init(void)
#ifdef CONFIG_PCI
dma_debug_add_bus(&pci_bus_type);
#endif
+ x86_init.iommu.iommu_init();
- calgary_iommu_init();
-
- intel_iommu_init();
+ if (swiotlb) {
+ printk(KERN_INFO "PCI-DMA: "
+ "Using software bounce buffering for IO (SWIOTLB)\n");
+ swiotlb_print_info();
+ } else
+ swiotlb_free();
- amd_iommu_init();
-
- gart_iommu_init();
-
- no_iommu_init();
return 0;
}
-
-void pci_iommu_shutdown(void)
-{
- gart_iommu_shutdown();
-
- amd_iommu_shutdown();
-}
/* Must execute after PCI subsystem */
rootfs_initcall(pci_iommu_init);
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index a7f1b64f86e0..e6a0d402f171 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -39,6 +39,7 @@
#include <asm/swiotlb.h>
#include <asm/dma.h>
#include <asm/k8.h>
+#include <asm/x86_init.h>
static unsigned long iommu_bus_base; /* GART remapping area (physical) */
static unsigned long iommu_size; /* size of remapping area bytes */
@@ -46,6 +47,8 @@ static unsigned long iommu_pages; /* .. and in pages */
static u32 *iommu_gatt_base; /* Remapping table */
+static dma_addr_t bad_dma_addr;
+
/*
* If this is disabled the IOMMU will use an optimized flushing strategy
* of only flushing when an mapping is reused. With it true the GART is
@@ -92,7 +95,7 @@ static unsigned long alloc_iommu(struct device *dev, int size,
base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
PAGE_SIZE) >> PAGE_SHIFT;
- boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
+ boundary_size = ALIGN((u64)dma_get_seg_boundary(dev) + 1,
PAGE_SIZE) >> PAGE_SHIFT;
spin_lock_irqsave(&iommu_bitmap_lock, flags);
@@ -216,7 +219,7 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
if (panic_on_overflow)
panic("dma_map_area overflow %lu bytes\n", size);
iommu_full(dev, size, dir);
- return bad_dma_address;
+ return bad_dma_addr;
}
for (i = 0; i < npages; i++) {
@@ -294,7 +297,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
int i;
#ifdef CONFIG_IOMMU_DEBUG
- printk(KERN_DEBUG "dma_map_sg overflow\n");
+ pr_debug("dma_map_sg overflow\n");
#endif
for_each_sg(sg, s, nents, i) {
@@ -302,7 +305,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
if (nonforced_iommu(dev, addr, s->length)) {
addr = dma_map_area(dev, addr, s->length, dir, 0);
- if (addr == bad_dma_address) {
+ if (addr == bad_dma_addr) {
if (i > 0)
gart_unmap_sg(dev, sg, i, dir, NULL);
nents = 0;
@@ -389,12 +392,14 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
if (!dev)
dev = &x86_dma_fallback_dev;
- out = 0;
- start = 0;
- start_sg = sgmap = sg;
- seg_size = 0;
- max_seg_size = dma_get_max_seg_size(dev);
- ps = NULL; /* shut up gcc */
+ out = 0;
+ start = 0;
+ start_sg = sg;
+ sgmap = sg;
+ seg_size = 0;
+ max_seg_size = dma_get_max_seg_size(dev);
+ ps = NULL; /* shut up gcc */
+
for_each_sg(sg, s, nents, i) {
dma_addr_t addr = sg_phys(s);
@@ -417,11 +422,12 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
sgmap, pages, need) < 0)
goto error;
out++;
- seg_size = 0;
- sgmap = sg_next(sgmap);
- pages = 0;
- start = i;
- start_sg = s;
+
+ seg_size = 0;
+ sgmap = sg_next(sgmap);
+ pages = 0;
+ start = i;
+ start_sg = s;
}
}
@@ -455,7 +461,7 @@ error:
iommu_full(dev, pages << PAGE_SHIFT, dir);
for_each_sg(sg, s, nents, i)
- s->dma_address = bad_dma_address;
+ s->dma_address = bad_dma_addr;
return 0;
}
@@ -479,7 +485,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
DMA_BIDIRECTIONAL, align_mask);
flush_gart();
- if (paddr != bad_dma_address) {
+ if (paddr != bad_dma_addr) {
*dma_addr = paddr;
return page_address(page);
}
@@ -499,6 +505,11 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr,
free_pages((unsigned long)vaddr, get_order(size));
}
+static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return (dma_addr == bad_dma_addr);
+}
+
static int no_agp;
static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
@@ -515,7 +526,7 @@ static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
iommu_size -= round_up(a, PMD_PAGE_SIZE) - a;
if (iommu_size < 64*1024*1024) {
- printk(KERN_WARNING
+ pr_warning(
"PCI-DMA: Warning: Small IOMMU %luMB."
" Consider increasing the AGP aperture in BIOS\n",
iommu_size >> 20);
@@ -570,28 +581,32 @@ void set_up_gart_resume(u32 aper_order, u32 aper_alloc)
aperture_alloc = aper_alloc;
}
-static int gart_resume(struct sys_device *dev)
+static void gart_fixup_northbridges(struct sys_device *dev)
{
- printk(KERN_INFO "PCI-DMA: Resuming GART IOMMU\n");
+ int i;
- if (fix_up_north_bridges) {
- int i;
+ if (!fix_up_north_bridges)
+ return;
- printk(KERN_INFO "PCI-DMA: Restoring GART aperture settings\n");
+ pr_info("PCI-DMA: Restoring GART aperture settings\n");
- for (i = 0; i < num_k8_northbridges; i++) {
- struct pci_dev *dev = k8_northbridges[i];
+ for (i = 0; i < num_k8_northbridges; i++) {
+ struct pci_dev *dev = k8_northbridges[i];
- /*
- * Don't enable translations just yet. That is the next
- * step. Restore the pre-suspend aperture settings.
- */
- pci_write_config_dword(dev, AMD64_GARTAPERTURECTL,
- aperture_order << 1);
- pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE,
- aperture_alloc >> 25);
- }
+ /*
+ * Don't enable translations just yet. That is the next
+ * step. Restore the pre-suspend aperture settings.
+ */
+ pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, aperture_order << 1);
+ pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE, aperture_alloc >> 25);
}
+}
+
+static int gart_resume(struct sys_device *dev)
+{
+ pr_info("PCI-DMA: Resuming GART IOMMU\n");
+
+ gart_fixup_northbridges(dev);
enable_gart_translations();
@@ -604,15 +619,14 @@ static int gart_suspend(struct sys_device *dev, pm_message_t state)
}
static struct sysdev_class gart_sysdev_class = {
- .name = "gart",
- .suspend = gart_suspend,
- .resume = gart_resume,
+ .name = "gart",
+ .suspend = gart_suspend,
+ .resume = gart_resume,
};
static struct sys_device device_gart = {
- .id = 0,
- .cls = &gart_sysdev_class,
+ .cls = &gart_sysdev_class,
};
/*
@@ -627,7 +641,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
void *gatt;
int i, error;
- printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
+ pr_info("PCI-DMA: Disabling AGP.\n");
+
aper_size = aper_base = info->aper_size = 0;
dev = NULL;
for (i = 0; i < num_k8_northbridges; i++) {
@@ -645,6 +660,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
}
if (!aper_base)
goto nommu;
+
info->aper_base = aper_base;
info->aper_size = aper_size >> 20;
@@ -667,14 +683,14 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
flush_gart();
- printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n",
+ pr_info("PCI-DMA: aperture base @ %x size %u KB\n",
aper_base, aper_size>>10);
return 0;
nommu:
/* Should not happen anymore */
- printk(KERN_WARNING "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
+ pr_warning("PCI-DMA: More than 4GB of RAM and no IOMMU\n"
"falling back to iommu=soft.\n");
return -1;
}
@@ -686,14 +702,15 @@ static struct dma_map_ops gart_dma_ops = {
.unmap_page = gart_unmap_page,
.alloc_coherent = gart_alloc_coherent,
.free_coherent = gart_free_coherent,
+ .mapping_error = gart_mapping_error,
};
-void gart_iommu_shutdown(void)
+static void gart_iommu_shutdown(void)
{
struct pci_dev *dev;
int i;
- if (no_agp && (dma_ops != &gart_dma_ops))
+ if (no_agp)
return;
for (i = 0; i < num_k8_northbridges; i++) {
@@ -708,7 +725,7 @@ void gart_iommu_shutdown(void)
}
}
-void __init gart_iommu_init(void)
+int __init gart_iommu_init(void)
{
struct agp_kern_info info;
unsigned long iommu_start;
@@ -718,7 +735,7 @@ void __init gart_iommu_init(void)
long i;
if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0)
- return;
+ return 0;
#ifndef CONFIG_AGP_AMD64
no_agp = 1;
@@ -730,35 +747,28 @@ void __init gart_iommu_init(void)
(agp_copy_info(agp_bridge, &info) < 0);
#endif
- if (swiotlb)
- return;
-
- /* Did we detect a different HW IOMMU? */
- if (iommu_detected && !gart_iommu_aperture)
- return;
-
if (no_iommu ||
(!force_iommu && max_pfn <= MAX_DMA32_PFN) ||
!gart_iommu_aperture ||
(no_agp && init_k8_gatt(&info) < 0)) {
if (max_pfn > MAX_DMA32_PFN) {
- printk(KERN_WARNING "More than 4GB of memory "
- "but GART IOMMU not available.\n");
- printk(KERN_WARNING "falling back to iommu=soft.\n");
+ pr_warning("More than 4GB of memory but GART IOMMU not available.\n");
+ pr_warning("falling back to iommu=soft.\n");
}
- return;
+ return 0;
}
/* need to map that range */
- aper_size = info.aper_size << 20;
- aper_base = info.aper_base;
- end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
+ aper_size = info.aper_size << 20;
+ aper_base = info.aper_base;
+ end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
+
if (end_pfn > max_low_pfn_mapped) {
start_pfn = (aper_base>>PAGE_SHIFT);
init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
}
- printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
+ pr_info("PCI-DMA: using GART IOMMU.\n");
iommu_size = check_iommu_size(info.aper_base, aper_size);
iommu_pages = iommu_size >> PAGE_SHIFT;
@@ -773,8 +783,7 @@ void __init gart_iommu_init(void)
ret = dma_debug_resize_entries(iommu_pages);
if (ret)
- printk(KERN_DEBUG
- "PCI-DMA: Cannot trace all the entries\n");
+ pr_debug("PCI-DMA: Cannot trace all the entries\n");
}
#endif
@@ -784,15 +793,14 @@ void __init gart_iommu_init(void)
*/
iommu_area_reserve(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
- agp_memory_reserved = iommu_size;
- printk(KERN_INFO
- "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
+ pr_info("PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
iommu_size >> 20);
- iommu_start = aper_size - iommu_size;
- iommu_bus_base = info.aper_base + iommu_start;
- bad_dma_address = iommu_bus_base;
- iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
+ agp_memory_reserved = iommu_size;
+ iommu_start = aper_size - iommu_size;
+ iommu_bus_base = info.aper_base + iommu_start;
+ bad_dma_addr = iommu_bus_base;
+ iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
/*
* Unmap the IOMMU part of the GART. The alias of the page is
@@ -814,7 +822,7 @@ void __init gart_iommu_init(void)
* the pages as Not-Present:
*/
wbinvd();
-
+
/*
* Now all caches are flushed and we can safely enable
* GART hardware. Doing it early leaves the possibility
@@ -838,6 +846,10 @@ void __init gart_iommu_init(void)
flush_gart();
dma_ops = &gart_dma_ops;
+ x86_platform.iommu_shutdown = gart_iommu_shutdown;
+ swiotlb = 0;
+
+ return 0;
}
void __init gart_parse_options(char *p)
@@ -856,7 +868,7 @@ void __init gart_parse_options(char *p)
#endif
if (isdigit(*p) && get_option(&p, &arg))
iommu_size = arg;
- if (!strncmp(p, "fullflush", 8))
+ if (!strncmp(p, "fullflush", 9))
iommu_fullflush = 1;
if (!strncmp(p, "nofullflush", 11))
iommu_fullflush = 0;
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index a3933d4330cd..22be12b60a8f 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -33,7 +33,7 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
dma_addr_t bus = page_to_phys(page) + offset;
WARN_ON(size == 0);
if (!check_addr("map_single", dev, bus, size))
- return bad_dma_address;
+ return DMA_ERROR_CODE;
flush_write_buffers();
return bus;
}
@@ -103,12 +103,3 @@ struct dma_map_ops nommu_dma_ops = {
.sync_sg_for_device = nommu_sync_sg_for_device,
.is_phys = 1,
};
-
-void __init no_iommu_init(void)
-{
- if (dma_ops)
- return;
-
- force_iommu = 0; /* no HW IOMMU */
- dma_ops = &nommu_dma_ops;
-}
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index aaa6b7839f1e..e3c0a66b9e77 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -42,18 +42,28 @@ static struct dma_map_ops swiotlb_dma_ops = {
.dma_supported = NULL,
};
-void __init pci_swiotlb_init(void)
+/*
+ * pci_swiotlb_init - initialize swiotlb if necessary
+ *
+ * This returns non-zero if we are forced to use swiotlb (by the boot
+ * option).
+ */
+int __init pci_swiotlb_init(void)
{
+ int use_swiotlb = swiotlb | swiotlb_force;
+
/* don't initialize swiotlb if iommu=off (no_iommu=1) */
#ifdef CONFIG_X86_64
- if ((!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN))
+ if (!no_iommu && max_pfn > MAX_DMA32_PFN)
swiotlb = 1;
#endif
if (swiotlb_force)
swiotlb = 1;
+
if (swiotlb) {
- printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
- swiotlb_init();
+ swiotlb_init(0);
dma_ops = &swiotlb_dma_ops;
}
+
+ return use_swiotlb;
}
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 5284cd2b5776..744508e7cfdd 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -10,6 +10,7 @@
#include <linux/clockchips.h>
#include <linux/random.h>
#include <trace/events/power.h>
+#include <linux/hw_breakpoint.h>
#include <asm/system.h>
#include <asm/apic.h>
#include <asm/syscalls.h>
@@ -17,6 +18,7 @@
#include <asm/uaccess.h>
#include <asm/i387.h>
#include <asm/ds.h>
+#include <asm/debugreg.h>
unsigned long idle_halt;
EXPORT_SYMBOL(idle_halt);
@@ -103,14 +105,7 @@ void flush_thread(void)
}
#endif
- clear_tsk_thread_flag(tsk, TIF_DEBUG);
-
- tsk->thread.debugreg0 = 0;
- tsk->thread.debugreg1 = 0;
- tsk->thread.debugreg2 = 0;
- tsk->thread.debugreg3 = 0;
- tsk->thread.debugreg6 = 0;
- tsk->thread.debugreg7 = 0;
+ flush_ptrace_hw_breakpoint(tsk);
memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
/*
* Forget coprocessor state..
@@ -192,16 +187,6 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
else if (next->debugctlmsr != prev->debugctlmsr)
update_debugctlmsr(next->debugctlmsr);
- if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
- set_debugreg(next->debugreg0, 0);
- set_debugreg(next->debugreg1, 1);
- set_debugreg(next->debugreg2, 2);
- set_debugreg(next->debugreg3, 3);
- /* no 4 and 5 */
- set_debugreg(next->debugreg6, 6);
- set_debugreg(next->debugreg7, 7);
- }
-
if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
test_tsk_thread_flag(next_p, TIF_NOTSC)) {
/* prev and next are different */
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 4cf79567cdab..075580b35682 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -58,6 +58,7 @@
#include <asm/idle.h>
#include <asm/syscalls.h>
#include <asm/ds.h>
+#include <asm/debugreg.h>
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
@@ -134,7 +135,7 @@ void __show_regs(struct pt_regs *regs, int all)
ss = regs->ss & 0xffff;
gs = get_user_gs(regs);
} else {
- sp = (unsigned long) (&regs->sp);
+ sp = kernel_stack_pointer(regs);
savesegment(ss, ss);
savesegment(gs, gs);
}
@@ -187,7 +188,7 @@ void __show_regs(struct pt_regs *regs, int all)
void show_regs(struct pt_regs *regs)
{
- __show_regs(regs, 1);
+ show_registers(regs);
show_trace(NULL, regs, &regs->sp, regs->bp);
}
@@ -259,7 +260,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
task_user_gs(p) = get_user_gs(regs);
+ p->thread.io_bitmap_ptr = NULL;
tsk = current;
+ err = -ENOMEM;
+
+ memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+
if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
IO_BITMAP_BYTES, GFP_KERNEL);
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index ad535b683170..a98fe88fab64 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -52,6 +52,7 @@
#include <asm/idle.h>
#include <asm/syscalls.h>
#include <asm/ds.h>
+#include <asm/debugreg.h>
asmlinkage extern void ret_from_fork(void);
@@ -226,8 +227,7 @@ void __show_regs(struct pt_regs *regs, int all)
void show_regs(struct pt_regs *regs)
{
- printk(KERN_INFO "CPU %d:", smp_processor_id());
- __show_regs(regs, 1);
+ show_registers(regs);
show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
}
@@ -297,12 +297,16 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
p->thread.fs = me->thread.fs;
p->thread.gs = me->thread.gs;
+ p->thread.io_bitmap_ptr = NULL;
savesegment(gs, p->thread.gsindex);
savesegment(fs, p->thread.fsindex);
savesegment(es, p->thread.es);
savesegment(ds, p->thread.ds);
+ err = -ENOMEM;
+ memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+
if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) {
p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
if (!p->thread.io_bitmap_ptr) {
@@ -341,6 +345,7 @@ out:
kfree(p->thread.io_bitmap_ptr);
p->thread.io_bitmap_max = 0;
}
+
return err;
}
@@ -495,6 +500,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
*/
if (preload_fpu)
__math_state_restore();
+
return prev_p;
}
@@ -664,3 +670,8 @@ long sys_arch_prctl(int code, unsigned long addr)
return do_arch_prctl(current, code, addr);
}
+unsigned long KSTK_ESP(struct task_struct *task)
+{
+ return (test_tsk_thread_flag(task, TIF_IA32)) ?
+ (task_pt_regs(task)->sp) : ((task)->thread.usersp);
+}
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 7b058a2dc66a..04d182a7cfdb 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -22,6 +22,8 @@
#include <linux/seccomp.h>
#include <linux/signal.h>
#include <linux/workqueue.h>
+#include <linux/perf_event.h>
+#include <linux/hw_breakpoint.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -34,6 +36,7 @@
#include <asm/prctl.h>
#include <asm/proto.h>
#include <asm/ds.h>
+#include <asm/hw_breakpoint.h>
#include "tls.h"
@@ -49,6 +52,118 @@ enum x86_regset {
REGSET_IOPERM32,
};
+struct pt_regs_offset {
+ const char *name;
+ int offset;
+};
+
+#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+static const struct pt_regs_offset regoffset_table[] = {
+#ifdef CONFIG_X86_64
+ REG_OFFSET_NAME(r15),
+ REG_OFFSET_NAME(r14),
+ REG_OFFSET_NAME(r13),
+ REG_OFFSET_NAME(r12),
+ REG_OFFSET_NAME(r11),
+ REG_OFFSET_NAME(r10),
+ REG_OFFSET_NAME(r9),
+ REG_OFFSET_NAME(r8),
+#endif
+ REG_OFFSET_NAME(bx),
+ REG_OFFSET_NAME(cx),
+ REG_OFFSET_NAME(dx),
+ REG_OFFSET_NAME(si),
+ REG_OFFSET_NAME(di),
+ REG_OFFSET_NAME(bp),
+ REG_OFFSET_NAME(ax),
+#ifdef CONFIG_X86_32
+ REG_OFFSET_NAME(ds),
+ REG_OFFSET_NAME(es),
+ REG_OFFSET_NAME(fs),
+ REG_OFFSET_NAME(gs),
+#endif
+ REG_OFFSET_NAME(orig_ax),
+ REG_OFFSET_NAME(ip),
+ REG_OFFSET_NAME(cs),
+ REG_OFFSET_NAME(flags),
+ REG_OFFSET_NAME(sp),
+ REG_OFFSET_NAME(ss),
+ REG_OFFSET_END,
+};
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name: the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (!strcmp(roff->name, name))
+ return roff->offset;
+ return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset: the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (roff->offset == offset)
+ return roff->name;
+ return NULL;
+}
+
+static const int arg_offs_table[] = {
+#ifdef CONFIG_X86_32
+ [0] = offsetof(struct pt_regs, ax),
+ [1] = offsetof(struct pt_regs, dx),
+ [2] = offsetof(struct pt_regs, cx)
+#else /* CONFIG_X86_64 */
+ [0] = offsetof(struct pt_regs, di),
+ [1] = offsetof(struct pt_regs, si),
+ [2] = offsetof(struct pt_regs, dx),
+ [3] = offsetof(struct pt_regs, cx),
+ [4] = offsetof(struct pt_regs, r8),
+ [5] = offsetof(struct pt_regs, r9)
+#endif
+};
+
+/**
+ * regs_get_argument_nth() - get Nth argument at function call
+ * @regs: pt_regs which contains registers at function entry.
+ * @n: argument number.
+ *
+ * regs_get_argument_nth() returns @n th argument of a function call.
+ * Since usually the kernel stack will be changed right after function entry,
+ * you must use this at function entry. If the @n th entry is NOT in the
+ * kernel stack or pt_regs, this returns 0.
+ */
+unsigned long regs_get_argument_nth(struct pt_regs *regs, unsigned int n)
+{
+ if (n < ARRAY_SIZE(arg_offs_table))
+ return *(unsigned long *)((char *)regs + arg_offs_table[n]);
+ else {
+ /*
+ * The typical case: arg n is on the stack.
+ * (Note: stack[0] = return address, so skip it)
+ */
+ n -= ARRAY_SIZE(arg_offs_table);
+ return regs_get_kernel_stack_nth(regs, 1 + n);
+ }
+}
+
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
@@ -137,11 +252,6 @@ static int set_segment_reg(struct task_struct *task,
return 0;
}
-static unsigned long debugreg_addr_limit(struct task_struct *task)
-{
- return TASK_SIZE - 3;
-}
-
#else /* CONFIG_X86_64 */
#define FLAG_MASK (FLAG_MASK_32 | X86_EFLAGS_NT)
@@ -266,15 +376,6 @@ static int set_segment_reg(struct task_struct *task,
return 0;
}
-static unsigned long debugreg_addr_limit(struct task_struct *task)
-{
-#ifdef CONFIG_IA32_EMULATION
- if (test_tsk_thread_flag(task, TIF_IA32))
- return IA32_PAGE_OFFSET - 3;
-#endif
- return TASK_SIZE_MAX - 7;
-}
-
#endif /* CONFIG_X86_32 */
static unsigned long get_flags(struct task_struct *task)
@@ -454,99 +555,239 @@ static int genregs_set(struct task_struct *target,
return ret;
}
+static void ptrace_triggered(struct perf_event *bp, void *data)
+{
+ int i;
+ struct thread_struct *thread = &(current->thread);
+
+ /*
+ * Store in the virtual DR6 register the fact that the breakpoint
+ * was hit so the thread's debugger will see it.
+ */
+ for (i = 0; i < HBP_NUM; i++) {
+ if (thread->ptrace_bps[i] == bp)
+ break;
+ }
+
+ thread->debugreg6 |= (DR_TRAP0 << i);
+}
+
/*
- * This function is trivial and will be inlined by the compiler.
- * Having it separates the implementation details of debug
- * registers from the interface details of ptrace.
+ * Walk through every ptrace breakpoints for this thread and
+ * build the dr7 value on top of their attributes.
+ *
*/
-static unsigned long ptrace_get_debugreg(struct task_struct *child, int n)
+static unsigned long ptrace_get_dr7(struct perf_event *bp[])
{
- switch (n) {
- case 0: return child->thread.debugreg0;
- case 1: return child->thread.debugreg1;
- case 2: return child->thread.debugreg2;
- case 3: return child->thread.debugreg3;
- case 6: return child->thread.debugreg6;
- case 7: return child->thread.debugreg7;
+ int i;
+ int dr7 = 0;
+ struct arch_hw_breakpoint *info;
+
+ for (i = 0; i < HBP_NUM; i++) {
+ if (bp[i] && !bp[i]->attr.disabled) {
+ info = counter_arch_bp(bp[i]);
+ dr7 |= encode_dr7(i, info->len, info->type);
+ }
}
- return 0;
+
+ return dr7;
}
-static int ptrace_set_debugreg(struct task_struct *child,
- int n, unsigned long data)
+static struct perf_event *
+ptrace_modify_breakpoint(struct perf_event *bp, int len, int type,
+ struct task_struct *tsk, int disabled)
{
- int i;
+ int err;
+ int gen_len, gen_type;
+ DEFINE_BREAKPOINT_ATTR(attr);
- if (unlikely(n == 4 || n == 5))
- return -EIO;
+ /*
+ * We shoud have at least an inactive breakpoint at this
+ * slot. It means the user is writing dr7 without having
+ * written the address register first
+ */
+ if (!bp)
+ return ERR_PTR(-EINVAL);
- if (n < 4 && unlikely(data >= debugreg_addr_limit(child)))
- return -EIO;
+ err = arch_bp_generic_fields(len, type, &gen_len, &gen_type);
+ if (err)
+ return ERR_PTR(err);
- switch (n) {
- case 0: child->thread.debugreg0 = data; break;
- case 1: child->thread.debugreg1 = data; break;
- case 2: child->thread.debugreg2 = data; break;
- case 3: child->thread.debugreg3 = data; break;
+ attr = bp->attr;
+ attr.bp_len = gen_len;
+ attr.bp_type = gen_type;
+ attr.disabled = disabled;
- case 6:
- if ((data & ~0xffffffffUL) != 0)
- return -EIO;
- child->thread.debugreg6 = data;
- break;
+ return modify_user_hw_breakpoint(bp, &attr, bp->callback, tsk);
+}
+
+/*
+ * Handle ptrace writes to debug register 7.
+ */
+static int ptrace_write_dr7(struct task_struct *tsk, unsigned long data)
+{
+ struct thread_struct *thread = &(tsk->thread);
+ unsigned long old_dr7;
+ int i, orig_ret = 0, rc = 0;
+ int enabled, second_pass = 0;
+ unsigned len, type;
+ struct perf_event *bp;
+
+ data &= ~DR_CONTROL_RESERVED;
+ old_dr7 = ptrace_get_dr7(thread->ptrace_bps);
+restore:
+ /*
+ * Loop through all the hardware breakpoints, making the
+ * appropriate changes to each.
+ */
+ for (i = 0; i < HBP_NUM; i++) {
+ enabled = decode_dr7(data, i, &len, &type);
+ bp = thread->ptrace_bps[i];
+
+ if (!enabled) {
+ if (bp) {
+ /*
+ * Don't unregister the breakpoints right-away,
+ * unless all register_user_hw_breakpoint()
+ * requests have succeeded. This prevents
+ * any window of opportunity for debug
+ * register grabbing by other users.
+ */
+ if (!second_pass)
+ continue;
+
+ thread->ptrace_bps[i] = NULL;
+ bp = ptrace_modify_breakpoint(bp, len, type,
+ tsk, 1);
+ if (IS_ERR(bp)) {
+ rc = PTR_ERR(bp);
+ thread->ptrace_bps[i] = NULL;
+ break;
+ }
+ thread->ptrace_bps[i] = bp;
+ }
+ continue;
+ }
+
+ bp = ptrace_modify_breakpoint(bp, len, type, tsk, 0);
+
+ /* Incorrect bp, or we have a bug in bp API */
+ if (IS_ERR(bp)) {
+ rc = PTR_ERR(bp);
+ thread->ptrace_bps[i] = NULL;
+ break;
+ }
+ thread->ptrace_bps[i] = bp;
+ }
+ /*
+ * Make a second pass to free the remaining unused breakpoints
+ * or to restore the original breakpoints if an error occurred.
+ */
+ if (!second_pass) {
+ second_pass = 1;
+ if (rc < 0) {
+ orig_ret = rc;
+ data = old_dr7;
+ }
+ goto restore;
+ }
+ return ((orig_ret < 0) ? orig_ret : rc);
+}
+
+/*
+ * Handle PTRACE_PEEKUSR calls for the debug register area.
+ */
+static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
+{
+ struct thread_struct *thread = &(tsk->thread);
+ unsigned long val = 0;
- case 7:
+ if (n < HBP_NUM) {
+ struct perf_event *bp;
+ bp = thread->ptrace_bps[n];
+ if (!bp)
+ return 0;
+ val = bp->hw.info.address;
+ } else if (n == 6) {
+ val = thread->debugreg6;
+ } else if (n == 7) {
+ val = ptrace_get_dr7(thread->ptrace_bps);
+ }
+ return val;
+}
+
+static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
+ unsigned long addr)
+{
+ struct perf_event *bp;
+ struct thread_struct *t = &tsk->thread;
+ DEFINE_BREAKPOINT_ATTR(attr);
+
+ if (!t->ptrace_bps[nr]) {
/*
- * Sanity-check data. Take one half-byte at once with
- * check = (val >> (16 + 4*i)) & 0xf. It contains the
- * R/Wi and LENi bits; bits 0 and 1 are R/Wi, and bits
- * 2 and 3 are LENi. Given a list of invalid values,
- * we do mask |= 1 << invalid_value, so that
- * (mask >> check) & 1 is a correct test for invalid
- * values.
- *
- * R/Wi contains the type of the breakpoint /
- * watchpoint, LENi contains the length of the watched
- * data in the watchpoint case.
- *
- * The invalid values are:
- * - LENi == 0x10 (undefined), so mask |= 0x0f00. [32-bit]
- * - R/Wi == 0x10 (break on I/O reads or writes), so
- * mask |= 0x4444.
- * - R/Wi == 0x00 && LENi != 0x00, so we have mask |=
- * 0x1110.
- *
- * Finally, mask = 0x0f00 | 0x4444 | 0x1110 == 0x5f54.
- *
- * See the Intel Manual "System Programming Guide",
- * 15.2.4
- *
- * Note that LENi == 0x10 is defined on x86_64 in long
- * mode (i.e. even for 32-bit userspace software, but
- * 64-bit kernel), so the x86_64 mask value is 0x5454.
- * See the AMD manual no. 24593 (AMD64 System Programming)
+ * Put stub len and type to register (reserve) an inactive but
+ * correct bp
*/
-#ifdef CONFIG_X86_32
-#define DR7_MASK 0x5f54
-#else
-#define DR7_MASK 0x5554
-#endif
- data &= ~DR_CONTROL_RESERVED;
- for (i = 0; i < 4; i++)
- if ((DR7_MASK >> ((data >> (16 + 4*i)) & 0xf)) & 1)
- return -EIO;
- child->thread.debugreg7 = data;
- if (data)
- set_tsk_thread_flag(child, TIF_DEBUG);
- else
- clear_tsk_thread_flag(child, TIF_DEBUG);
- break;
+ attr.bp_addr = addr;
+ attr.bp_len = HW_BREAKPOINT_LEN_1;
+ attr.bp_type = HW_BREAKPOINT_W;
+ attr.disabled = 1;
+
+ bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk);
+ } else {
+ bp = t->ptrace_bps[nr];
+ t->ptrace_bps[nr] = NULL;
+
+ attr = bp->attr;
+ attr.bp_addr = addr;
+ bp = modify_user_hw_breakpoint(bp, &attr, bp->callback, tsk);
}
+ /*
+ * CHECKME: the previous code returned -EIO if the addr wasn't a
+ * valid task virtual addr. The new one will return -EINVAL in this
+ * case.
+ * -EINVAL may be what we want for in-kernel breakpoints users, but
+ * -EIO looks better for ptrace, since we refuse a register writing
+ * for the user. And anyway this is the previous behaviour.
+ */
+ if (IS_ERR(bp))
+ return PTR_ERR(bp);
+
+ t->ptrace_bps[nr] = bp;
return 0;
}
/*
+ * Handle PTRACE_POKEUSR calls for the debug register area.
+ */
+int ptrace_set_debugreg(struct task_struct *tsk, int n, unsigned long val)
+{
+ struct thread_struct *thread = &(tsk->thread);
+ int rc = 0;
+
+ /* There are no DR4 or DR5 registers */
+ if (n == 4 || n == 5)
+ return -EIO;
+
+ if (n == 6) {
+ thread->debugreg6 = val;
+ goto ret_path;
+ }
+ if (n < HBP_NUM) {
+ rc = ptrace_set_breakpoint_addr(tsk, n, val);
+ if (rc)
+ return rc;
+ }
+ /* All that's left is DR7 */
+ if (n == 7)
+ rc = ptrace_write_dr7(tsk, val);
+
+ret_path:
+ return rc;
+}
+
+/*
* These access the current or another (stopped) task's io permission
* bitmap for debugging or core dump.
*/
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index a1a3cdda06e1..2b97fc5b124e 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -23,7 +23,7 @@
# include <linux/ctype.h>
# include <linux/mc146818rtc.h>
#else
-# include <asm/iommu.h>
+# include <asm/x86_init.h>
#endif
/*
@@ -436,6 +436,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5"),
},
},
+ { /* Handle problems with rebooting on Apple Macmini3,1 */
+ .callback = set_pci_reboot,
+ .ident = "Apple Macmini3,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"),
+ },
+ },
{ }
};
@@ -614,7 +622,7 @@ void native_machine_shutdown(void)
#endif
#ifdef CONFIG_X86_64
- pci_iommu_shutdown();
+ x86_platform.iommu_shutdown();
#endif
}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index e09f0e2c14b5..82e88cdda9bc 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -109,6 +109,7 @@
#ifdef CONFIG_X86_64
#include <asm/numa_64.h>
#endif
+#include <asm/mce.h>
/*
* end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
@@ -247,7 +248,7 @@ EXPORT_SYMBOL(edd);
* from boot_params into a safe place.
*
*/
-static inline void copy_edd(void)
+static inline void __init copy_edd(void)
{
memcpy(edd.mbr_signature, boot_params.edd_mbr_sig_buffer,
sizeof(edd.mbr_signature));
@@ -256,7 +257,7 @@ static inline void copy_edd(void)
edd.edd_info_nr = boot_params.eddbuf_entries;
}
#else
-static inline void copy_edd(void)
+static inline void __init copy_edd(void)
{
}
#endif
@@ -660,6 +661,13 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
},
},
{
+ .callback = dmi_low_memory_corruption,
+ .ident = "Phoenix/MSC BIOS",
+ .matches = {
+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix/MSC"),
+ },
+ },
+ {
/*
* AMI BIOS with low memory corruption was found on Intel DG45ID board.
* It hase different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
@@ -1024,6 +1032,8 @@ void __init setup_arch(char **cmdline_p)
#endif
#endif
x86_init.oem.banner();
+
+ mcheck_init();
}
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 6a44a76055ad..fbf3b07c8567 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -799,15 +799,6 @@ static void do_signal(struct pt_regs *regs)
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
- /*
- * Re-enable any watchpoints before delivering the
- * signal to user space. The processor register will
- * have been cleared if the watchpoint triggered
- * inside the kernel.
- */
- if (current->thread.debugreg7)
- set_debugreg(current->thread.debugreg7, 7);
-
/* Whee! Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
/*
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index d915d956e66d..ec1de97600e7 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -198,7 +198,6 @@ void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
inc_irq_stat(irq_resched_count);
- run_local_timers();
/*
* KVM uses this interrupt to force a cpu out of guest mode
*/
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 565ebc65920e..324f2a44c221 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1250,16 +1250,7 @@ static void __ref remove_cpu_from_maps(int cpu)
void cpu_disable_common(void)
{
int cpu = smp_processor_id();
- /*
- * HACK:
- * Allow any queued timer interrupts to get serviced
- * This is only a temporary solution until we cleanup
- * fixup_irqs as we do for IA64.
- */
- local_irq_enable();
- mdelay(1);
- local_irq_disable();
remove_siblinginfo(cpu);
/* It's now safe to remove this processor from the online map */
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index dcb00d278512..be2573448ed9 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -38,7 +38,8 @@ unsigned long profile_pc(struct pt_regs *regs)
#ifdef CONFIG_FRAME_POINTER
return *(unsigned long *)(regs->bp + sizeof(long));
#else
- unsigned long *sp = (unsigned long *)regs->sp;
+ unsigned long *sp =
+ (unsigned long *)kernel_stack_pointer(regs);
/*
* Return address is either directly at stack pointer
* or above a saved flags. Eflags has bits 22-31 zero,
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 503c1f2e8835..1740c85e24bb 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -23,8 +23,6 @@
static struct bau_control **uv_bau_table_bases __read_mostly;
static int uv_bau_retry_limit __read_mostly;
-/* position of pnode (which is nasid>>1): */
-static int uv_nshift __read_mostly;
/* base pnode in this partition */
static int uv_partition_base_pnode __read_mostly;
@@ -723,7 +721,7 @@ uv_activation_descriptor_init(int node, int pnode)
BUG_ON(!adp);
pa = uv_gpa(adp); /* need the real nasid*/
- n = pa >> uv_nshift;
+ n = uv_gpa_to_pnode(pa);
m = pa & uv_mmask;
uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE,
@@ -778,7 +776,7 @@ uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp)
* need the pnode of where the memory was really allocated
*/
pa = uv_gpa(pqp);
- pn = pa >> uv_nshift;
+ pn = uv_gpa_to_pnode(pa);
uv_write_global_mmr64(pnode,
UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST,
((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) |
@@ -843,8 +841,7 @@ static int __init uv_bau_init(void)
GFP_KERNEL, cpu_to_node(cur_cpu));
uv_bau_retry_limit = 1;
- uv_nshift = uv_hub_info->n_val;
- uv_mmask = (1UL << uv_hub_info->n_val) - 1;
+ uv_mmask = (1UL << uv_hub_info->m_val) - 1;
nblades = uv_num_possible_blades();
uv_bau_table_bases = (struct bau_control **)
diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c
index 699f7eeb896a..cd022121cab6 100644
--- a/arch/x86/kernel/trampoline.c
+++ b/arch/x86/kernel/trampoline.c
@@ -3,8 +3,16 @@
#include <asm/trampoline.h>
#include <asm/e820.h>
+#if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP)
+#define __trampinit
+#define __trampinitdata
+#else
+#define __trampinit __cpuinit
+#define __trampinitdata __cpuinitdata
+#endif
+
/* ready for x86_64 and x86 */
-unsigned char *__cpuinitdata trampoline_base = __va(TRAMPOLINE_BASE);
+unsigned char *__trampinitdata trampoline_base = __va(TRAMPOLINE_BASE);
void __init reserve_trampoline_memory(void)
{
@@ -26,7 +34,7 @@ void __init reserve_trampoline_memory(void)
* bootstrap into the page concerned. The caller
* has made sure it's suitably aligned.
*/
-unsigned long __cpuinit setup_trampoline(void)
+unsigned long __trampinit setup_trampoline(void)
{
memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE);
return virt_to_phys(trampoline_base);
diff --git a/arch/x86/kernel/trampoline_64.S b/arch/x86/kernel/trampoline_64.S
index 596d54c660a5..3af2dff58b21 100644
--- a/arch/x86/kernel/trampoline_64.S
+++ b/arch/x86/kernel/trampoline_64.S
@@ -32,8 +32,12 @@
#include <asm/segment.h>
#include <asm/processor-flags.h>
+#ifdef CONFIG_ACPI_SLEEP
+.section .rodata, "a", @progbits
+#else
/* We can free up the trampoline after bootup if cpu hotplug is not supported. */
__CPUINITRODATA
+#endif
.code16
ENTRY(trampoline_data)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 7e37dcee0cc3..33399176512a 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -529,77 +529,56 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
{
struct task_struct *tsk = current;
- unsigned long condition;
+ unsigned long dr6;
int si_code;
- get_debugreg(condition, 6);
+ get_debugreg(dr6, 6);
/* Catch kmemcheck conditions first of all! */
- if (condition & DR_STEP && kmemcheck_trap(regs))
+ if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
return;
+ /* DR6 may or may not be cleared by the CPU */
+ set_debugreg(0, 6);
/*
* The processor cleared BTF, so don't mark that we need it set.
*/
clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
tsk->thread.debugctlmsr = 0;
- if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
- SIGTRAP) == NOTIFY_STOP)
+ /* Store the virtualized DR6 value */
+ tsk->thread.debugreg6 = dr6;
+
+ if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code,
+ SIGTRAP) == NOTIFY_STOP)
return;
/* It's safe to allow irq's after DR6 has been saved */
preempt_conditional_sti(regs);
- /* Mask out spurious debug traps due to lazy DR7 setting */
- if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
- if (!tsk->thread.debugreg7)
- goto clear_dr7;
+ if (regs->flags & X86_VM_MASK) {
+ handle_vm86_trap((struct kernel_vm86_regs *) regs,
+ error_code, 1);
+ return;
}
-#ifdef CONFIG_X86_32
- if (regs->flags & X86_VM_MASK)
- goto debug_vm86;
-#endif
-
- /* Save debug status register where ptrace can see it */
- tsk->thread.debugreg6 = condition;
-
/*
- * Single-stepping through TF: make sure we ignore any events in
- * kernel space (but re-enable TF when returning to user mode).
+ * Single-stepping through system calls: ignore any exceptions in
+ * kernel space, but re-enable TF when returning to user mode.
+ *
+ * We already checked v86 mode above, so we can check for kernel mode
+ * by just checking the CPL of CS.
*/
- if (condition & DR_STEP) {
- if (!user_mode(regs))
- goto clear_TF_reenable;
+ if ((dr6 & DR_STEP) && !user_mode(regs)) {
+ tsk->thread.debugreg6 &= ~DR_STEP;
+ set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+ regs->flags &= ~X86_EFLAGS_TF;
}
-
- si_code = get_si_code(condition);
- /* Ok, finally something we can handle */
- send_sigtrap(tsk, regs, error_code, si_code);
-
- /*
- * Disable additional traps. They'll be re-enabled when
- * the signal is delivered.
- */
-clear_dr7:
- set_debugreg(0, 7);
+ si_code = get_si_code(tsk->thread.debugreg6);
+ if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS))
+ send_sigtrap(tsk, regs, error_code, si_code);
preempt_conditional_cli(regs);
- return;
-#ifdef CONFIG_X86_32
-debug_vm86:
- /* reenable preemption: handle_vm86_trap() might sleep */
- dec_preempt_count();
- handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
- conditional_cli(regs);
- return;
-#endif
-
-clear_TF_reenable:
- set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
- regs->flags &= ~X86_EFLAGS_TF;
- preempt_conditional_cli(regs);
return;
}
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index f37930954d15..eed156851f5d 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -114,13 +114,12 @@ void __cpuinit check_tsc_sync_source(int cpu)
return;
if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
- printk_once(KERN_INFO "Skipping synchronization checks as TSC is reliable.\n");
+ if (cpu == (nr_cpu_ids-1) || system_state != SYSTEM_BOOTING)
+ pr_info(
+ "Skipped synchronization checks as TSC is reliable.\n");
return;
}
- pr_info("checking TSC synchronization [CPU#%d -> CPU#%d]:",
- smp_processor_id(), cpu);
-
/*
* Reset it - in case this is a second bootup:
*/
@@ -142,12 +141,14 @@ void __cpuinit check_tsc_sync_source(int cpu)
cpu_relax();
if (nr_warps) {
- printk("\n");
+ pr_warning("TSC synchronization [CPU#%d -> CPU#%d]:\n",
+ smp_processor_id(), cpu);
pr_warning("Measured %Ld cycles TSC warp between CPUs, "
"turning off TSC clock.\n", max_warp);
mark_tsc_unstable("check_tsc_sync_source failed");
} else {
- printk(" passed.\n");
+ pr_debug("TSC synchronization [CPU#%d -> CPU#%d]: passed\n",
+ smp_processor_id(), cpu);
}
/*
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
index aeef529917e4..61d805df4c91 100644
--- a/arch/x86/kernel/uv_irq.c
+++ b/arch/x86/kernel/uv_irq.c
@@ -9,10 +9,25 @@
*/
#include <linux/module.h>
+#include <linux/rbtree.h>
#include <linux/irq.h>
#include <asm/apic.h>
#include <asm/uv/uv_irq.h>
+#include <asm/uv/uv_hub.h>
+
+/* MMR offset and pnode of hub sourcing interrupts for a given irq */
+struct uv_irq_2_mmr_pnode{
+ struct rb_node list;
+ unsigned long offset;
+ int pnode;
+ int irq;
+};
+
+static spinlock_t uv_irq_lock;
+static struct rb_root uv_irq_root;
+
+static int uv_set_irq_affinity(unsigned int, const struct cpumask *);
static void uv_noop(unsigned int irq)
{
@@ -39,25 +54,214 @@ struct irq_chip uv_irq_chip = {
.unmask = uv_noop,
.eoi = uv_ack_apic,
.end = uv_noop,
+ .set_affinity = uv_set_irq_affinity,
};
/*
+ * Add offset and pnode information of the hub sourcing interrupts to the
+ * rb tree for a specific irq.
+ */
+static int uv_set_irq_2_mmr_info(int irq, unsigned long offset, unsigned blade)
+{
+ struct rb_node **link = &uv_irq_root.rb_node;
+ struct rb_node *parent = NULL;
+ struct uv_irq_2_mmr_pnode *n;
+ struct uv_irq_2_mmr_pnode *e;
+ unsigned long irqflags;
+
+ n = kmalloc_node(sizeof(struct uv_irq_2_mmr_pnode), GFP_KERNEL,
+ uv_blade_to_memory_nid(blade));
+ if (!n)
+ return -ENOMEM;
+
+ n->irq = irq;
+ n->offset = offset;
+ n->pnode = uv_blade_to_pnode(blade);
+ spin_lock_irqsave(&uv_irq_lock, irqflags);
+ /* Find the right place in the rbtree: */
+ while (*link) {
+ parent = *link;
+ e = rb_entry(parent, struct uv_irq_2_mmr_pnode, list);
+
+ if (unlikely(irq == e->irq)) {
+ /* irq entry exists */
+ e->pnode = uv_blade_to_pnode(blade);
+ e->offset = offset;
+ spin_unlock_irqrestore(&uv_irq_lock, irqflags);
+ kfree(n);
+ return 0;
+ }
+
+ if (irq < e->irq)
+ link = &(*link)->rb_left;
+ else
+ link = &(*link)->rb_right;
+ }
+
+ /* Insert the node into the rbtree. */
+ rb_link_node(&n->list, parent, link);
+ rb_insert_color(&n->list, &uv_irq_root);
+
+ spin_unlock_irqrestore(&uv_irq_lock, irqflags);
+ return 0;
+}
+
+/* Retrieve offset and pnode information from the rb tree for a specific irq */
+int uv_irq_2_mmr_info(int irq, unsigned long *offset, int *pnode)
+{
+ struct uv_irq_2_mmr_pnode *e;
+ struct rb_node *n;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&uv_irq_lock, irqflags);
+ n = uv_irq_root.rb_node;
+ while (n) {
+ e = rb_entry(n, struct uv_irq_2_mmr_pnode, list);
+
+ if (e->irq == irq) {
+ *offset = e->offset;
+ *pnode = e->pnode;
+ spin_unlock_irqrestore(&uv_irq_lock, irqflags);
+ return 0;
+ }
+
+ if (irq < e->irq)
+ n = n->rb_left;
+ else
+ n = n->rb_right;
+ }
+ spin_unlock_irqrestore(&uv_irq_lock, irqflags);
+ return -1;
+}
+
+/*
+ * Re-target the irq to the specified CPU and enable the specified MMR located
+ * on the specified blade to allow the sending of MSIs to the specified CPU.
+ */
+static int
+arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
+ unsigned long mmr_offset, int restrict)
+{
+ const struct cpumask *eligible_cpu = cpumask_of(cpu);
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_cfg *cfg;
+ int mmr_pnode;
+ unsigned long mmr_value;
+ struct uv_IO_APIC_route_entry *entry;
+ int err;
+
+ BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) !=
+ sizeof(unsigned long));
+
+ cfg = irq_cfg(irq);
+
+ err = assign_irq_vector(irq, cfg, eligible_cpu);
+ if (err != 0)
+ return err;
+
+ if (restrict == UV_AFFINITY_CPU)
+ desc->status |= IRQ_NO_BALANCING;
+ else
+ desc->status |= IRQ_MOVE_PCNTXT;
+
+ set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
+ irq_name);
+
+ mmr_value = 0;
+ entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+ entry->vector = cfg->vector;
+ entry->delivery_mode = apic->irq_delivery_mode;
+ entry->dest_mode = apic->irq_dest_mode;
+ entry->polarity = 0;
+ entry->trigger = 0;
+ entry->mask = 0;
+ entry->dest = apic->cpu_mask_to_apicid(eligible_cpu);
+
+ mmr_pnode = uv_blade_to_pnode(mmr_blade);
+ uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+
+ if (cfg->move_in_progress)
+ send_cleanup_vector(cfg);
+
+ return irq;
+}
+
+/*
+ * Disable the specified MMR located on the specified blade so that MSIs are
+ * longer allowed to be sent.
+ */
+static void arch_disable_uv_irq(int mmr_pnode, unsigned long mmr_offset)
+{
+ unsigned long mmr_value;
+ struct uv_IO_APIC_route_entry *entry;
+
+ BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) !=
+ sizeof(unsigned long));
+
+ mmr_value = 0;
+ entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+ entry->mask = 1;
+
+ uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+}
+
+static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_cfg *cfg = desc->chip_data;
+ unsigned int dest;
+ unsigned long mmr_value;
+ struct uv_IO_APIC_route_entry *entry;
+ unsigned long mmr_offset;
+ unsigned mmr_pnode;
+
+ dest = set_desc_affinity(desc, mask);
+ if (dest == BAD_APICID)
+ return -1;
+
+ mmr_value = 0;
+ entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+
+ entry->vector = cfg->vector;
+ entry->delivery_mode = apic->irq_delivery_mode;
+ entry->dest_mode = apic->irq_dest_mode;
+ entry->polarity = 0;
+ entry->trigger = 0;
+ entry->mask = 0;
+ entry->dest = dest;
+
+ /* Get previously stored MMR and pnode of hub sourcing interrupts */
+ if (uv_irq_2_mmr_info(irq, &mmr_offset, &mmr_pnode))
+ return -1;
+
+ uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+
+ if (cfg->move_in_progress)
+ send_cleanup_vector(cfg);
+
+ return 0;
+}
+
+/*
* Set up a mapping of an available irq and vector, and enable the specified
* MMR that defines the MSI that is to be sent to the specified CPU when an
* interrupt is raised.
*/
int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
- unsigned long mmr_offset)
+ unsigned long mmr_offset, int restrict)
{
- int irq;
- int ret;
+ int irq, ret;
+
+ irq = create_irq_nr(NR_IRQS_LEGACY, uv_blade_to_memory_nid(mmr_blade));
- irq = create_irq();
if (irq <= 0)
return -EBUSY;
- ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset);
- if (ret != irq)
+ ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset,
+ restrict);
+ if (ret == irq)
+ uv_set_irq_2_mmr_info(irq, mmr_offset, mmr_blade);
+ else
destroy_irq(irq);
return ret;
@@ -71,9 +275,28 @@ EXPORT_SYMBOL_GPL(uv_setup_irq);
*
* Set mmr_blade and mmr_offset to what was passed in on uv_setup_irq().
*/
-void uv_teardown_irq(unsigned int irq, int mmr_blade, unsigned long mmr_offset)
+void uv_teardown_irq(unsigned int irq)
{
- arch_disable_uv_irq(mmr_blade, mmr_offset);
+ struct uv_irq_2_mmr_pnode *e;
+ struct rb_node *n;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&uv_irq_lock, irqflags);
+ n = uv_irq_root.rb_node;
+ while (n) {
+ e = rb_entry(n, struct uv_irq_2_mmr_pnode, list);
+ if (e->irq == irq) {
+ arch_disable_uv_irq(e->pnode, e->offset);
+ rb_erase(n, &uv_irq_root);
+ kfree(e);
+ break;
+ }
+ if (irq < e->irq)
+ n = n->rb_left;
+ else
+ n = n->rb_right;
+ }
+ spin_unlock_irqrestore(&uv_irq_lock, irqflags);
destroy_irq(irq);
}
EXPORT_SYMBOL_GPL(uv_teardown_irq);
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c
index f068553a1b17..abda6f53e71e 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/kernel/visws_quirks.c
@@ -183,7 +183,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
return;
}
- apic_cpus = apic->apicid_to_cpu_present(m->apicid);
+ apic->apicid_to_cpu_present(m->apicid, &apic_cpus);
physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
/*
* Validate version
@@ -486,7 +486,7 @@ static void end_cobalt_irq(unsigned int irq)
}
static struct irq_chip cobalt_irq_type = {
- .typename = "Cobalt-APIC",
+ .name = "Cobalt-APIC",
.startup = startup_cobalt_irq,
.shutdown = disable_cobalt_irq,
.enable = enable_cobalt_irq,
@@ -523,7 +523,7 @@ static void end_piix4_master_irq(unsigned int irq)
}
static struct irq_chip piix4_master_irq_type = {
- .typename = "PIIX4-master",
+ .name = "PIIX4-master",
.startup = startup_piix4_master_irq,
.ack = ack_cobalt_irq,
.end = end_piix4_master_irq,
@@ -531,7 +531,7 @@ static struct irq_chip piix4_master_irq_type = {
static struct irq_chip piix4_virtual_irq_type = {
- .typename = "PIIX4-virtual",
+ .name = "PIIX4-virtual",
.shutdown = disable_8259A_irq,
.enable = enable_8259A_irq,
.disable = disable_8259A_irq,
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index 31e6f6cfe53e..d430e4c30193 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -648,7 +648,7 @@ static inline int __init activate_vmi(void)
pv_info.paravirt_enabled = 1;
pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
- pv_info.name = "vmi";
+ pv_info.name = "vmi [deprecated]";
pv_init_ops.patch = vmi_patch;
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 92929fb3f9fa..3c68fe2d46cf 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -305,6 +305,9 @@ SECTIONS
#ifdef CONFIG_X86_32
+/*
+ * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
+ */
. = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
"kernel image bigger than KERNEL_IMAGE_SIZE");
#else
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
index 3909e3ba5ce3..a1029769b6f2 100644
--- a/arch/x86/kernel/x8664_ksyms_64.c
+++ b/arch/x86/kernel/x8664_ksyms_64.c
@@ -30,9 +30,8 @@ EXPORT_SYMBOL(__put_user_8);
EXPORT_SYMBOL(copy_user_generic);
EXPORT_SYMBOL(__copy_user_nocache);
-EXPORT_SYMBOL(copy_from_user);
-EXPORT_SYMBOL(copy_to_user);
-EXPORT_SYMBOL(__copy_from_user_inatomic);
+EXPORT_SYMBOL(_copy_from_user);
+EXPORT_SYMBOL(_copy_to_user);
EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(clear_page);
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 4449a4a2c2ed..d11c5ff7c65e 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -14,10 +14,13 @@
#include <asm/time.h>
#include <asm/irq.h>
#include <asm/tsc.h>
+#include <asm/iommu.h>
void __cpuinit x86_init_noop(void) { }
void __init x86_init_uint_noop(unsigned int unused) { }
void __init x86_init_pgd_noop(pgd_t *unused) { }
+int __init iommu_init_noop(void) { return 0; }
+void iommu_shutdown_noop(void) { }
/*
* The platform setup functions are preset with the default functions
@@ -62,6 +65,10 @@ struct x86_init_ops x86_init __initdata = {
.tsc_pre_init = x86_init_noop,
.timer_init = hpet_time_init,
},
+
+ .iommu = {
+ .iommu_init = iommu_init_noop,
+ },
};
struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
@@ -72,4 +79,5 @@ struct x86_platform_ops x86_platform = {
.calibrate_tsc = native_calibrate_tsc,
.get_wallclock = mach_get_cmos_time,
.set_wallclock = mach_set_rtc_mmss,
+ .iommu_shutdown = iommu_shutdown_noop,
};
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 82ad523b4901..144e7f60b5e2 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -116,7 +116,7 @@ static s64 __kpit_elapsed(struct kvm *kvm)
* itself with the initial count and continues counting
* from there.
*/
- remaining = hrtimer_expires_remaining(&ps->pit_timer.timer);
+ remaining = hrtimer_get_remaining(&ps->pit_timer.timer);
elapsed = ps->pit_timer.period - ktime_to_ns(remaining);
elapsed = mod_64(elapsed, ps->pit_timer.period);
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 7024224f0fc8..23c217692ea9 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -521,7 +521,7 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
if (apic_get_reg(apic, APIC_TMICT) == 0)
return 0;
- remaining = hrtimer_expires_remaining(&apic->lapic_timer.timer);
+ remaining = hrtimer_get_remaining(&apic->lapic_timer.timer);
if (ktime_to_ns(remaining) < 0)
remaining = ktime_set(0, 0);
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 685a4ffac8e6..818b92ad82cf 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -748,7 +748,8 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
return write_protected;
}
-static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
+static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
+ unsigned long data)
{
u64 *spte;
int need_tlb_flush = 0;
@@ -763,7 +764,8 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
return need_tlb_flush;
}
-static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
+static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
+ unsigned long data)
{
int need_flush = 0;
u64 *spte, new_spte;
@@ -799,9 +801,10 @@ static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
return 0;
}
-static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, u64 data,
+static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
+ unsigned long data,
int (*handler)(struct kvm *kvm, unsigned long *rmapp,
- u64 data))
+ unsigned long data))
{
int i, j;
int retval = 0;
@@ -846,10 +849,11 @@ int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
{
- kvm_handle_hva(kvm, hva, (u64)&pte, kvm_set_pte_rmapp);
+ kvm_handle_hva(kvm, hva, (unsigned long)&pte, kvm_set_pte_rmapp);
}
-static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
+static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
+ unsigned long data)
{
u64 *spte;
int young = 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9b9695322f56..4fc80174191c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -42,6 +42,7 @@
#define CREATE_TRACE_POINTS
#include "trace.h"
+#include <asm/debugreg.h>
#include <asm/uaccess.h>
#include <asm/msr.h>
#include <asm/desc.h>
@@ -1692,7 +1693,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
unsigned bank_num = mcg_cap & 0xff, bank;
r = -EINVAL;
- if (!bank_num)
+ if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS)
goto out;
if (mcg_cap & ~(KVM_MCE_CAP_SUPPORTED | 0xff | 0xff0000))
goto out;
@@ -3643,14 +3644,15 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
trace_kvm_entry(vcpu->vcpu_id);
kvm_x86_ops->run(vcpu, kvm_run);
- if (unlikely(vcpu->arch.switch_db_regs || test_thread_flag(TIF_DEBUG))) {
- set_debugreg(current->thread.debugreg0, 0);
- set_debugreg(current->thread.debugreg1, 1);
- set_debugreg(current->thread.debugreg2, 2);
- set_debugreg(current->thread.debugreg3, 3);
- set_debugreg(current->thread.debugreg6, 6);
- set_debugreg(current->thread.debugreg7, 7);
- }
+ /*
+ * If the guest has used debug registers, at least dr7
+ * will be disabled while returning to the host.
+ * If we don't have active breakpoints in the host, we don't
+ * care about the messed up debug address registers. But if
+ * we have some of them active, restore the old state.
+ */
+ if (hw_breakpoint_active())
+ hw_breakpoint_restore();
set_bit(KVM_REQ_KICK, &vcpu->requests);
local_irq_enable();
@@ -4051,7 +4053,7 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
}
-static u32 get_tss_base_addr(struct kvm_vcpu *vcpu,
+static gpa_t get_tss_base_addr(struct kvm_vcpu *vcpu,
struct desc_struct *seg_desc)
{
u32 base_addr = get_desc_base(seg_desc);
diff --git a/arch/x86/lib/.gitignore b/arch/x86/lib/.gitignore
new file mode 100644
index 000000000000..8df89f0a3fe6
--- /dev/null
+++ b/arch/x86/lib/.gitignore
@@ -0,0 +1 @@
+inat-tables.c
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 85f5db95c60f..a2d6472895fb 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -2,12 +2,25 @@
# Makefile for x86 specific library files.
#
+inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk
+inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
+quiet_cmd_inat_tables = GEN $@
+ cmd_inat_tables = $(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@
+
+$(obj)/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
+ $(call cmd,inat_tables)
+
+$(obj)/inat.o: $(obj)/inat-tables.c
+
+clean-files := inat-tables.c
+
obj-$(CONFIG_SMP) := msr.o
lib-y := delay.o
lib-y += thunk_$(BITS).o
lib-y += usercopy_$(BITS).o getuser.o putuser.o
lib-y += memcpy_$(BITS).o
+lib-y += insn.o inat.o
obj-y += msr-reg.o msr-reg-export.o
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
index 6ba0f7bb85ea..cf889d4e076a 100644
--- a/arch/x86/lib/copy_user_64.S
+++ b/arch/x86/lib/copy_user_64.S
@@ -65,7 +65,7 @@
.endm
/* Standard copy_to_user with segment limit checking */
-ENTRY(copy_to_user)
+ENTRY(_copy_to_user)
CFI_STARTPROC
GET_THREAD_INFO(%rax)
movq %rdi,%rcx
@@ -75,10 +75,10 @@ ENTRY(copy_to_user)
jae bad_to_user
ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
CFI_ENDPROC
-ENDPROC(copy_to_user)
+ENDPROC(_copy_to_user)
/* Standard copy_from_user with segment limit checking */
-ENTRY(copy_from_user)
+ENTRY(_copy_from_user)
CFI_STARTPROC
GET_THREAD_INFO(%rax)
movq %rsi,%rcx
@@ -88,7 +88,7 @@ ENTRY(copy_from_user)
jae bad_from_user
ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
CFI_ENDPROC
-ENDPROC(copy_from_user)
+ENDPROC(_copy_from_user)
ENTRY(copy_user_generic)
CFI_STARTPROC
@@ -96,12 +96,6 @@ ENTRY(copy_user_generic)
CFI_ENDPROC
ENDPROC(copy_user_generic)
-ENTRY(__copy_from_user_inatomic)
- CFI_STARTPROC
- ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
- CFI_ENDPROC
-ENDPROC(__copy_from_user_inatomic)
-
.section .fixup,"ax"
/* must zero dest */
ENTRY(bad_from_user)
diff --git a/arch/x86/lib/inat.c b/arch/x86/lib/inat.c
new file mode 100644
index 000000000000..46fc4ee09fc4
--- /dev/null
+++ b/arch/x86/lib/inat.c
@@ -0,0 +1,90 @@
+/*
+ * x86 instruction attribute tables
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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 <asm/insn.h>
+
+/* Attribute tables are generated from opcode map */
+#include "inat-tables.c"
+
+/* Attribute search APIs */
+insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
+{
+ return inat_primary_table[opcode];
+}
+
+insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, insn_byte_t last_pfx,
+ insn_attr_t esc_attr)
+{
+ const insn_attr_t *table;
+ insn_attr_t lpfx_attr;
+ int n, m = 0;
+
+ n = inat_escape_id(esc_attr);
+ if (last_pfx) {
+ lpfx_attr = inat_get_opcode_attribute(last_pfx);
+ m = inat_last_prefix_id(lpfx_attr);
+ }
+ table = inat_escape_tables[n][0];
+ if (!table)
+ return 0;
+ if (inat_has_variant(table[opcode]) && m) {
+ table = inat_escape_tables[n][m];
+ if (!table)
+ return 0;
+ }
+ return table[opcode];
+}
+
+insn_attr_t inat_get_group_attribute(insn_byte_t modrm, insn_byte_t last_pfx,
+ insn_attr_t grp_attr)
+{
+ const insn_attr_t *table;
+ insn_attr_t lpfx_attr;
+ int n, m = 0;
+
+ n = inat_group_id(grp_attr);
+ if (last_pfx) {
+ lpfx_attr = inat_get_opcode_attribute(last_pfx);
+ m = inat_last_prefix_id(lpfx_attr);
+ }
+ table = inat_group_tables[n][0];
+ if (!table)
+ return inat_group_common_attribute(grp_attr);
+ if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && m) {
+ table = inat_group_tables[n][m];
+ if (!table)
+ return inat_group_common_attribute(grp_attr);
+ }
+ return table[X86_MODRM_REG(modrm)] |
+ inat_group_common_attribute(grp_attr);
+}
+
+insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
+ insn_byte_t vex_p)
+{
+ const insn_attr_t *table;
+ if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
+ return 0;
+ table = inat_avx_tables[vex_m][vex_p];
+ if (!table)
+ return 0;
+ return table[opcode];
+}
+
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
new file mode 100644
index 000000000000..9f33b984d0ef
--- /dev/null
+++ b/arch/x86/lib/insn.c
@@ -0,0 +1,516 @@
+/*
+ * x86 instruction analysis
+ *
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004, 2009
+ */
+
+#include <linux/string.h>
+#include <asm/inat.h>
+#include <asm/insn.h>
+
+#define get_next(t, insn) \
+ ({t r; r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
+
+#define peek_next(t, insn) \
+ ({t r; r = *(t*)insn->next_byte; r; })
+
+#define peek_nbyte_next(t, insn, n) \
+ ({t r; r = *(t*)((insn)->next_byte + n); r; })
+
+/**
+ * insn_init() - initialize struct insn
+ * @insn: &struct insn to be initialized
+ * @kaddr: address (in kernel memory) of instruction (or copy thereof)
+ * @x86_64: !0 for 64-bit kernel or 64-bit app
+ */
+void insn_init(struct insn *insn, const void *kaddr, int x86_64)
+{
+ memset(insn, 0, sizeof(*insn));
+ insn->kaddr = kaddr;
+ insn->next_byte = kaddr;
+ insn->x86_64 = x86_64 ? 1 : 0;
+ insn->opnd_bytes = 4;
+ if (x86_64)
+ insn->addr_bytes = 8;
+ else
+ insn->addr_bytes = 4;
+}
+
+/**
+ * insn_get_prefixes - scan x86 instruction prefix bytes
+ * @insn: &struct insn containing instruction
+ *
+ * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
+ * to point to the (first) opcode. No effect if @insn->prefixes.got
+ * is already set.
+ */
+void insn_get_prefixes(struct insn *insn)
+{
+ struct insn_field *prefixes = &insn->prefixes;
+ insn_attr_t attr;
+ insn_byte_t b, lb;
+ int i, nb;
+
+ if (prefixes->got)
+ return;
+
+ nb = 0;
+ lb = 0;
+ b = peek_next(insn_byte_t, insn);
+ attr = inat_get_opcode_attribute(b);
+ while (inat_is_legacy_prefix(attr)) {
+ /* Skip if same prefix */
+ for (i = 0; i < nb; i++)
+ if (prefixes->bytes[i] == b)
+ goto found;
+ if (nb == 4)
+ /* Invalid instruction */
+ break;
+ prefixes->bytes[nb++] = b;
+ if (inat_is_address_size_prefix(attr)) {
+ /* address size switches 2/4 or 4/8 */
+ if (insn->x86_64)
+ insn->addr_bytes ^= 12;
+ else
+ insn->addr_bytes ^= 6;
+ } else if (inat_is_operand_size_prefix(attr)) {
+ /* oprand size switches 2/4 */
+ insn->opnd_bytes ^= 6;
+ }
+found:
+ prefixes->nbytes++;
+ insn->next_byte++;
+ lb = b;
+ b = peek_next(insn_byte_t, insn);
+ attr = inat_get_opcode_attribute(b);
+ }
+ /* Set the last prefix */
+ if (lb && lb != insn->prefixes.bytes[3]) {
+ if (unlikely(insn->prefixes.bytes[3])) {
+ /* Swap the last prefix */
+ b = insn->prefixes.bytes[3];
+ for (i = 0; i < nb; i++)
+ if (prefixes->bytes[i] == lb)
+ prefixes->bytes[i] = b;
+ }
+ insn->prefixes.bytes[3] = lb;
+ }
+
+ /* Decode REX prefix */
+ if (insn->x86_64) {
+ b = peek_next(insn_byte_t, insn);
+ attr = inat_get_opcode_attribute(b);
+ if (inat_is_rex_prefix(attr)) {
+ insn->rex_prefix.value = b;
+ insn->rex_prefix.nbytes = 1;
+ insn->next_byte++;
+ if (X86_REX_W(b))
+ /* REX.W overrides opnd_size */
+ insn->opnd_bytes = 8;
+ }
+ }
+ insn->rex_prefix.got = 1;
+
+ /* Decode VEX prefix */
+ b = peek_next(insn_byte_t, insn);
+ attr = inat_get_opcode_attribute(b);
+ if (inat_is_vex_prefix(attr)) {
+ insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
+ if (!insn->x86_64) {
+ /*
+ * In 32-bits mode, if the [7:6] bits (mod bits of
+ * ModRM) on the second byte are not 11b, it is
+ * LDS or LES.
+ */
+ if (X86_MODRM_MOD(b2) != 3)
+ goto vex_end;
+ }
+ insn->vex_prefix.bytes[0] = b;
+ insn->vex_prefix.bytes[1] = b2;
+ if (inat_is_vex3_prefix(attr)) {
+ b2 = peek_nbyte_next(insn_byte_t, insn, 2);
+ insn->vex_prefix.bytes[2] = b2;
+ insn->vex_prefix.nbytes = 3;
+ insn->next_byte += 3;
+ if (insn->x86_64 && X86_VEX_W(b2))
+ /* VEX.W overrides opnd_size */
+ insn->opnd_bytes = 8;
+ } else {
+ insn->vex_prefix.nbytes = 2;
+ insn->next_byte += 2;
+ }
+ }
+vex_end:
+ insn->vex_prefix.got = 1;
+
+ prefixes->got = 1;
+ return;
+}
+
+/**
+ * insn_get_opcode - collect opcode(s)
+ * @insn: &struct insn containing instruction
+ *
+ * Populates @insn->opcode, updates @insn->next_byte to point past the
+ * opcode byte(s), and set @insn->attr (except for groups).
+ * If necessary, first collects any preceding (prefix) bytes.
+ * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got
+ * is already 1.
+ */
+void insn_get_opcode(struct insn *insn)
+{
+ struct insn_field *opcode = &insn->opcode;
+ insn_byte_t op, pfx;
+ if (opcode->got)
+ return;
+ if (!insn->prefixes.got)
+ insn_get_prefixes(insn);
+
+ /* Get first opcode */
+ op = get_next(insn_byte_t, insn);
+ opcode->bytes[0] = op;
+ opcode->nbytes = 1;
+
+ /* Check if there is VEX prefix or not */
+ if (insn_is_avx(insn)) {
+ insn_byte_t m, p;
+ m = insn_vex_m_bits(insn);
+ p = insn_vex_p_bits(insn);
+ insn->attr = inat_get_avx_attribute(op, m, p);
+ if (!inat_accept_vex(insn->attr))
+ insn->attr = 0; /* This instruction is bad */
+ goto end; /* VEX has only 1 byte for opcode */
+ }
+
+ insn->attr = inat_get_opcode_attribute(op);
+ while (inat_is_escape(insn->attr)) {
+ /* Get escaped opcode */
+ op = get_next(insn_byte_t, insn);
+ opcode->bytes[opcode->nbytes++] = op;
+ pfx = insn_last_prefix(insn);
+ insn->attr = inat_get_escape_attribute(op, pfx, insn->attr);
+ }
+ if (inat_must_vex(insn->attr))
+ insn->attr = 0; /* This instruction is bad */
+end:
+ opcode->got = 1;
+}
+
+/**
+ * insn_get_modrm - collect ModRM byte, if any
+ * @insn: &struct insn containing instruction
+ *
+ * Populates @insn->modrm and updates @insn->next_byte to point past the
+ * ModRM byte, if any. If necessary, first collects the preceding bytes
+ * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1.
+ */
+void insn_get_modrm(struct insn *insn)
+{
+ struct insn_field *modrm = &insn->modrm;
+ insn_byte_t pfx, mod;
+ if (modrm->got)
+ return;
+ if (!insn->opcode.got)
+ insn_get_opcode(insn);
+
+ if (inat_has_modrm(insn->attr)) {
+ mod = get_next(insn_byte_t, insn);
+ modrm->value = mod;
+ modrm->nbytes = 1;
+ if (inat_is_group(insn->attr)) {
+ pfx = insn_last_prefix(insn);
+ insn->attr = inat_get_group_attribute(mod, pfx,
+ insn->attr);
+ }
+ }
+
+ if (insn->x86_64 && inat_is_force64(insn->attr))
+ insn->opnd_bytes = 8;
+ modrm->got = 1;
+}
+
+
+/**
+ * insn_rip_relative() - Does instruction use RIP-relative addressing mode?
+ * @insn: &struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * ModRM byte. No effect if @insn->x86_64 is 0.
+ */
+int insn_rip_relative(struct insn *insn)
+{
+ struct insn_field *modrm = &insn->modrm;
+
+ if (!insn->x86_64)
+ return 0;
+ if (!modrm->got)
+ insn_get_modrm(insn);
+ /*
+ * For rip-relative instructions, the mod field (top 2 bits)
+ * is zero and the r/m field (bottom 3 bits) is 0x5.
+ */
+ return (modrm->nbytes && (modrm->value & 0xc7) == 0x5);
+}
+
+/**
+ * insn_get_sib() - Get the SIB byte of instruction
+ * @insn: &struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * ModRM byte.
+ */
+void insn_get_sib(struct insn *insn)
+{
+ insn_byte_t modrm;
+
+ if (insn->sib.got)
+ return;
+ if (!insn->modrm.got)
+ insn_get_modrm(insn);
+ if (insn->modrm.nbytes) {
+ modrm = (insn_byte_t)insn->modrm.value;
+ if (insn->addr_bytes != 2 &&
+ X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
+ insn->sib.value = get_next(insn_byte_t, insn);
+ insn->sib.nbytes = 1;
+ }
+ }
+ insn->sib.got = 1;
+}
+
+
+/**
+ * insn_get_displacement() - Get the displacement of instruction
+ * @insn: &struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * SIB byte.
+ * Displacement value is sign-expanded.
+ */
+void insn_get_displacement(struct insn *insn)
+{
+ insn_byte_t mod, rm, base;
+
+ if (insn->displacement.got)
+ return;
+ if (!insn->sib.got)
+ insn_get_sib(insn);
+ if (insn->modrm.nbytes) {
+ /*
+ * Interpreting the modrm byte:
+ * mod = 00 - no displacement fields (exceptions below)
+ * mod = 01 - 1-byte displacement field
+ * mod = 10 - displacement field is 4 bytes, or 2 bytes if
+ * address size = 2 (0x67 prefix in 32-bit mode)
+ * mod = 11 - no memory operand
+ *
+ * If address size = 2...
+ * mod = 00, r/m = 110 - displacement field is 2 bytes
+ *
+ * If address size != 2...
+ * mod != 11, r/m = 100 - SIB byte exists
+ * mod = 00, SIB base = 101 - displacement field is 4 bytes
+ * mod = 00, r/m = 101 - rip-relative addressing, displacement
+ * field is 4 bytes
+ */
+ mod = X86_MODRM_MOD(insn->modrm.value);
+ rm = X86_MODRM_RM(insn->modrm.value);
+ base = X86_SIB_BASE(insn->sib.value);
+ if (mod == 3)
+ goto out;
+ if (mod == 1) {
+ insn->displacement.value = get_next(char, insn);
+ insn->displacement.nbytes = 1;
+ } else if (insn->addr_bytes == 2) {
+ if ((mod == 0 && rm == 6) || mod == 2) {
+ insn->displacement.value =
+ get_next(short, insn);
+ insn->displacement.nbytes = 2;
+ }
+ } else {
+ if ((mod == 0 && rm == 5) || mod == 2 ||
+ (mod == 0 && base == 5)) {
+ insn->displacement.value = get_next(int, insn);
+ insn->displacement.nbytes = 4;
+ }
+ }
+ }
+out:
+ insn->displacement.got = 1;
+}
+
+/* Decode moffset16/32/64 */
+static void __get_moffset(struct insn *insn)
+{
+ switch (insn->addr_bytes) {
+ case 2:
+ insn->moffset1.value = get_next(short, insn);
+ insn->moffset1.nbytes = 2;
+ break;
+ case 4:
+ insn->moffset1.value = get_next(int, insn);
+ insn->moffset1.nbytes = 4;
+ break;
+ case 8:
+ insn->moffset1.value = get_next(int, insn);
+ insn->moffset1.nbytes = 4;
+ insn->moffset2.value = get_next(int, insn);
+ insn->moffset2.nbytes = 4;
+ break;
+ }
+ insn->moffset1.got = insn->moffset2.got = 1;
+}
+
+/* Decode imm v32(Iz) */
+static void __get_immv32(struct insn *insn)
+{
+ switch (insn->opnd_bytes) {
+ case 2:
+ insn->immediate.value = get_next(short, insn);
+ insn->immediate.nbytes = 2;
+ break;
+ case 4:
+ case 8:
+ insn->immediate.value = get_next(int, insn);
+ insn->immediate.nbytes = 4;
+ break;
+ }
+}
+
+/* Decode imm v64(Iv/Ov) */
+static void __get_immv(struct insn *insn)
+{
+ switch (insn->opnd_bytes) {
+ case 2:
+ insn->immediate1.value = get_next(short, insn);
+ insn->immediate1.nbytes = 2;
+ break;
+ case 4:
+ insn->immediate1.value = get_next(int, insn);
+ insn->immediate1.nbytes = 4;
+ break;
+ case 8:
+ insn->immediate1.value = get_next(int, insn);
+ insn->immediate1.nbytes = 4;
+ insn->immediate2.value = get_next(int, insn);
+ insn->immediate2.nbytes = 4;
+ break;
+ }
+ insn->immediate1.got = insn->immediate2.got = 1;
+}
+
+/* Decode ptr16:16/32(Ap) */
+static void __get_immptr(struct insn *insn)
+{
+ switch (insn->opnd_bytes) {
+ case 2:
+ insn->immediate1.value = get_next(short, insn);
+ insn->immediate1.nbytes = 2;
+ break;
+ case 4:
+ insn->immediate1.value = get_next(int, insn);
+ insn->immediate1.nbytes = 4;
+ break;
+ case 8:
+ /* ptr16:64 is not exist (no segment) */
+ return;
+ }
+ insn->immediate2.value = get_next(unsigned short, insn);
+ insn->immediate2.nbytes = 2;
+ insn->immediate1.got = insn->immediate2.got = 1;
+}
+
+/**
+ * insn_get_immediate() - Get the immediates of instruction
+ * @insn: &struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * displacement bytes.
+ * Basically, most of immediates are sign-expanded. Unsigned-value can be
+ * get by bit masking with ((1 << (nbytes * 8)) - 1)
+ */
+void insn_get_immediate(struct insn *insn)
+{
+ if (insn->immediate.got)
+ return;
+ if (!insn->displacement.got)
+ insn_get_displacement(insn);
+
+ if (inat_has_moffset(insn->attr)) {
+ __get_moffset(insn);
+ goto done;
+ }
+
+ if (!inat_has_immediate(insn->attr))
+ /* no immediates */
+ goto done;
+
+ switch (inat_immediate_size(insn->attr)) {
+ case INAT_IMM_BYTE:
+ insn->immediate.value = get_next(char, insn);
+ insn->immediate.nbytes = 1;
+ break;
+ case INAT_IMM_WORD:
+ insn->immediate.value = get_next(short, insn);
+ insn->immediate.nbytes = 2;
+ break;
+ case INAT_IMM_DWORD:
+ insn->immediate.value = get_next(int, insn);
+ insn->immediate.nbytes = 4;
+ break;
+ case INAT_IMM_QWORD:
+ insn->immediate1.value = get_next(int, insn);
+ insn->immediate1.nbytes = 4;
+ insn->immediate2.value = get_next(int, insn);
+ insn->immediate2.nbytes = 4;
+ break;
+ case INAT_IMM_PTR:
+ __get_immptr(insn);
+ break;
+ case INAT_IMM_VWORD32:
+ __get_immv32(insn);
+ break;
+ case INAT_IMM_VWORD:
+ __get_immv(insn);
+ break;
+ default:
+ break;
+ }
+ if (inat_has_second_immediate(insn->attr)) {
+ insn->immediate2.value = get_next(char, insn);
+ insn->immediate2.nbytes = 1;
+ }
+done:
+ insn->immediate.got = 1;
+}
+
+/**
+ * insn_get_length() - Get the length of instruction
+ * @insn: &struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * immediates bytes.
+ */
+void insn_get_length(struct insn *insn)
+{
+ if (insn->length)
+ return;
+ if (!insn->immediate.got)
+ insn_get_immediate(insn);
+ insn->length = (unsigned char)((unsigned long)insn->next_byte
+ - (unsigned long)insn->kaddr);
+}
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index 33a1e3ca22d8..41628b104b9e 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -71,14 +71,9 @@ int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
}
EXPORT_SYMBOL(wrmsr_on_cpu);
-/* rdmsr on a bunch of CPUs
- *
- * @mask: which CPUs
- * @msr_no: which MSR
- * @msrs: array of MSR values
- *
- */
-void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs)
+static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
+ struct msr *msrs,
+ void (*msr_func) (void *info))
{
struct msr_info rv;
int this_cpu;
@@ -92,11 +87,23 @@ void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs)
this_cpu = get_cpu();
if (cpumask_test_cpu(this_cpu, mask))
- __rdmsr_on_cpu(&rv);
+ msr_func(&rv);
- smp_call_function_many(mask, __rdmsr_on_cpu, &rv, 1);
+ smp_call_function_many(mask, msr_func, &rv, 1);
put_cpu();
}
+
+/* rdmsr on a bunch of CPUs
+ *
+ * @mask: which CPUs
+ * @msr_no: which MSR
+ * @msrs: array of MSR values
+ *
+ */
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+{
+ __rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
+}
EXPORT_SYMBOL(rdmsr_on_cpus);
/*
@@ -107,24 +114,9 @@ EXPORT_SYMBOL(rdmsr_on_cpus);
* @msrs: array of MSR values
*
*/
-void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs)
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
{
- struct msr_info rv;
- int this_cpu;
-
- memset(&rv, 0, sizeof(rv));
-
- rv.off = cpumask_first(mask);
- rv.msrs = msrs;
- rv.msr_no = msr_no;
-
- this_cpu = get_cpu();
-
- if (cpumask_test_cpu(this_cpu, mask))
- __wrmsr_on_cpu(&rv);
-
- smp_call_function_many(mask, __wrmsr_on_cpu, &rv, 1);
- put_cpu();
+ __rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
}
EXPORT_SYMBOL(wrmsr_on_cpus);
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 1f118d462acc..e218d5df85ff 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -874,7 +874,7 @@ EXPORT_SYMBOL(copy_to_user);
* data to the requested size using zero bytes.
*/
unsigned long
-copy_from_user(void *to, const void __user *from, unsigned long n)
+_copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (access_ok(VERIFY_READ, from, n))
n = __copy_from_user(to, from, n);
@@ -882,4 +882,10 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
memset(to, 0, n);
return n;
}
-EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(_copy_from_user);
+
+void copy_from_user_overflow(void)
+{
+ WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_from_user_overflow);
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
new file mode 100644
index 000000000000..a793da5e560e
--- /dev/null
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -0,0 +1,893 @@
+# x86 Opcode Maps
+#
+#<Opcode maps>
+# Table: table-name
+# Referrer: escaped-name
+# AVXcode: avx-code
+# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
+# (or)
+# opcode: escape # escaped-name
+# EndTable
+#
+#<group maps>
+# GrpTable: GrpXXX
+# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
+# EndTable
+#
+# AVX Superscripts
+# (VEX): this opcode can accept VEX prefix.
+# (oVEX): this opcode requires VEX prefix.
+# (o128): this opcode only supports 128bit VEX.
+# (o256): this opcode only supports 256bit VEX.
+#
+
+Table: one byte opcode
+Referrer:
+AVXcode:
+# 0x00 - 0x0f
+00: ADD Eb,Gb
+01: ADD Ev,Gv
+02: ADD Gb,Eb
+03: ADD Gv,Ev
+04: ADD AL,Ib
+05: ADD rAX,Iz
+06: PUSH ES (i64)
+07: POP ES (i64)
+08: OR Eb,Gb
+09: OR Ev,Gv
+0a: OR Gb,Eb
+0b: OR Gv,Ev
+0c: OR AL,Ib
+0d: OR rAX,Iz
+0e: PUSH CS (i64)
+0f: escape # 2-byte escape
+# 0x10 - 0x1f
+10: ADC Eb,Gb
+11: ADC Ev,Gv
+12: ADC Gb,Eb
+13: ADC Gv,Ev
+14: ADC AL,Ib
+15: ADC rAX,Iz
+16: PUSH SS (i64)
+17: POP SS (i64)
+18: SBB Eb,Gb
+19: SBB Ev,Gv
+1a: SBB Gb,Eb
+1b: SBB Gv,Ev
+1c: SBB AL,Ib
+1d: SBB rAX,Iz
+1e: PUSH DS (i64)
+1f: POP DS (i64)
+# 0x20 - 0x2f
+20: AND Eb,Gb
+21: AND Ev,Gv
+22: AND Gb,Eb
+23: AND Gv,Ev
+24: AND AL,Ib
+25: AND rAx,Iz
+26: SEG=ES (Prefix)
+27: DAA (i64)
+28: SUB Eb,Gb
+29: SUB Ev,Gv
+2a: SUB Gb,Eb
+2b: SUB Gv,Ev
+2c: SUB AL,Ib
+2d: SUB rAX,Iz
+2e: SEG=CS (Prefix)
+2f: DAS (i64)
+# 0x30 - 0x3f
+30: XOR Eb,Gb
+31: XOR Ev,Gv
+32: XOR Gb,Eb
+33: XOR Gv,Ev
+34: XOR AL,Ib
+35: XOR rAX,Iz
+36: SEG=SS (Prefix)
+37: AAA (i64)
+38: CMP Eb,Gb
+39: CMP Ev,Gv
+3a: CMP Gb,Eb
+3b: CMP Gv,Ev
+3c: CMP AL,Ib
+3d: CMP rAX,Iz
+3e: SEG=DS (Prefix)
+3f: AAS (i64)
+# 0x40 - 0x4f
+40: INC eAX (i64) | REX (o64)
+41: INC eCX (i64) | REX.B (o64)
+42: INC eDX (i64) | REX.X (o64)
+43: INC eBX (i64) | REX.XB (o64)
+44: INC eSP (i64) | REX.R (o64)
+45: INC eBP (i64) | REX.RB (o64)
+46: INC eSI (i64) | REX.RX (o64)
+47: INC eDI (i64) | REX.RXB (o64)
+48: DEC eAX (i64) | REX.W (o64)
+49: DEC eCX (i64) | REX.WB (o64)
+4a: DEC eDX (i64) | REX.WX (o64)
+4b: DEC eBX (i64) | REX.WXB (o64)
+4c: DEC eSP (i64) | REX.WR (o64)
+4d: DEC eBP (i64) | REX.WRB (o64)
+4e: DEC eSI (i64) | REX.WRX (o64)
+4f: DEC eDI (i64) | REX.WRXB (o64)
+# 0x50 - 0x5f
+50: PUSH rAX/r8 (d64)
+51: PUSH rCX/r9 (d64)
+52: PUSH rDX/r10 (d64)
+53: PUSH rBX/r11 (d64)
+54: PUSH rSP/r12 (d64)
+55: PUSH rBP/r13 (d64)
+56: PUSH rSI/r14 (d64)
+57: PUSH rDI/r15 (d64)
+58: POP rAX/r8 (d64)
+59: POP rCX/r9 (d64)
+5a: POP rDX/r10 (d64)
+5b: POP rBX/r11 (d64)
+5c: POP rSP/r12 (d64)
+5d: POP rBP/r13 (d64)
+5e: POP rSI/r14 (d64)
+5f: POP rDI/r15 (d64)
+# 0x60 - 0x6f
+60: PUSHA/PUSHAD (i64)
+61: POPA/POPAD (i64)
+62: BOUND Gv,Ma (i64)
+63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
+64: SEG=FS (Prefix)
+65: SEG=GS (Prefix)
+66: Operand-Size (Prefix)
+67: Address-Size (Prefix)
+68: PUSH Iz (d64)
+69: IMUL Gv,Ev,Iz
+6a: PUSH Ib (d64)
+6b: IMUL Gv,Ev,Ib
+6c: INS/INSB Yb,DX
+6d: INS/INSW/INSD Yz,DX
+6e: OUTS/OUTSB DX,Xb
+6f: OUTS/OUTSW/OUTSD DX,Xz
+# 0x70 - 0x7f
+70: JO Jb
+71: JNO Jb
+72: JB/JNAE/JC Jb
+73: JNB/JAE/JNC Jb
+74: JZ/JE Jb
+75: JNZ/JNE Jb
+76: JBE/JNA Jb
+77: JNBE/JA Jb
+78: JS Jb
+79: JNS Jb
+7a: JP/JPE Jb
+7b: JNP/JPO Jb
+7c: JL/JNGE Jb
+7d: JNL/JGE Jb
+7e: JLE/JNG Jb
+7f: JNLE/JG Jb
+# 0x80 - 0x8f
+80: Grp1 Eb,Ib (1A)
+81: Grp1 Ev,Iz (1A)
+82: Grp1 Eb,Ib (1A),(i64)
+83: Grp1 Ev,Ib (1A)
+84: TEST Eb,Gb
+85: TEST Ev,Gv
+86: XCHG Eb,Gb
+87: XCHG Ev,Gv
+88: MOV Eb,Gb
+89: MOV Ev,Gv
+8a: MOV Gb,Eb
+8b: MOV Gv,Ev
+8c: MOV Ev,Sw
+8d: LEA Gv,M
+8e: MOV Sw,Ew
+8f: Grp1A (1A) | POP Ev (d64)
+# 0x90 - 0x9f
+90: NOP | PAUSE (F3) | XCHG r8,rAX
+91: XCHG rCX/r9,rAX
+92: XCHG rDX/r10,rAX
+93: XCHG rBX/r11,rAX
+94: XCHG rSP/r12,rAX
+95: XCHG rBP/r13,rAX
+96: XCHG rSI/r14,rAX
+97: XCHG rDI/r15,rAX
+98: CBW/CWDE/CDQE
+99: CWD/CDQ/CQO
+9a: CALLF Ap (i64)
+9b: FWAIT/WAIT
+9c: PUSHF/D/Q Fv (d64)
+9d: POPF/D/Q Fv (d64)
+9e: SAHF
+9f: LAHF
+# 0xa0 - 0xaf
+a0: MOV AL,Ob
+a1: MOV rAX,Ov
+a2: MOV Ob,AL
+a3: MOV Ov,rAX
+a4: MOVS/B Xb,Yb
+a5: MOVS/W/D/Q Xv,Yv
+a6: CMPS/B Xb,Yb
+a7: CMPS/W/D Xv,Yv
+a8: TEST AL,Ib
+a9: TEST rAX,Iz
+aa: STOS/B Yb,AL
+ab: STOS/W/D/Q Yv,rAX
+ac: LODS/B AL,Xb
+ad: LODS/W/D/Q rAX,Xv
+ae: SCAS/B AL,Yb
+af: SCAS/W/D/Q rAX,Xv
+# 0xb0 - 0xbf
+b0: MOV AL/R8L,Ib
+b1: MOV CL/R9L,Ib
+b2: MOV DL/R10L,Ib
+b3: MOV BL/R11L,Ib
+b4: MOV AH/R12L,Ib
+b5: MOV CH/R13L,Ib
+b6: MOV DH/R14L,Ib
+b7: MOV BH/R15L,Ib
+b8: MOV rAX/r8,Iv
+b9: MOV rCX/r9,Iv
+ba: MOV rDX/r10,Iv
+bb: MOV rBX/r11,Iv
+bc: MOV rSP/r12,Iv
+bd: MOV rBP/r13,Iv
+be: MOV rSI/r14,Iv
+bf: MOV rDI/r15,Iv
+# 0xc0 - 0xcf
+c0: Grp2 Eb,Ib (1A)
+c1: Grp2 Ev,Ib (1A)
+c2: RETN Iw (f64)
+c3: RETN
+c4: LES Gz,Mp (i64) | 3bytes-VEX (Prefix)
+c5: LDS Gz,Mp (i64) | 2bytes-VEX (Prefix)
+c6: Grp11 Eb,Ib (1A)
+c7: Grp11 Ev,Iz (1A)
+c8: ENTER Iw,Ib
+c9: LEAVE (d64)
+ca: RETF Iw
+cb: RETF
+cc: INT3
+cd: INT Ib
+ce: INTO (i64)
+cf: IRET/D/Q
+# 0xd0 - 0xdf
+d0: Grp2 Eb,1 (1A)
+d1: Grp2 Ev,1 (1A)
+d2: Grp2 Eb,CL (1A)
+d3: Grp2 Ev,CL (1A)
+d4: AAM Ib (i64)
+d5: AAD Ib (i64)
+d6:
+d7: XLAT/XLATB
+d8: ESC
+d9: ESC
+da: ESC
+db: ESC
+dc: ESC
+dd: ESC
+de: ESC
+df: ESC
+# 0xe0 - 0xef
+e0: LOOPNE/LOOPNZ Jb (f64)
+e1: LOOPE/LOOPZ Jb (f64)
+e2: LOOP Jb (f64)
+e3: JrCXZ Jb (f64)
+e4: IN AL,Ib
+e5: IN eAX,Ib
+e6: OUT Ib,AL
+e7: OUT Ib,eAX
+e8: CALL Jz (f64)
+e9: JMP-near Jz (f64)
+ea: JMP-far Ap (i64)
+eb: JMP-short Jb (f64)
+ec: IN AL,DX
+ed: IN eAX,DX
+ee: OUT DX,AL
+ef: OUT DX,eAX
+# 0xf0 - 0xff
+f0: LOCK (Prefix)
+f1:
+f2: REPNE (Prefix)
+f3: REP/REPE (Prefix)
+f4: HLT
+f5: CMC
+f6: Grp3_1 Eb (1A)
+f7: Grp3_2 Ev (1A)
+f8: CLC
+f9: STC
+fa: CLI
+fb: STI
+fc: CLD
+fd: STD
+fe: Grp4 (1A)
+ff: Grp5 (1A)
+EndTable
+
+Table: 2-byte opcode (0x0f)
+Referrer: 2-byte escape
+AVXcode: 1
+# 0x0f 0x00-0x0f
+00: Grp6 (1A)
+01: Grp7 (1A)
+02: LAR Gv,Ew
+03: LSL Gv,Ew
+04:
+05: SYSCALL (o64)
+06: CLTS
+07: SYSRET (o64)
+08: INVD
+09: WBINVD
+0a:
+0b: UD2 (1B)
+0c:
+0d: NOP Ev | GrpP
+0e: FEMMS
+# 3DNow! uses the last imm byte as opcode extension.
+0f: 3DNow! Pq,Qq,Ib
+# 0x0f 0x10-0x1f
+10: movups Vps,Wps (VEX) | movss Vss,Wss (F3),(VEX),(o128) | movupd Vpd,Wpd (66),(VEX) | movsd Vsd,Wsd (F2),(VEX),(o128)
+11: movups Wps,Vps (VEX) | movss Wss,Vss (F3),(VEX),(o128) | movupd Wpd,Vpd (66),(VEX) | movsd Wsd,Vsd (F2),(VEX),(o128)
+12: movlps Vq,Mq (VEX),(o128) | movlpd Vq,Mq (66),(VEX),(o128) | movhlps Vq,Uq (VEX),(o128) | movddup Vq,Wq (F2),(VEX) | movsldup Vq,Wq (F3),(VEX)
+13: mpvlps Mq,Vq (VEX),(o128) | movlpd Mq,Vq (66),(VEX),(o128)
+14: unpcklps Vps,Wq (VEX) | unpcklpd Vpd,Wq (66),(VEX)
+15: unpckhps Vps,Wq (VEX) | unpckhpd Vpd,Wq (66),(VEX)
+16: movhps Vq,Mq (VEX),(o128) | movhpd Vq,Mq (66),(VEX),(o128) | movlsps Vq,Uq (VEX),(o128) | movshdup Vq,Wq (F3),(VEX)
+17: movhps Mq,Vq (VEX),(o128) | movhpd Mq,Vq (66),(VEX),(o128)
+18: Grp16 (1A)
+19:
+1a:
+1b:
+1c:
+1d:
+1e:
+1f: NOP Ev
+# 0x0f 0x20-0x2f
+20: MOV Rd,Cd
+21: MOV Rd,Dd
+22: MOV Cd,Rd
+23: MOV Dd,Rd
+24:
+25:
+26:
+27:
+28: movaps Vps,Wps (VEX) | movapd Vpd,Wpd (66),(VEX)
+29: movaps Wps,Vps (VEX) | movapd Wpd,Vpd (66),(VEX)
+2a: cvtpi2ps Vps,Qpi | cvtsi2ss Vss,Ed/q (F3),(VEX),(o128) | cvtpi2pd Vpd,Qpi (66) | cvtsi2sd Vsd,Ed/q (F2),(VEX),(o128)
+2b: movntps Mps,Vps (VEX) | movntpd Mpd,Vpd (66),(VEX)
+2c: cvttps2pi Ppi,Wps | cvttss2si Gd/q,Wss (F3),(VEX),(o128) | cvttpd2pi Ppi,Wpd (66) | cvttsd2si Gd/q,Wsd (F2),(VEX),(o128)
+2d: cvtps2pi Ppi,Wps | cvtss2si Gd/q,Wss (F3),(VEX),(o128) | cvtpd2pi Qpi,Wpd (66) | cvtsd2si Gd/q,Wsd (F2),(VEX),(o128)
+2e: ucomiss Vss,Wss (VEX),(o128) | ucomisd Vsd,Wsd (66),(VEX),(o128)
+2f: comiss Vss,Wss (VEX),(o128) | comisd Vsd,Wsd (66),(VEX),(o128)
+# 0x0f 0x30-0x3f
+30: WRMSR
+31: RDTSC
+32: RDMSR
+33: RDPMC
+34: SYSENTER
+35: SYSEXIT
+36:
+37: GETSEC
+38: escape # 3-byte escape 1
+39:
+3a: escape # 3-byte escape 2
+3b:
+3c:
+3d:
+3e:
+3f:
+# 0x0f 0x40-0x4f
+40: CMOVO Gv,Ev
+41: CMOVNO Gv,Ev
+42: CMOVB/C/NAE Gv,Ev
+43: CMOVAE/NB/NC Gv,Ev
+44: CMOVE/Z Gv,Ev
+45: CMOVNE/NZ Gv,Ev
+46: CMOVBE/NA Gv,Ev
+47: CMOVA/NBE Gv,Ev
+48: CMOVS Gv,Ev
+49: CMOVNS Gv,Ev
+4a: CMOVP/PE Gv,Ev
+4b: CMOVNP/PO Gv,Ev
+4c: CMOVL/NGE Gv,Ev
+4d: CMOVNL/GE Gv,Ev
+4e: CMOVLE/NG Gv,Ev
+4f: CMOVNLE/G Gv,Ev
+# 0x0f 0x50-0x5f
+50: movmskps Gd/q,Ups (VEX) | movmskpd Gd/q,Upd (66),(VEX)
+51: sqrtps Vps,Wps (VEX) | sqrtss Vss,Wss (F3),(VEX),(o128) | sqrtpd Vpd,Wpd (66),(VEX) | sqrtsd Vsd,Wsd (F2),(VEX),(o128)
+52: rsqrtps Vps,Wps (VEX) | rsqrtss Vss,Wss (F3),(VEX),(o128)
+53: rcpps Vps,Wps (VEX) | rcpss Vss,Wss (F3),(VEX),(o128)
+54: andps Vps,Wps (VEX) | andpd Vpd,Wpd (66),(VEX)
+55: andnps Vps,Wps (VEX) | andnpd Vpd,Wpd (66),(VEX)
+56: orps Vps,Wps (VEX) | orpd Vpd,Wpd (66),(VEX)
+57: xorps Vps,Wps (VEX) | xorpd Vpd,Wpd (66),(VEX)
+58: addps Vps,Wps (VEX) | addss Vss,Wss (F3),(VEX),(o128) | addpd Vpd,Wpd (66),(VEX) | addsd Vsd,Wsd (F2),(VEX),(o128)
+59: mulps Vps,Wps (VEX) | mulss Vss,Wss (F3),(VEX),(o128) | mulpd Vpd,Wpd (66),(VEX) | mulsd Vsd,Wsd (F2),(VEX),(o128)
+5a: cvtps2pd Vpd,Wps (VEX) | cvtss2sd Vsd,Wss (F3),(VEX),(o128) | cvtpd2ps Vps,Wpd (66),(VEX) | cvtsd2ss Vsd,Wsd (F2),(VEX),(o128)
+5b: cvtdq2ps Vps,Wdq (VEX) | cvtps2dq Vdq,Wps (66),(VEX) | cvttps2dq Vdq,Wps (F3),(VEX)
+5c: subps Vps,Wps (VEX) | subss Vss,Wss (F3),(VEX),(o128) | subpd Vpd,Wpd (66),(VEX) | subsd Vsd,Wsd (F2),(VEX),(o128)
+5d: minps Vps,Wps (VEX) | minss Vss,Wss (F3),(VEX),(o128) | minpd Vpd,Wpd (66),(VEX) | minsd Vsd,Wsd (F2),(VEX),(o128)
+5e: divps Vps,Wps (VEX) | divss Vss,Wss (F3),(VEX),(o128) | divpd Vpd,Wpd (66),(VEX) | divsd Vsd,Wsd (F2),(VEX),(o128)
+5f: maxps Vps,Wps (VEX) | maxss Vss,Wss (F3),(VEX),(o128) | maxpd Vpd,Wpd (66),(VEX) | maxsd Vsd,Wsd (F2),(VEX),(o128)
+# 0x0f 0x60-0x6f
+60: punpcklbw Pq,Qd | punpcklbw Vdq,Wdq (66),(VEX),(o128)
+61: punpcklwd Pq,Qd | punpcklwd Vdq,Wdq (66),(VEX),(o128)
+62: punpckldq Pq,Qd | punpckldq Vdq,Wdq (66),(VEX),(o128)
+63: packsswb Pq,Qq | packsswb Vdq,Wdq (66),(VEX),(o128)
+64: pcmpgtb Pq,Qq | pcmpgtb Vdq,Wdq (66),(VEX),(o128)
+65: pcmpgtw Pq,Qq | pcmpgtw Vdq,Wdq (66),(VEX),(o128)
+66: pcmpgtd Pq,Qq | pcmpgtd Vdq,Wdq (66),(VEX),(o128)
+67: packuswb Pq,Qq | packuswb Vdq,Wdq (66),(VEX),(o128)
+68: punpckhbw Pq,Qd | punpckhbw Vdq,Wdq (66),(VEX),(o128)
+69: punpckhwd Pq,Qd | punpckhwd Vdq,Wdq (66),(VEX),(o128)
+6a: punpckhdq Pq,Qd | punpckhdq Vdq,Wdq (66),(VEX),(o128)
+6b: packssdw Pq,Qd | packssdw Vdq,Wdq (66),(VEX),(o128)
+6c: punpcklqdq Vdq,Wdq (66),(VEX),(o128)
+6d: punpckhqdq Vdq,Wdq (66),(VEX),(o128)
+6e: movd/q/ Pd,Ed/q | movd/q Vdq,Ed/q (66),(VEX),(o128)
+6f: movq Pq,Qq | movdqa Vdq,Wdq (66),(VEX) | movdqu Vdq,Wdq (F3),(VEX)
+# 0x0f 0x70-0x7f
+70: pshufw Pq,Qq,Ib | pshufd Vdq,Wdq,Ib (66),(VEX),(o128) | pshufhw Vdq,Wdq,Ib (F3),(VEX),(o128) | pshuflw VdqWdq,Ib (F2),(VEX),(o128)
+71: Grp12 (1A)
+72: Grp13 (1A)
+73: Grp14 (1A)
+74: pcmpeqb Pq,Qq | pcmpeqb Vdq,Wdq (66),(VEX),(o128)
+75: pcmpeqw Pq,Qq | pcmpeqw Vdq,Wdq (66),(VEX),(o128)
+76: pcmpeqd Pq,Qq | pcmpeqd Vdq,Wdq (66),(VEX),(o128)
+77: emms/vzeroupper/vzeroall (VEX)
+78: VMREAD Ed/q,Gd/q
+79: VMWRITE Gd/q,Ed/q
+7a:
+7b:
+7c: haddps Vps,Wps (F2),(VEX) | haddpd Vpd,Wpd (66),(VEX)
+7d: hsubps Vps,Wps (F2),(VEX) | hsubpd Vpd,Wpd (66),(VEX)
+7e: movd/q Ed/q,Pd | movd/q Ed/q,Vdq (66),(VEX),(o128) | movq Vq,Wq (F3),(VEX),(o128)
+7f: movq Qq,Pq | movdqa Wdq,Vdq (66),(VEX) | movdqu Wdq,Vdq (F3),(VEX)
+# 0x0f 0x80-0x8f
+80: JO Jz (f64)
+81: JNO Jz (f64)
+82: JB/JNAE/JC Jz (f64)
+83: JNB/JAE/JNC Jz (f64)
+84: JZ/JE Jz (f64)
+85: JNZ/JNE Jz (f64)
+86: JBE/JNA Jz (f64)
+87: JNBE/JA Jz (f64)
+88: JS Jz (f64)
+89: JNS Jz (f64)
+8a: JP/JPE Jz (f64)
+8b: JNP/JPO Jz (f64)
+8c: JL/JNGE Jz (f64)
+8d: JNL/JGE Jz (f64)
+8e: JLE/JNG Jz (f64)
+8f: JNLE/JG Jz (f64)
+# 0x0f 0x90-0x9f
+90: SETO Eb
+91: SETNO Eb
+92: SETB/C/NAE Eb
+93: SETAE/NB/NC Eb
+94: SETE/Z Eb
+95: SETNE/NZ Eb
+96: SETBE/NA Eb
+97: SETA/NBE Eb
+98: SETS Eb
+99: SETNS Eb
+9a: SETP/PE Eb
+9b: SETNP/PO Eb
+9c: SETL/NGE Eb
+9d: SETNL/GE Eb
+9e: SETLE/NG Eb
+9f: SETNLE/G Eb
+# 0x0f 0xa0-0xaf
+a0: PUSH FS (d64)
+a1: POP FS (d64)
+a2: CPUID
+a3: BT Ev,Gv
+a4: SHLD Ev,Gv,Ib
+a5: SHLD Ev,Gv,CL
+a6: GrpPDLK
+a7: GrpRNG
+a8: PUSH GS (d64)
+a9: POP GS (d64)
+aa: RSM
+ab: BTS Ev,Gv
+ac: SHRD Ev,Gv,Ib
+ad: SHRD Ev,Gv,CL
+ae: Grp15 (1A),(1C)
+af: IMUL Gv,Ev
+# 0x0f 0xb0-0xbf
+b0: CMPXCHG Eb,Gb
+b1: CMPXCHG Ev,Gv
+b2: LSS Gv,Mp
+b3: BTR Ev,Gv
+b4: LFS Gv,Mp
+b5: LGS Gv,Mp
+b6: MOVZX Gv,Eb
+b7: MOVZX Gv,Ew
+b8: JMPE | POPCNT Gv,Ev (F3)
+b9: Grp10 (1A)
+ba: Grp8 Ev,Ib (1A)
+bb: BTC Ev,Gv
+bc: BSF Gv,Ev
+bd: BSR Gv,Ev
+be: MOVSX Gv,Eb
+bf: MOVSX Gv,Ew
+# 0x0f 0xc0-0xcf
+c0: XADD Eb,Gb
+c1: XADD Ev,Gv
+c2: cmpps Vps,Wps,Ib (VEX) | cmpss Vss,Wss,Ib (F3),(VEX),(o128) | cmppd Vpd,Wpd,Ib (66),(VEX) | cmpsd Vsd,Wsd,Ib (F2),(VEX)
+c3: movnti Md/q,Gd/q
+c4: pinsrw Pq,Rd/q/Mw,Ib | pinsrw Vdq,Rd/q/Mw,Ib (66),(VEX),(o128)
+c5: pextrw Gd,Nq,Ib | pextrw Gd,Udq,Ib (66),(VEX),(o128)
+c6: shufps Vps,Wps,Ib (VEX) | shufpd Vpd,Wpd,Ib (66),(VEX)
+c7: Grp9 (1A)
+c8: BSWAP RAX/EAX/R8/R8D
+c9: BSWAP RCX/ECX/R9/R9D
+ca: BSWAP RDX/EDX/R10/R10D
+cb: BSWAP RBX/EBX/R11/R11D
+cc: BSWAP RSP/ESP/R12/R12D
+cd: BSWAP RBP/EBP/R13/R13D
+ce: BSWAP RSI/ESI/R14/R14D
+cf: BSWAP RDI/EDI/R15/R15D
+# 0x0f 0xd0-0xdf
+d0: addsubps Vps,Wps (F2),(VEX) | addsubpd Vpd,Wpd (66),(VEX)
+d1: psrlw Pq,Qq | psrlw Vdq,Wdq (66),(VEX),(o128)
+d2: psrld Pq,Qq | psrld Vdq,Wdq (66),(VEX),(o128)
+d3: psrlq Pq,Qq | psrlq Vdq,Wdq (66),(VEX),(o128)
+d4: paddq Pq,Qq | paddq Vdq,Wdq (66),(VEX),(o128)
+d5: pmullw Pq,Qq | pmullw Vdq,Wdq (66),(VEX),(o128)
+d6: movq Wq,Vq (66),(VEX),(o128) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2)
+d7: pmovmskb Gd,Nq | pmovmskb Gd,Udq (66),(VEX),(o128)
+d8: psubusb Pq,Qq | psubusb Vdq,Wdq (66),(VEX),(o128)
+d9: psubusw Pq,Qq | psubusw Vdq,Wdq (66),(VEX),(o128)
+da: pminub Pq,Qq | pminub Vdq,Wdq (66),(VEX),(o128)
+db: pand Pq,Qq | pand Vdq,Wdq (66),(VEX),(o128)
+dc: paddusb Pq,Qq | paddusb Vdq,Wdq (66),(VEX),(o128)
+dd: paddusw Pq,Qq | paddusw Vdq,Wdq (66),(VEX),(o128)
+de: pmaxub Pq,Qq | pmaxub Vdq,Wdq (66),(VEX),(o128)
+df: pandn Pq,Qq | pandn Vdq,Wdq (66),(VEX),(o128)
+# 0x0f 0xe0-0xef
+e0: pavgb Pq,Qq | pavgb Vdq,Wdq (66),(VEX),(o128)
+e1: psraw Pq,Qq | psraw Vdq,Wdq (66),(VEX),(o128)
+e2: psrad Pq,Qq | psrad Vdq,Wdq (66),(VEX),(o128)
+e3: pavgw Pq,Qq | pavgw Vdq,Wdq (66),(VEX),(o128)
+e4: pmulhuw Pq,Qq | pmulhuw Vdq,Wdq (66),(VEX),(o128)
+e5: pmulhw Pq,Qq | pmulhw Vdq,Wdq (66),(VEX),(o128)
+e6: cvtpd2dq Vdq,Wpd (F2),(VEX) | cvttpd2dq Vdq,Wpd (66),(VEX) | cvtdq2pd Vpd,Wdq (F3),(VEX)
+e7: movntq Mq,Pq | movntdq Mdq,Vdq (66),(VEX)
+e8: psubsb Pq,Qq | psubsb Vdq,Wdq (66),(VEX),(o128)
+e9: psubsw Pq,Qq | psubsw Vdq,Wdq (66),(VEX),(o128)
+ea: pminsw Pq,Qq | pminsw Vdq,Wdq (66),(VEX),(o128)
+eb: por Pq,Qq | por Vdq,Wdq (66),(VEX),(o128)
+ec: paddsb Pq,Qq | paddsb Vdq,Wdq (66),(VEX),(o128)
+ed: paddsw Pq,Qq | paddsw Vdq,Wdq (66),(VEX),(o128)
+ee: pmaxsw Pq,Qq | pmaxsw Vdq,Wdq (66),(VEX),(o128)
+ef: pxor Pq,Qq | pxor Vdq,Wdq (66),(VEX),(o128)
+# 0x0f 0xf0-0xff
+f0: lddqu Vdq,Mdq (F2),(VEX)
+f1: psllw Pq,Qq | psllw Vdq,Wdq (66),(VEX),(o128)
+f2: pslld Pq,Qq | pslld Vdq,Wdq (66),(VEX),(o128)
+f3: psllq Pq,Qq | psllq Vdq,Wdq (66),(VEX),(o128)
+f4: pmuludq Pq,Qq | pmuludq Vdq,Wdq (66),(VEX),(o128)
+f5: pmaddwd Pq,Qq | pmaddwd Vdq,Wdq (66),(VEX),(o128)
+f6: psadbw Pq,Qq | psadbw Vdq,Wdq (66),(VEX),(o128)
+f7: maskmovq Pq,Nq | maskmovdqu Vdq,Udq (66),(VEX),(o128)
+f8: psubb Pq,Qq | psubb Vdq,Wdq (66),(VEX),(o128)
+f9: psubw Pq,Qq | psubw Vdq,Wdq (66),(VEX),(o128)
+fa: psubd Pq,Qq | psubd Vdq,Wdq (66),(VEX),(o128)
+fb: psubq Pq,Qq | psubq Vdq,Wdq (66),(VEX),(o128)
+fc: paddb Pq,Qq | paddb Vdq,Wdq (66),(VEX),(o128)
+fd: paddw Pq,Qq | paddw Vdq,Wdq (66),(VEX),(o128)
+fe: paddd Pq,Qq | paddd Vdq,Wdq (66),(VEX),(o128)
+ff:
+EndTable
+
+Table: 3-byte opcode 1 (0x0f 0x38)
+Referrer: 3-byte escape 1
+AVXcode: 2
+# 0x0f 0x38 0x00-0x0f
+00: pshufb Pq,Qq | pshufb Vdq,Wdq (66),(VEX),(o128)
+01: phaddw Pq,Qq | phaddw Vdq,Wdq (66),(VEX),(o128)
+02: phaddd Pq,Qq | phaddd Vdq,Wdq (66),(VEX),(o128)
+03: phaddsw Pq,Qq | phaddsw Vdq,Wdq (66),(VEX),(o128)
+04: pmaddubsw Pq,Qq | pmaddubsw Vdq,Wdq (66),(VEX),(o128)
+05: phsubw Pq,Qq | phsubw Vdq,Wdq (66),(VEX),(o128)
+06: phsubd Pq,Qq | phsubd Vdq,Wdq (66),(VEX),(o128)
+07: phsubsw Pq,Qq | phsubsw Vdq,Wdq (66),(VEX),(o128)
+08: psignb Pq,Qq | psignb Vdq,Wdq (66),(VEX),(o128)
+09: psignw Pq,Qq | psignw Vdq,Wdq (66),(VEX),(o128)
+0a: psignd Pq,Qq | psignd Vdq,Wdq (66),(VEX),(o128)
+0b: pmulhrsw Pq,Qq | pmulhrsw Vdq,Wdq (66),(VEX),(o128)
+0c: Vpermilps /r (66),(oVEX)
+0d: Vpermilpd /r (66),(oVEX)
+0e: vtestps /r (66),(oVEX)
+0f: vtestpd /r (66),(oVEX)
+# 0x0f 0x38 0x10-0x1f
+10: pblendvb Vdq,Wdq (66)
+11:
+12:
+13:
+14: blendvps Vdq,Wdq (66)
+15: blendvpd Vdq,Wdq (66)
+16:
+17: ptest Vdq,Wdq (66),(VEX)
+18: vbroadcastss /r (66),(oVEX)
+19: vbroadcastsd /r (66),(oVEX),(o256)
+1a: vbroadcastf128 /r (66),(oVEX),(o256)
+1b:
+1c: pabsb Pq,Qq | pabsb Vdq,Wdq (66),(VEX),(o128)
+1d: pabsw Pq,Qq | pabsw Vdq,Wdq (66),(VEX),(o128)
+1e: pabsd Pq,Qq | pabsd Vdq,Wdq (66),(VEX),(o128)
+1f:
+# 0x0f 0x38 0x20-0x2f
+20: pmovsxbw Vdq,Udq/Mq (66),(VEX),(o128)
+21: pmovsxbd Vdq,Udq/Md (66),(VEX),(o128)
+22: pmovsxbq Vdq,Udq/Mw (66),(VEX),(o128)
+23: pmovsxwd Vdq,Udq/Mq (66),(VEX),(o128)
+24: pmovsxwq Vdq,Udq/Md (66),(VEX),(o128)
+25: pmovsxdq Vdq,Udq/Mq (66),(VEX),(o128)
+26:
+27:
+28: pmuldq Vdq,Wdq (66),(VEX),(o128)
+29: pcmpeqq Vdq,Wdq (66),(VEX),(o128)
+2a: movntdqa Vdq,Mdq (66),(VEX),(o128)
+2b: packusdw Vdq,Wdq (66),(VEX),(o128)
+2c: vmaskmovps(ld) /r (66),(oVEX)
+2d: vmaskmovpd(ld) /r (66),(oVEX)
+2e: vmaskmovps(st) /r (66),(oVEX)
+2f: vmaskmovpd(st) /r (66),(oVEX)
+# 0x0f 0x38 0x30-0x3f
+30: pmovzxbw Vdq,Udq/Mq (66),(VEX),(o128)
+31: pmovzxbd Vdq,Udq/Md (66),(VEX),(o128)
+32: pmovzxbq Vdq,Udq/Mw (66),(VEX),(o128)
+33: pmovzxwd Vdq,Udq/Mq (66),(VEX),(o128)
+34: pmovzxwq Vdq,Udq/Md (66),(VEX),(o128)
+35: pmovzxdq Vdq,Udq/Mq (66),(VEX),(o128)
+36:
+37: pcmpgtq Vdq,Wdq (66),(VEX),(o128)
+38: pminsb Vdq,Wdq (66),(VEX),(o128)
+39: pminsd Vdq,Wdq (66),(VEX),(o128)
+3a: pminuw Vdq,Wdq (66),(VEX),(o128)
+3b: pminud Vdq,Wdq (66),(VEX),(o128)
+3c: pmaxsb Vdq,Wdq (66),(VEX),(o128)
+3d: pmaxsd Vdq,Wdq (66),(VEX),(o128)
+3e: pmaxuw Vdq,Wdq (66),(VEX),(o128)
+3f: pmaxud Vdq,Wdq (66),(VEX),(o128)
+# 0x0f 0x38 0x40-0x8f
+40: pmulld Vdq,Wdq (66),(VEX),(o128)
+41: phminposuw Vdq,Wdq (66),(VEX),(o128)
+80: INVEPT Gd/q,Mdq (66)
+81: INVPID Gd/q,Mdq (66)
+# 0x0f 0x38 0x90-0xbf (FMA)
+96: vfmaddsub132pd/ps /r (66),(VEX)
+97: vfmsubadd132pd/ps /r (66),(VEX)
+98: vfmadd132pd/ps /r (66),(VEX)
+99: vfmadd132sd/ss /r (66),(VEX),(o128)
+9a: vfmsub132pd/ps /r (66),(VEX)
+9b: vfmsub132sd/ss /r (66),(VEX),(o128)
+9c: vfnmadd132pd/ps /r (66),(VEX)
+9d: vfnmadd132sd/ss /r (66),(VEX),(o128)
+9e: vfnmsub132pd/ps /r (66),(VEX)
+9f: vfnmsub132sd/ss /r (66),(VEX),(o128)
+a6: vfmaddsub213pd/ps /r (66),(VEX)
+a7: vfmsubadd213pd/ps /r (66),(VEX)
+a8: vfmadd213pd/ps /r (66),(VEX)
+a9: vfmadd213sd/ss /r (66),(VEX),(o128)
+aa: vfmsub213pd/ps /r (66),(VEX)
+ab: vfmsub213sd/ss /r (66),(VEX),(o128)
+ac: vfnmadd213pd/ps /r (66),(VEX)
+ad: vfnmadd213sd/ss /r (66),(VEX),(o128)
+ae: vfnmsub213pd/ps /r (66),(VEX)
+af: vfnmsub213sd/ss /r (66),(VEX),(o128)
+b6: vfmaddsub231pd/ps /r (66),(VEX)
+b7: vfmsubadd231pd/ps /r (66),(VEX)
+b8: vfmadd231pd/ps /r (66),(VEX)
+b9: vfmadd231sd/ss /r (66),(VEX),(o128)
+ba: vfmsub231pd/ps /r (66),(VEX)
+bb: vfmsub231sd/ss /r (66),(VEX),(o128)
+bc: vfnmadd231pd/ps /r (66),(VEX)
+bd: vfnmadd231sd/ss /r (66),(VEX),(o128)
+be: vfnmsub231pd/ps /r (66),(VEX)
+bf: vfnmsub231sd/ss /r (66),(VEX),(o128)
+# 0x0f 0x38 0xc0-0xff
+db: aesimc Vdq,Wdq (66),(VEX),(o128)
+dc: aesenc Vdq,Wdq (66),(VEX),(o128)
+dd: aesenclast Vdq,Wdq (66),(VEX),(o128)
+de: aesdec Vdq,Wdq (66),(VEX),(o128)
+df: aesdeclast Vdq,Wdq (66),(VEX),(o128)
+f0: MOVBE Gv,Mv | CRC32 Gd,Eb (F2)
+f1: MOVBE Mv,Gv | CRC32 Gd,Ev (F2)
+EndTable
+
+Table: 3-byte opcode 2 (0x0f 0x3a)
+Referrer: 3-byte escape 2
+AVXcode: 3
+# 0x0f 0x3a 0x00-0xff
+04: vpermilps /r,Ib (66),(oVEX)
+05: vpermilpd /r,Ib (66),(oVEX)
+06: vperm2f128 /r,Ib (66),(oVEX),(o256)
+08: roundps Vdq,Wdq,Ib (66),(VEX)
+09: roundpd Vdq,Wdq,Ib (66),(VEX)
+0a: roundss Vss,Wss,Ib (66),(VEX),(o128)
+0b: roundsd Vsd,Wsd,Ib (66),(VEX),(o128)
+0c: blendps Vdq,Wdq,Ib (66),(VEX)
+0d: blendpd Vdq,Wdq,Ib (66),(VEX)
+0e: pblendw Vdq,Wdq,Ib (66),(VEX),(o128)
+0f: palignr Pq,Qq,Ib | palignr Vdq,Wdq,Ib (66),(VEX),(o128)
+14: pextrb Rd/Mb,Vdq,Ib (66),(VEX),(o128)
+15: pextrw Rd/Mw,Vdq,Ib (66),(VEX),(o128)
+16: pextrd/pextrq Ed/q,Vdq,Ib (66),(VEX),(o128)
+17: extractps Ed,Vdq,Ib (66),(VEX),(o128)
+18: vinsertf128 /r,Ib (66),(oVEX),(o256)
+19: vextractf128 /r,Ib (66),(oVEX),(o256)
+20: pinsrb Vdq,Rd/q/Mb,Ib (66),(VEX),(o128)
+21: insertps Vdq,Udq/Md,Ib (66),(VEX),(o128)
+22: pinsrd/pinsrq Vdq,Ed/q,Ib (66),(VEX),(o128)
+40: dpps Vdq,Wdq,Ib (66),(VEX)
+41: dppd Vdq,Wdq,Ib (66),(VEX),(o128)
+42: mpsadbw Vdq,Wdq,Ib (66),(VEX),(o128)
+44: pclmulq Vdq,Wdq,Ib (66),(VEX),(o128)
+4a: vblendvps /r,Ib (66),(oVEX)
+4b: vblendvpd /r,Ib (66),(oVEX)
+4c: vpblendvb /r,Ib (66),(oVEX),(o128)
+60: pcmpestrm Vdq,Wdq,Ib (66),(VEX),(o128)
+61: pcmpestri Vdq,Wdq,Ib (66),(VEX),(o128)
+62: pcmpistrm Vdq,Wdq,Ib (66),(VEX),(o128)
+63: pcmpistri Vdq,Wdq,Ib (66),(VEX),(o128)
+df: aeskeygenassist Vdq,Wdq,Ib (66),(VEX),(o128)
+EndTable
+
+GrpTable: Grp1
+0: ADD
+1: OR
+2: ADC
+3: SBB
+4: AND
+5: SUB
+6: XOR
+7: CMP
+EndTable
+
+GrpTable: Grp1A
+0: POP
+EndTable
+
+GrpTable: Grp2
+0: ROL
+1: ROR
+2: RCL
+3: RCR
+4: SHL/SAL
+5: SHR
+6:
+7: SAR
+EndTable
+
+GrpTable: Grp3_1
+0: TEST Eb,Ib
+1:
+2: NOT Eb
+3: NEG Eb
+4: MUL AL,Eb
+5: IMUL AL,Eb
+6: DIV AL,Eb
+7: IDIV AL,Eb
+EndTable
+
+GrpTable: Grp3_2
+0: TEST Ev,Iz
+1:
+2: NOT Ev
+3: NEG Ev
+4: MUL rAX,Ev
+5: IMUL rAX,Ev
+6: DIV rAX,Ev
+7: IDIV rAX,Ev
+EndTable
+
+GrpTable: Grp4
+0: INC Eb
+1: DEC Eb
+EndTable
+
+GrpTable: Grp5
+0: INC Ev
+1: DEC Ev
+2: CALLN Ev (f64)
+3: CALLF Ep
+4: JMPN Ev (f64)
+5: JMPF Ep
+6: PUSH Ev (d64)
+7:
+EndTable
+
+GrpTable: Grp6
+0: SLDT Rv/Mw
+1: STR Rv/Mw
+2: LLDT Ew
+3: LTR Ew
+4: VERR Ew
+5: VERW Ew
+EndTable
+
+GrpTable: Grp7
+0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B)
+1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001)
+2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B)
+3: LIDT Ms
+4: SMSW Mw/Rv
+5:
+6: LMSW Ew
+7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
+EndTable
+
+GrpTable: Grp8
+4: BT
+5: BTS
+6: BTR
+7: BTC
+EndTable
+
+GrpTable: Grp9
+1: CMPXCHG8B/16B Mq/Mdq
+6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3)
+7: VMPTRST Mq
+EndTable
+
+GrpTable: Grp10
+EndTable
+
+GrpTable: Grp11
+0: MOV
+EndTable
+
+GrpTable: Grp12
+2: psrlw Nq,Ib (11B) | psrlw Udq,Ib (66),(11B),(VEX),(o128)
+4: psraw Nq,Ib (11B) | psraw Udq,Ib (66),(11B),(VEX),(o128)
+6: psllw Nq,Ib (11B) | psllw Udq,Ib (66),(11B),(VEX),(o128)
+EndTable
+
+GrpTable: Grp13
+2: psrld Nq,Ib (11B) | psrld Udq,Ib (66),(11B),(VEX),(o128)
+4: psrad Nq,Ib (11B) | psrad Udq,Ib (66),(11B),(VEX),(o128)
+6: pslld Nq,Ib (11B) | pslld Udq,Ib (66),(11B),(VEX),(o128)
+EndTable
+
+GrpTable: Grp14
+2: psrlq Nq,Ib (11B) | psrlq Udq,Ib (66),(11B),(VEX),(o128)
+3: psrldq Udq,Ib (66),(11B),(VEX),(o128)
+6: psllq Nq,Ib (11B) | psllq Udq,Ib (66),(11B),(VEX),(o128)
+7: pslldq Udq,Ib (66),(11B),(VEX),(o128)
+EndTable
+
+GrpTable: Grp15
+0: fxsave
+1: fxstor
+2: ldmxcsr (VEX)
+3: stmxcsr (VEX)
+4: XSAVE
+5: XRSTOR | lfence (11B)
+6: mfence (11B)
+7: clflush | sfence (11B)
+EndTable
+
+GrpTable: Grp16
+0: prefetch NTA
+1: prefetch T0
+2: prefetch T1
+3: prefetch T2
+EndTable
+
+# AMD's Prefetch Group
+GrpTable: GrpP
+0: PREFETCH
+1: PREFETCHW
+EndTable
+
+GrpTable: GrpPDLK
+0: MONTMUL
+1: XSHA1
+2: XSHA2
+EndTable
+
+GrpTable: GrpRNG
+0: xstore-rng
+1: xcrypt-ecb
+2: xcrypt-cbc
+4: xcrypt-cfb
+5: xcrypt-ofb
+EndTable
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index 61b41ca3b5a2..d0474ad2a6e5 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -35,34 +35,3 @@ int fixup_exception(struct pt_regs *regs)
return 0;
}
-
-#ifdef CONFIG_X86_64
-/*
- * Need to defined our own search_extable on X86_64 to work around
- * a B stepping K8 bug.
- */
-const struct exception_table_entry *
-search_extable(const struct exception_table_entry *first,
- const struct exception_table_entry *last,
- unsigned long value)
-{
- /* B stepping K8 bug */
- if ((value >> 32) == 0)
- value |= 0xffffffffUL << 32;
-
- while (first <= last) {
- const struct exception_table_entry *mid;
- long diff;
-
- mid = (last - first) / 2 + first;
- diff = mid->insn - value;
- if (diff == 0)
- return mid;
- else if (diff < 0)
- first = mid+1;
- else
- last = mid-1;
- }
- return NULL;
-}
-#endif
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index f4cee9028cf0..f62777940dfb 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -38,7 +38,8 @@ enum x86_pf_error_code {
* Returns 0 if mmiotrace is disabled, or if the fault is not
* handled by mmiotrace:
*/
-static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr)
+static inline int __kprobes
+kmmio_fault(struct pt_regs *regs, unsigned long addr)
{
if (unlikely(is_kmmio_active()))
if (kmmio_handler(regs, addr) == 1)
@@ -46,7 +47,7 @@ static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr)
return 0;
}
-static inline int notify_page_fault(struct pt_regs *regs)
+static inline int __kprobes notify_page_fault(struct pt_regs *regs)
{
int ret = 0;
@@ -240,7 +241,7 @@ void vmalloc_sync_all(void)
*
* Handle a fault on the vmalloc or module mapping area
*/
-static noinline int vmalloc_fault(unsigned long address)
+static noinline __kprobes int vmalloc_fault(unsigned long address)
{
unsigned long pgd_paddr;
pmd_t *pmd_k;
@@ -357,7 +358,7 @@ void vmalloc_sync_all(void)
*
* This assumes no large pages in there.
*/
-static noinline int vmalloc_fault(unsigned long address)
+static noinline __kprobes int vmalloc_fault(unsigned long address)
{
pgd_t *pgd, *pgd_ref;
pud_t *pud, *pud_ref;
@@ -658,7 +659,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
show_fault_oops(regs, error_code, address);
stackend = end_of_stack(tsk);
- if (*stackend != STACK_END_MAGIC)
+ if (tsk != &init_task && *stackend != STACK_END_MAGIC)
printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
tsk->thread.cr2 = address;
@@ -860,7 +861,7 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte)
* There are no security implications to leaving a stale TLB when
* increasing the permissions on a page.
*/
-static noinline int
+static noinline __kprobes int
spurious_fault(unsigned long error_code, unsigned long address)
{
pgd_t *pgd;
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 334e63ca7b2b..2feb9bdedaaf 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -170,8 +170,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
(unsigned long long)phys_addr,
(unsigned long long)(phys_addr + size),
prot_val, new_prot_val);
- free_memtype(phys_addr, phys_addr + size);
- return NULL;
+ goto err_free_memtype;
}
prot_val = new_prot_val;
}
@@ -197,26 +196,25 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
*/
area = get_vm_area_caller(size, VM_IOREMAP, caller);
if (!area)
- return NULL;
+ goto err_free_memtype;
area->phys_addr = phys_addr;
vaddr = (unsigned long) area->addr;
- if (kernel_map_sync_memtype(phys_addr, size, prot_val)) {
- free_memtype(phys_addr, phys_addr + size);
- free_vm_area(area);
- return NULL;
- }
+ if (kernel_map_sync_memtype(phys_addr, size, prot_val))
+ goto err_free_area;
- if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
- free_memtype(phys_addr, phys_addr + size);
- free_vm_area(area);
- return NULL;
- }
+ if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot))
+ goto err_free_area;
ret_addr = (void __iomem *) (vaddr + offset);
mmiotrace_ioremap(unaligned_phys_addr, unaligned_size, ret_addr);
return ret_addr;
+err_free_area:
+ free_vm_area(area);
+err_free_memtype:
+ free_memtype(phys_addr, phys_addr + size);
+ return NULL;
}
/**
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 16ccbd77917f..11a4ad4d6253 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -540,8 +540,14 @@ kmmio_die_notifier(struct notifier_block *nb, unsigned long val, void *args)
struct die_args *arg = args;
if (val == DIE_DEBUG && (arg->err & DR_STEP))
- if (post_kmmio_handler(arg->err, arg->regs) == 1)
+ if (post_kmmio_handler(arg->err, arg->regs) == 1) {
+ /*
+ * Reset the BS bit in dr6 (pointed by args->err) to
+ * denote completion of processing
+ */
+ (*(unsigned long *)ERR_PTR(arg->err)) &= ~DR_STEP;
return NOTIFY_STOP;
+ }
return NOTIFY_DONE;
}
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index dbb5381f7b3b..9d7ce96e5a5c 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -136,7 +136,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
apicid_to_node[apic_id] = node;
node_set(node, cpu_nodes_parsed);
acpi_numa = 1;
- printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+ printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
pxm, apic_id, node);
}
@@ -170,7 +170,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
apicid_to_node[apic_id] = node;
node_set(node, cpu_nodes_parsed);
acpi_numa = 1;
- printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+ printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n",
pxm, apic_id, node);
}
diff --git a/arch/x86/mm/testmmiotrace.c b/arch/x86/mm/testmmiotrace.c
index 427fd1b56df5..8565d944f7cf 100644
--- a/arch/x86/mm/testmmiotrace.c
+++ b/arch/x86/mm/testmmiotrace.c
@@ -1,12 +1,13 @@
/*
* Written by Pekka Paalanen, 2008-2009 <pq@iki.fi>
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/io.h>
#include <linux/mmiotrace.h>
-#define MODULE_NAME "testmmiotrace"
-
static unsigned long mmio_address;
module_param(mmio_address, ulong, 0);
MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
@@ -30,7 +31,7 @@ static unsigned v32(unsigned i)
static void do_write_test(void __iomem *p)
{
unsigned int i;
- pr_info(MODULE_NAME ": write test.\n");
+ pr_info("write test.\n");
mmiotrace_printk("Write test.\n");
for (i = 0; i < 256; i++)
@@ -47,7 +48,7 @@ static void do_read_test(void __iomem *p)
{
unsigned int i;
unsigned errs[3] = { 0 };
- pr_info(MODULE_NAME ": read test.\n");
+ pr_info("read test.\n");
mmiotrace_printk("Read test.\n");
for (i = 0; i < 256; i++)
@@ -68,7 +69,7 @@ static void do_read_test(void __iomem *p)
static void do_read_far_test(void __iomem *p)
{
- pr_info(MODULE_NAME ": read far test.\n");
+ pr_info("read far test.\n");
mmiotrace_printk("Read far test.\n");
ioread32(p + read_far);
@@ -78,7 +79,7 @@ static void do_test(unsigned long size)
{
void __iomem *p = ioremap_nocache(mmio_address, size);
if (!p) {
- pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
+ pr_err("could not ioremap, aborting.\n");
return;
}
mmiotrace_printk("ioremap returned %p.\n", p);
@@ -94,24 +95,22 @@ static int __init init(void)
unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
if (mmio_address == 0) {
- pr_err(MODULE_NAME ": you have to use the module argument "
- "mmio_address.\n");
- pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS"
- " YOU REALLY KNOW WHAT YOU ARE DOING!\n");
+ pr_err("you have to use the module argument mmio_address.\n");
+ pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n");
return -ENXIO;
}
- pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI "
- "address space, and writing 16 kB of rubbish in there.\n",
- size >> 10, mmio_address);
+ pr_warning("WARNING: mapping %lu kB @ 0x%08lx in PCI address space, "
+ "and writing 16 kB of rubbish in there.\n",
+ size >> 10, mmio_address);
do_test(size);
- pr_info(MODULE_NAME ": All done.\n");
+ pr_info("All done.\n");
return 0;
}
static void __exit cleanup(void)
{
- pr_debug(MODULE_NAME ": unloaded.\n");
+ pr_debug("unloaded.\n");
}
module_init(init);
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 8aa85f17667e..0a979f3e5b8a 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -18,6 +18,7 @@
#include <asm/mce.h>
#include <asm/xcr.h>
#include <asm/suspend.h>
+#include <asm/debugreg.h>
#ifdef CONFIG_X86_32
static struct saved_context saved_context;
@@ -142,31 +143,6 @@ static void fix_processor_context(void)
#endif
load_TR_desc(); /* This does ltr */
load_LDT(&current->active_mm->context); /* This does lldt */
-
- /*
- * Now maybe reload the debug registers
- */
- if (current->thread.debugreg7) {
-#ifdef CONFIG_X86_32
- set_debugreg(current->thread.debugreg0, 0);
- set_debugreg(current->thread.debugreg1, 1);
- set_debugreg(current->thread.debugreg2, 2);
- set_debugreg(current->thread.debugreg3, 3);
- /* no 4 and 5 */
- set_debugreg(current->thread.debugreg6, 6);
- set_debugreg(current->thread.debugreg7, 7);
-#else
- /* CONFIG_X86_64 */
- loaddebug(&current->thread, 0);
- loaddebug(&current->thread, 1);
- loaddebug(&current->thread, 2);
- loaddebug(&current->thread, 3);
- /* no 4 and 5 */
- loaddebug(&current->thread, 6);
- loaddebug(&current->thread, 7);
-#endif
- }
-
}
/**
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile
new file mode 100644
index 000000000000..f82082677337
--- /dev/null
+++ b/arch/x86/tools/Makefile
@@ -0,0 +1,31 @@
+PHONY += posttest
+
+ifeq ($(KBUILD_VERBOSE),1)
+ posttest_verbose = -v
+else
+ posttest_verbose =
+endif
+
+ifeq ($(CONFIG_64BIT),y)
+ posttest_64bit = -y
+else
+ posttest_64bit = -n
+endif
+
+distill_awk = $(srctree)/arch/x86/tools/distill.awk
+chkobjdump = $(srctree)/arch/x86/tools/chkobjdump.awk
+
+quiet_cmd_posttest = TEST $@
+ cmd_posttest = ($(OBJDUMP) -v | $(AWK) -f $(chkobjdump)) || $(OBJDUMP) -d -j .text $(objtree)/vmlinux | $(AWK) -f $(distill_awk) | $(obj)/test_get_len $(posttest_64bit) $(posttest_verbose)
+
+posttest: $(obj)/test_get_len vmlinux
+ $(call cmd,posttest)
+
+hostprogs-y := test_get_len
+
+# -I needed for generated C source and C source which in the kernel tree.
+HOSTCFLAGS_test_get_len.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x86/include/ -I$(srctree)/arch/x86/lib/ -I$(srctree)/include/
+
+# Dependencies are also needed.
+$(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c
+
diff --git a/arch/x86/tools/chkobjdump.awk b/arch/x86/tools/chkobjdump.awk
new file mode 100644
index 000000000000..0d13cd9fdcff
--- /dev/null
+++ b/arch/x86/tools/chkobjdump.awk
@@ -0,0 +1,23 @@
+# GNU objdump version checker
+#
+# Usage:
+# objdump -v | awk -f chkobjdump.awk
+BEGIN {
+ # objdump version 2.19 or later is OK for the test.
+ od_ver = 2;
+ od_sver = 19;
+}
+
+/^GNU/ {
+ split($4, ver, ".");
+ if (ver[1] > od_ver ||
+ (ver[1] == od_ver && ver[2] >= od_sver)) {
+ exit 1;
+ } else {
+ printf("Warning: objdump version %s is older than %d.%d\n",
+ $4, od_ver, od_sver);
+ print("Warning: Skipping posttest.");
+ # Logic is inverted, because we just skip test without error.
+ exit 0;
+ }
+}
diff --git a/arch/x86/tools/distill.awk b/arch/x86/tools/distill.awk
new file mode 100644
index 000000000000..c13c0ee48ab4
--- /dev/null
+++ b/arch/x86/tools/distill.awk
@@ -0,0 +1,47 @@
+#!/bin/awk -f
+# Usage: objdump -d a.out | awk -f distill.awk | ./test_get_len
+# Distills the disassembly as follows:
+# - Removes all lines except the disassembled instructions.
+# - For instructions that exceed 1 line (7 bytes), crams all the hex bytes
+# into a single line.
+# - Remove bad(or prefix only) instructions
+
+BEGIN {
+ prev_addr = ""
+ prev_hex = ""
+ prev_mnemonic = ""
+ bad_expr = "(\\(bad\\)|^rex|^.byte|^rep(z|nz)$|^lock$|^es$|^cs$|^ss$|^ds$|^fs$|^gs$|^data(16|32)$|^addr(16|32|64))"
+ fwait_expr = "^9b "
+ fwait_str="9b\tfwait"
+}
+
+/^ *[0-9a-f]+ <[^>]*>:/ {
+ # Symbol entry
+ printf("%s%s\n", $2, $1)
+}
+
+/^ *[0-9a-f]+:/ {
+ if (split($0, field, "\t") < 3) {
+ # This is a continuation of the same insn.
+ prev_hex = prev_hex field[2]
+ } else {
+ # Skip bad instructions
+ if (match(prev_mnemonic, bad_expr))
+ prev_addr = ""
+ # Split fwait from other f* instructions
+ if (match(prev_hex, fwait_expr) && prev_mnemonic != "fwait") {
+ printf "%s\t%s\n", prev_addr, fwait_str
+ sub(fwait_expr, "", prev_hex)
+ }
+ if (prev_addr != "")
+ printf "%s\t%s\t%s\n", prev_addr, prev_hex, prev_mnemonic
+ prev_addr = field[1]
+ prev_hex = field[2]
+ prev_mnemonic = field[3]
+ }
+}
+
+END {
+ if (prev_addr != "")
+ printf "%s\t%s\t%s\n", prev_addr, prev_hex, prev_mnemonic
+}
diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk
new file mode 100644
index 000000000000..e34e92a28eb6
--- /dev/null
+++ b/arch/x86/tools/gen-insn-attr-x86.awk
@@ -0,0 +1,380 @@
+#!/bin/awk -f
+# gen-insn-attr-x86.awk: Instruction attribute table generator
+# Written by Masami Hiramatsu <mhiramat@redhat.com>
+#
+# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c
+
+# Awk implementation sanity check
+function check_awk_implement() {
+ if (!match("abc", "[[:lower:]]+"))
+ return "Your awk doesn't support charactor-class."
+ if (sprintf("%x", 0) != "0")
+ return "Your awk has a printf-format problem."
+ return ""
+}
+
+# Clear working vars
+function clear_vars() {
+ delete table
+ delete lptable2
+ delete lptable1
+ delete lptable3
+ eid = -1 # escape id
+ gid = -1 # group id
+ aid = -1 # AVX id
+ tname = ""
+}
+
+BEGIN {
+ # Implementation error checking
+ awkchecked = check_awk_implement()
+ if (awkchecked != "") {
+ print "Error: " awkchecked > "/dev/stderr"
+ print "Please try to use gawk." > "/dev/stderr"
+ exit 1
+ }
+
+ # Setup generating tables
+ print "/* x86 opcode map generated from x86-opcode-map.txt */"
+ print "/* Do not change this code. */\n"
+ ggid = 1
+ geid = 1
+ gaid = 0
+ delete etable
+ delete gtable
+ delete atable
+
+ opnd_expr = "^[[:alpha:]/]"
+ ext_expr = "^\\("
+ sep_expr = "^\\|$"
+ group_expr = "^Grp[[:alnum:]]+"
+
+ imm_expr = "^[IJAO][[:lower:]]"
+ imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
+ imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
+ imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
+ imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)"
+ imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)"
+ imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)"
+ imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
+ imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
+ imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)"
+ imm_flag["Ob"] = "INAT_MOFFSET"
+ imm_flag["Ov"] = "INAT_MOFFSET"
+
+ modrm_expr = "^([CDEGMNPQRSUVW/][[:lower:]]+|NTA|T[012])"
+ force64_expr = "\\([df]64\\)"
+ rex_expr = "^REX(\\.[XRWB]+)*"
+ fpu_expr = "^ESC" # TODO
+
+ lprefix1_expr = "\\(66\\)"
+ lprefix2_expr = "\\(F3\\)"
+ lprefix3_expr = "\\(F2\\)"
+ max_lprefix = 4
+
+ vexok_expr = "\\(VEX\\)"
+ vexonly_expr = "\\(oVEX\\)"
+
+ prefix_expr = "\\(Prefix\\)"
+ prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
+ prefix_num["REPNE"] = "INAT_PFX_REPNE"
+ prefix_num["REP/REPE"] = "INAT_PFX_REPE"
+ prefix_num["LOCK"] = "INAT_PFX_LOCK"
+ prefix_num["SEG=CS"] = "INAT_PFX_CS"
+ prefix_num["SEG=DS"] = "INAT_PFX_DS"
+ prefix_num["SEG=ES"] = "INAT_PFX_ES"
+ prefix_num["SEG=FS"] = "INAT_PFX_FS"
+ prefix_num["SEG=GS"] = "INAT_PFX_GS"
+ prefix_num["SEG=SS"] = "INAT_PFX_SS"
+ prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
+ prefix_num["2bytes-VEX"] = "INAT_PFX_VEX2"
+ prefix_num["3bytes-VEX"] = "INAT_PFX_VEX3"
+
+ clear_vars()
+}
+
+function semantic_error(msg) {
+ print "Semantic error at " NR ": " msg > "/dev/stderr"
+ exit 1
+}
+
+function debug(msg) {
+ print "DEBUG: " msg
+}
+
+function array_size(arr, i,c) {
+ c = 0
+ for (i in arr)
+ c++
+ return c
+}
+
+/^Table:/ {
+ print "/* " $0 " */"
+ if (tname != "")
+ semantic_error("Hit Table: before EndTable:.");
+}
+
+/^Referrer:/ {
+ if (NF != 1) {
+ # escape opcode table
+ ref = ""
+ for (i = 2; i <= NF; i++)
+ ref = ref $i
+ eid = escape[ref]
+ tname = sprintf("inat_escape_table_%d", eid)
+ }
+}
+
+/^AVXcode:/ {
+ if (NF != 1) {
+ # AVX/escape opcode table
+ aid = $2
+ if (gaid <= aid)
+ gaid = aid + 1
+ if (tname == "") # AVX only opcode table
+ tname = sprintf("inat_avx_table_%d", $2)
+ }
+ if (aid == -1 && eid == -1) # primary opcode table
+ tname = "inat_primary_table"
+}
+
+/^GrpTable:/ {
+ print "/* " $0 " */"
+ if (!($2 in group))
+ semantic_error("No group: " $2 )
+ gid = group[$2]
+ tname = "inat_group_table_" gid
+}
+
+function print_table(tbl,name,fmt,n)
+{
+ print "const insn_attr_t " name " = {"
+ for (i = 0; i < n; i++) {
+ id = sprintf(fmt, i)
+ if (tbl[id])
+ print " [" id "] = " tbl[id] ","
+ }
+ print "};"
+}
+
+/^EndTable/ {
+ if (gid != -1) {
+ # print group tables
+ if (array_size(table) != 0) {
+ print_table(table, tname "[INAT_GROUP_TABLE_SIZE]",
+ "0x%x", 8)
+ gtable[gid,0] = tname
+ }
+ if (array_size(lptable1) != 0) {
+ print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]",
+ "0x%x", 8)
+ gtable[gid,1] = tname "_1"
+ }
+ if (array_size(lptable2) != 0) {
+ print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]",
+ "0x%x", 8)
+ gtable[gid,2] = tname "_2"
+ }
+ if (array_size(lptable3) != 0) {
+ print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]",
+ "0x%x", 8)
+ gtable[gid,3] = tname "_3"
+ }
+ } else {
+ # print primary/escaped tables
+ if (array_size(table) != 0) {
+ print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]",
+ "0x%02x", 256)
+ etable[eid,0] = tname
+ if (aid >= 0)
+ atable[aid,0] = tname
+ }
+ if (array_size(lptable1) != 0) {
+ print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]",
+ "0x%02x", 256)
+ etable[eid,1] = tname "_1"
+ if (aid >= 0)
+ atable[aid,1] = tname "_1"
+ }
+ if (array_size(lptable2) != 0) {
+ print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]",
+ "0x%02x", 256)
+ etable[eid,2] = tname "_2"
+ if (aid >= 0)
+ atable[aid,2] = tname "_2"
+ }
+ if (array_size(lptable3) != 0) {
+ print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]",
+ "0x%02x", 256)
+ etable[eid,3] = tname "_3"
+ if (aid >= 0)
+ atable[aid,3] = tname "_3"
+ }
+ }
+ print ""
+ clear_vars()
+}
+
+function add_flags(old,new) {
+ if (old && new)
+ return old " | " new
+ else if (old)
+ return old
+ else
+ return new
+}
+
+# convert operands to flags.
+function convert_operands(opnd, i,imm,mod)
+{
+ imm = null
+ mod = null
+ for (i in opnd) {
+ i = opnd[i]
+ if (match(i, imm_expr) == 1) {
+ if (!imm_flag[i])
+ semantic_error("Unknown imm opnd: " i)
+ if (imm) {
+ if (i != "Ib")
+ semantic_error("Second IMM error")
+ imm = add_flags(imm, "INAT_SCNDIMM")
+ } else
+ imm = imm_flag[i]
+ } else if (match(i, modrm_expr))
+ mod = "INAT_MODRM"
+ }
+ return add_flags(imm, mod)
+}
+
+/^[0-9a-f]+\:/ {
+ if (NR == 1)
+ next
+ # get index
+ idx = "0x" substr($1, 1, index($1,":") - 1)
+ if (idx in table)
+ semantic_error("Redefine " idx " in " tname)
+
+ # check if escaped opcode
+ if ("escape" == $2) {
+ if ($3 != "#")
+ semantic_error("No escaped name")
+ ref = ""
+ for (i = 4; i <= NF; i++)
+ ref = ref $i
+ if (ref in escape)
+ semantic_error("Redefine escape (" ref ")")
+ escape[ref] = geid
+ geid++
+ table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")"
+ next
+ }
+
+ variant = null
+ # converts
+ i = 2
+ while (i <= NF) {
+ opcode = $(i++)
+ delete opnds
+ ext = null
+ flags = null
+ opnd = null
+ # parse one opcode
+ if (match($i, opnd_expr)) {
+ opnd = $i
+ split($(i++), opnds, ",")
+ flags = convert_operands(opnds)
+ }
+ if (match($i, ext_expr))
+ ext = $(i++)
+ if (match($i, sep_expr))
+ i++
+ else if (i < NF)
+ semantic_error($i " is not a separator")
+
+ # check if group opcode
+ if (match(opcode, group_expr)) {
+ if (!(opcode in group)) {
+ group[opcode] = ggid
+ ggid++
+ }
+ flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")")
+ }
+ # check force(or default) 64bit
+ if (match(ext, force64_expr))
+ flags = add_flags(flags, "INAT_FORCE64")
+
+ # check REX prefix
+ if (match(opcode, rex_expr))
+ flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
+
+ # check coprocessor escape : TODO
+ if (match(opcode, fpu_expr))
+ flags = add_flags(flags, "INAT_MODRM")
+
+ # check VEX only code
+ if (match(ext, vexonly_expr))
+ flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
+
+ # check VEX only code
+ if (match(ext, vexok_expr))
+ flags = add_flags(flags, "INAT_VEXOK")
+
+ # check prefixes
+ if (match(ext, prefix_expr)) {
+ if (!prefix_num[opcode])
+ semantic_error("Unknown prefix: " opcode)
+ flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")")
+ }
+ if (length(flags) == 0)
+ continue
+ # check if last prefix
+ if (match(ext, lprefix1_expr)) {
+ lptable1[idx] = add_flags(lptable1[idx],flags)
+ variant = "INAT_VARIANT"
+ } else if (match(ext, lprefix2_expr)) {
+ lptable2[idx] = add_flags(lptable2[idx],flags)
+ variant = "INAT_VARIANT"
+ } else if (match(ext, lprefix3_expr)) {
+ lptable3[idx] = add_flags(lptable3[idx],flags)
+ variant = "INAT_VARIANT"
+ } else {
+ table[idx] = add_flags(table[idx],flags)
+ }
+ }
+ if (variant)
+ table[idx] = add_flags(table[idx],variant)
+}
+
+END {
+ if (awkchecked != "")
+ exit 1
+ # print escape opcode map's array
+ print "/* Escape opcode map array */"
+ print "const insn_attr_t const *inat_escape_tables[INAT_ESC_MAX + 1]" \
+ "[INAT_LSTPFX_MAX + 1] = {"
+ for (i = 0; i < geid; i++)
+ for (j = 0; j < max_lprefix; j++)
+ if (etable[i,j])
+ print " ["i"]["j"] = "etable[i,j]","
+ print "};\n"
+ # print group opcode map's array
+ print "/* Group opcode map array */"
+ print "const insn_attr_t const *inat_group_tables[INAT_GRP_MAX + 1]"\
+ "[INAT_LSTPFX_MAX + 1] = {"
+ for (i = 0; i < ggid; i++)
+ for (j = 0; j < max_lprefix; j++)
+ if (gtable[i,j])
+ print " ["i"]["j"] = "gtable[i,j]","
+ print "};\n"
+ # print AVX opcode map's array
+ print "/* AVX opcode map array */"
+ print "const insn_attr_t const *inat_avx_tables[X86_VEX_M_MAX + 1]"\
+ "[INAT_LSTPFX_MAX + 1] = {"
+ for (i = 0; i < gaid; i++)
+ for (j = 0; j < max_lprefix; j++)
+ if (atable[i,j])
+ print " ["i"]["j"] = "atable[i,j]","
+ print "};"
+}
+
diff --git a/arch/x86/tools/test_get_len.c b/arch/x86/tools/test_get_len.c
new file mode 100644
index 000000000000..d8214dc03fa7
--- /dev/null
+++ b/arch/x86/tools/test_get_len.c
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2009
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+
+#define unlikely(cond) (cond)
+
+#include <asm/insn.h>
+#include <inat.c>
+#include <insn.c>
+
+/*
+ * Test of instruction analysis in general and insn_get_length() in
+ * particular. See if insn_get_length() and the disassembler agree
+ * on the length of each instruction in an elf disassembly.
+ *
+ * Usage: objdump -d a.out | awk -f distill.awk | ./test_get_len
+ */
+
+const char *prog;
+static int verbose;
+static int x86_64;
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: objdump -d a.out | awk -f distill.awk |"
+ " %s [-y|-n] [-v] \n", prog);
+ fprintf(stderr, "\t-y 64bit mode\n");
+ fprintf(stderr, "\t-n 32bit mode\n");
+ fprintf(stderr, "\t-v verbose mode\n");
+ exit(1);
+}
+
+static void malformed_line(const char *line, int line_nr)
+{
+ fprintf(stderr, "%s: malformed line %d:\n%s", prog, line_nr, line);
+ exit(3);
+}
+
+static void dump_field(FILE *fp, const char *name, const char *indent,
+ struct insn_field *field)
+{
+ fprintf(fp, "%s.%s = {\n", indent, name);
+ fprintf(fp, "%s\t.value = %d, bytes[] = {%x, %x, %x, %x},\n",
+ indent, field->value, field->bytes[0], field->bytes[1],
+ field->bytes[2], field->bytes[3]);
+ fprintf(fp, "%s\t.got = %d, .nbytes = %d},\n", indent,
+ field->got, field->nbytes);
+}
+
+static void dump_insn(FILE *fp, struct insn *insn)
+{
+ fprintf(fp, "Instruction = { \n");
+ dump_field(fp, "prefixes", "\t", &insn->prefixes);
+ dump_field(fp, "rex_prefix", "\t", &insn->rex_prefix);
+ dump_field(fp, "vex_prefix", "\t", &insn->vex_prefix);
+ dump_field(fp, "opcode", "\t", &insn->opcode);
+ dump_field(fp, "modrm", "\t", &insn->modrm);
+ dump_field(fp, "sib", "\t", &insn->sib);
+ dump_field(fp, "displacement", "\t", &insn->displacement);
+ dump_field(fp, "immediate1", "\t", &insn->immediate1);
+ dump_field(fp, "immediate2", "\t", &insn->immediate2);
+ fprintf(fp, "\t.attr = %x, .opnd_bytes = %d, .addr_bytes = %d,\n",
+ insn->attr, insn->opnd_bytes, insn->addr_bytes);
+ fprintf(fp, "\t.length = %d, .x86_64 = %d, .kaddr = %p}\n",
+ insn->length, insn->x86_64, insn->kaddr);
+}
+
+static void parse_args(int argc, char **argv)
+{
+ int c;
+ prog = argv[0];
+ while ((c = getopt(argc, argv, "ynv")) != -1) {
+ switch (c) {
+ case 'y':
+ x86_64 = 1;
+ break;
+ case 'n':
+ x86_64 = 0;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+}
+
+#define BUFSIZE 256
+
+int main(int argc, char **argv)
+{
+ char line[BUFSIZE], sym[BUFSIZE] = "<unknown>";
+ unsigned char insn_buf[16];
+ struct insn insn;
+ int insns = 0, c;
+ int warnings = 0;
+
+ parse_args(argc, argv);
+
+ while (fgets(line, BUFSIZE, stdin)) {
+ char copy[BUFSIZE], *s, *tab1, *tab2;
+ int nb = 0;
+ unsigned int b;
+
+ if (line[0] == '<') {
+ /* Symbol line */
+ strcpy(sym, line);
+ continue;
+ }
+
+ insns++;
+ memset(insn_buf, 0, 16);
+ strcpy(copy, line);
+ tab1 = strchr(copy, '\t');
+ if (!tab1)
+ malformed_line(line, insns);
+ s = tab1 + 1;
+ s += strspn(s, " ");
+ tab2 = strchr(s, '\t');
+ if (!tab2)
+ malformed_line(line, insns);
+ *tab2 = '\0'; /* Characters beyond tab2 aren't examined */
+ while (s < tab2) {
+ if (sscanf(s, "%x", &b) == 1) {
+ insn_buf[nb++] = (unsigned char) b;
+ s += 3;
+ } else
+ break;
+ }
+ /* Decode an instruction */
+ insn_init(&insn, insn_buf, x86_64);
+ insn_get_length(&insn);
+ if (insn.length != nb) {
+ warnings++;
+ fprintf(stderr, "Warning: %s found difference at %s\n",
+ prog, sym);
+ fprintf(stderr, "Warning: %s", line);
+ fprintf(stderr, "Warning: objdump says %d bytes, but "
+ "insn_get_length() says %d\n", nb,
+ insn.length);
+ if (verbose)
+ dump_insn(stderr, &insn);
+ }
+ }
+ if (warnings)
+ fprintf(stderr, "Warning: decoded and checked %d"
+ " instructions with %d warnings\n", insns, warnings);
+ else
+ fprintf(stderr, "Succeed: decoded and checked %d"
+ " instructions\n", insns);
+ return 0;
+}
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 3439616d69f1..dfbf70e65860 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -178,6 +178,7 @@ static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0;
static void xen_cpuid(unsigned int *ax, unsigned int *bx,
unsigned int *cx, unsigned int *dx)
{
+ unsigned maskebx = ~0;
unsigned maskecx = ~0;
unsigned maskedx = ~0;
@@ -185,9 +186,16 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
* Mask out inconvenient features, to try and disable as many
* unsupported kernel subsystems as possible.
*/
- if (*ax == 1) {
+ switch (*ax) {
+ case 1:
maskecx = cpuid_leaf1_ecx_mask;
maskedx = cpuid_leaf1_edx_mask;
+ break;
+
+ case 0xb:
+ /* Suppress extended topology stuff */
+ maskebx = 0;
+ break;
}
asm(XEN_EMULATE_PREFIX "cpuid"
@@ -197,6 +205,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
"=d" (*dx)
: "0" (*ax), "2" (*cx));
+ *bx &= maskebx;
*cx &= maskecx;
*dx &= maskedx;
}
@@ -1075,6 +1084,8 @@ asmlinkage void __init xen_start_kernel(void)
* Set up some pagetable state before starting to set any ptes.
*/
+ xen_init_mmu_ops();
+
/* Prevent unwanted bits from being set in PTEs. */
__supported_pte_mask &= ~_PAGE_GLOBAL;
if (!xen_initial_domain())
@@ -1099,7 +1110,6 @@ asmlinkage void __init xen_start_kernel(void)
*/
xen_setup_stackprotector();
- xen_init_mmu_ops();
xen_init_irq_ops();
xen_init_cpuid_mask();
diff --git a/block/blk-core.c b/block/blk-core.c
index ac0fa10f8fa5..71da5111120c 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1161,7 +1161,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
const unsigned int ff = bio->bi_rw & REQ_FAILFAST_MASK;
int rw_flags;
- if (bio_rw_flagged(bio, BIO_RW_BARRIER) && bio_has_data(bio) &&
+ if (bio_rw_flagged(bio, BIO_RW_BARRIER) &&
(q->next_ordered == QUEUE_ORDERED_NONE)) {
bio_endio(bio, -EOPNOTSUPP);
return 0;
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 069a61017c02..aa1e9535e358 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -196,6 +196,7 @@ enum cfqq_state_flags {
CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */
CFQ_CFQQ_FLAG_sync, /* synchronous queue */
CFQ_CFQQ_FLAG_coop, /* has done a coop jump of the queue */
+ CFQ_CFQQ_FLAG_coop_preempt, /* coop preempt */
};
#define CFQ_CFQQ_FNS(name) \
@@ -222,6 +223,7 @@ CFQ_CFQQ_FNS(prio_changed);
CFQ_CFQQ_FNS(slice_new);
CFQ_CFQQ_FNS(sync);
CFQ_CFQQ_FNS(coop);
+CFQ_CFQQ_FNS(coop_preempt);
#undef CFQ_CFQQ_FNS
#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \
@@ -945,10 +947,13 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd,
{
if (!cfqq) {
cfqq = cfq_get_next_queue(cfqd);
- if (cfqq)
+ if (cfqq && !cfq_cfqq_coop_preempt(cfqq))
cfq_clear_cfqq_coop(cfqq);
}
+ if (cfqq)
+ cfq_clear_cfqq_coop_preempt(cfqq);
+
__cfq_set_active_queue(cfqd, cfqq);
return cfqq;
}
@@ -2051,7 +2056,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
* it's a metadata request and the current queue is doing regular IO.
*/
if (rq_is_meta(rq) && !cfqq->meta_pending)
- return false;
+ return true;
/*
* Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice.
@@ -2066,8 +2071,16 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
* if this request is as-good as one we would expect from the
* current cfqq, let it preempt
*/
- if (cfq_rq_close(cfqd, rq))
+ if (cfq_rq_close(cfqd, rq) && (!cfq_cfqq_coop(new_cfqq) ||
+ cfqd->busy_queues == 1)) {
+ /*
+ * Mark new queue coop_preempt, so its coop flag will not be
+ * cleared when new queue gets scheduled at the very first time
+ */
+ cfq_mark_cfqq_coop_preempt(new_cfqq);
+ cfq_mark_cfqq_coop(new_cfqq);
return true;
+ }
return false;
}
diff --git a/crypto/async_tx/Kconfig b/crypto/async_tx/Kconfig
index e5aeb2b79e6f..e28e276ac611 100644
--- a/crypto/async_tx/Kconfig
+++ b/crypto/async_tx/Kconfig
@@ -23,3 +23,8 @@ config ASYNC_RAID6_RECOV
select ASYNC_CORE
select ASYNC_PQ
+config ASYNC_TX_DISABLE_PQ_VAL_DMA
+ bool
+
+config ASYNC_TX_DISABLE_XOR_VAL_DMA
+ bool
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index b88db6d1dc65..ec87f53d5059 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -26,14 +26,10 @@
#include <linux/async_tx.h>
/**
- * scribble - space to hold throwaway P buffer for synchronous gen_syndrome
+ * pq_scribble_page - space to hold throwaway P or Q buffer for
+ * synchronous gen_syndrome
*/
-static struct page *scribble;
-
-static bool is_raid6_zero_block(struct page *p)
-{
- return p == (void *) raid6_empty_zero_page;
-}
+static struct page *pq_scribble_page;
/* the struct page *blocks[] parameter passed to async_gen_syndrome()
* and async_syndrome_val() contains the 'P' destination address at
@@ -83,7 +79,7 @@ do_async_gen_syndrome(struct dma_chan *chan, struct page **blocks,
* sources and update the coefficients accordingly
*/
for (i = 0, idx = 0; i < src_cnt; i++) {
- if (is_raid6_zero_block(blocks[i]))
+ if (blocks[i] == NULL)
continue;
dma_src[idx] = dma_map_page(dma->dev, blocks[i], offset, len,
DMA_TO_DEVICE);
@@ -160,9 +156,9 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
srcs = (void **) blocks;
for (i = 0; i < disks; i++) {
- if (is_raid6_zero_block(blocks[i])) {
+ if (blocks[i] == NULL) {
BUG_ON(i > disks - 3); /* P or Q can't be zero */
- srcs[i] = blocks[i];
+ srcs[i] = (void*)raid6_empty_zero_page;
} else
srcs[i] = page_address(blocks[i]) + offset;
}
@@ -186,10 +182,14 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
* blocks[disks-1] to NULL. When P or Q is omitted 'len' must be <=
* PAGE_SIZE as a temporary buffer of this size is used in the
* synchronous path. 'disks' always accounts for both destination
- * buffers.
+ * buffers. If any source buffers (blocks[i] where i < disks - 2) are
+ * set to NULL those buffers will be replaced with the raid6_zero_page
+ * in the synchronous path and omitted in the hardware-asynchronous
+ * path.
*
* 'blocks' note: if submit->scribble is NULL then the contents of
- * 'blocks' may be overridden
+ * 'blocks' may be overwritten to perform address conversions
+ * (dma_map_page() or page_address()).
*/
struct dma_async_tx_descriptor *
async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
@@ -227,11 +227,11 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
async_tx_quiesce(&submit->depend_tx);
if (!P(blocks, disks)) {
- P(blocks, disks) = scribble;
+ P(blocks, disks) = pq_scribble_page;
BUG_ON(len + offset > PAGE_SIZE);
}
if (!Q(blocks, disks)) {
- Q(blocks, disks) = scribble;
+ Q(blocks, disks) = pq_scribble_page;
BUG_ON(len + offset > PAGE_SIZE);
}
do_sync_gen_syndrome(blocks, offset, disks, len, submit);
@@ -240,6 +240,16 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
}
EXPORT_SYMBOL_GPL(async_gen_syndrome);
+static inline struct dma_chan *
+pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, size_t len)
+{
+ #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
+ return NULL;
+ #endif
+ return async_tx_find_channel(submit, DMA_PQ_VAL, NULL, 0, blocks,
+ disks, len);
+}
+
/**
* async_syndrome_val - asynchronously validate a raid6 syndrome
* @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1
@@ -260,13 +270,13 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
size_t len, enum sum_check_flags *pqres, struct page *spare,
struct async_submit_ctl *submit)
{
- struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ_VAL,
- NULL, 0, blocks, disks,
- len);
+ struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len);
struct dma_device *device = chan ? chan->device : NULL;
struct dma_async_tx_descriptor *tx;
+ unsigned char coefs[disks-2];
enum dma_ctrl_flags dma_flags = submit->cb_fn ? DMA_PREP_INTERRUPT : 0;
dma_addr_t *dma_src = NULL;
+ int src_cnt = 0;
BUG_ON(disks < 4);
@@ -285,22 +295,32 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
__func__, disks, len);
if (!P(blocks, disks))
dma_flags |= DMA_PREP_PQ_DISABLE_P;
+ else
+ pq[0] = dma_map_page(dev, P(blocks, disks),
+ offset, len,
+ DMA_TO_DEVICE);
if (!Q(blocks, disks))
dma_flags |= DMA_PREP_PQ_DISABLE_Q;
+ else
+ pq[1] = dma_map_page(dev, Q(blocks, disks),
+ offset, len,
+ DMA_TO_DEVICE);
+
if (submit->flags & ASYNC_TX_FENCE)
dma_flags |= DMA_PREP_FENCE;
- for (i = 0; i < disks; i++)
+ for (i = 0; i < disks-2; i++)
if (likely(blocks[i])) {
- BUG_ON(is_raid6_zero_block(blocks[i]));
- dma_src[i] = dma_map_page(dev, blocks[i],
- offset, len,
- DMA_TO_DEVICE);
+ dma_src[src_cnt] = dma_map_page(dev, blocks[i],
+ offset, len,
+ DMA_TO_DEVICE);
+ coefs[src_cnt] = raid6_gfexp[i];
+ src_cnt++;
}
for (;;) {
tx = device->device_prep_dma_pq_val(chan, pq, dma_src,
- disks - 2,
- raid6_gfexp,
+ src_cnt,
+ coefs,
len, pqres,
dma_flags);
if (likely(tx))
@@ -373,9 +393,9 @@ EXPORT_SYMBOL_GPL(async_syndrome_val);
static int __init async_pq_init(void)
{
- scribble = alloc_page(GFP_KERNEL);
+ pq_scribble_page = alloc_page(GFP_KERNEL);
- if (scribble)
+ if (pq_scribble_page)
return 0;
pr_err("%s: failed to allocate required spare page\n", __func__);
@@ -385,7 +405,7 @@ static int __init async_pq_init(void)
static void __exit async_pq_exit(void)
{
- put_page(scribble);
+ put_page(pq_scribble_page);
}
module_init(async_pq_init);
diff --git a/crypto/async_tx/async_raid6_recov.c b/crypto/async_tx/async_raid6_recov.c
index 6d73dde4786d..943f2abac9b4 100644
--- a/crypto/async_tx/async_raid6_recov.c
+++ b/crypto/async_tx/async_raid6_recov.c
@@ -131,8 +131,8 @@ async_mult(struct page *dest, struct page *src, u8 coef, size_t len,
}
static struct dma_async_tx_descriptor *
-__2data_recov_4(size_t bytes, int faila, int failb, struct page **blocks,
- struct async_submit_ctl *submit)
+__2data_recov_4(int disks, size_t bytes, int faila, int failb,
+ struct page **blocks, struct async_submit_ctl *submit)
{
struct dma_async_tx_descriptor *tx = NULL;
struct page *p, *q, *a, *b;
@@ -143,8 +143,8 @@ __2data_recov_4(size_t bytes, int faila, int failb, struct page **blocks,
void *cb_param = submit->cb_param;
void *scribble = submit->scribble;
- p = blocks[4-2];
- q = blocks[4-1];
+ p = blocks[disks-2];
+ q = blocks[disks-1];
a = blocks[faila];
b = blocks[failb];
@@ -170,8 +170,8 @@ __2data_recov_4(size_t bytes, int faila, int failb, struct page **blocks,
}
static struct dma_async_tx_descriptor *
-__2data_recov_5(size_t bytes, int faila, int failb, struct page **blocks,
- struct async_submit_ctl *submit)
+__2data_recov_5(int disks, size_t bytes, int faila, int failb,
+ struct page **blocks, struct async_submit_ctl *submit)
{
struct dma_async_tx_descriptor *tx = NULL;
struct page *p, *q, *g, *dp, *dq;
@@ -181,21 +181,22 @@ __2data_recov_5(size_t bytes, int faila, int failb, struct page **blocks,
dma_async_tx_callback cb_fn = submit->cb_fn;
void *cb_param = submit->cb_param;
void *scribble = submit->scribble;
- int uninitialized_var(good);
- int i;
+ int good_srcs, good, i;
- for (i = 0; i < 3; i++) {
+ good_srcs = 0;
+ good = -1;
+ for (i = 0; i < disks-2; i++) {
+ if (blocks[i] == NULL)
+ continue;
if (i == faila || i == failb)
continue;
- else {
- good = i;
- break;
- }
+ good = i;
+ good_srcs++;
}
- BUG_ON(i >= 3);
+ BUG_ON(good_srcs > 1);
- p = blocks[5-2];
- q = blocks[5-1];
+ p = blocks[disks-2];
+ q = blocks[disks-1];
g = blocks[good];
/* Compute syndrome with zero for the missing data pages
@@ -263,10 +264,10 @@ __2data_recov_n(int disks, size_t bytes, int faila, int failb,
* delta p and delta q
*/
dp = blocks[faila];
- blocks[faila] = (void *)raid6_empty_zero_page;
+ blocks[faila] = NULL;
blocks[disks-2] = dp;
dq = blocks[failb];
- blocks[failb] = (void *)raid6_empty_zero_page;
+ blocks[failb] = NULL;
blocks[disks-1] = dq;
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble);
@@ -323,6 +324,8 @@ struct dma_async_tx_descriptor *
async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
struct page **blocks, struct async_submit_ctl *submit)
{
+ int non_zero_srcs, i;
+
BUG_ON(faila == failb);
if (failb < faila)
swap(faila, failb);
@@ -334,11 +337,13 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
*/
if (!submit->scribble) {
void **ptrs = (void **) blocks;
- int i;
async_tx_quiesce(&submit->depend_tx);
for (i = 0; i < disks; i++)
- ptrs[i] = page_address(blocks[i]);
+ if (blocks[i] == NULL)
+ ptrs[i] = (void *) raid6_empty_zero_page;
+ else
+ ptrs[i] = page_address(blocks[i]);
raid6_2data_recov(disks, bytes, faila, failb, ptrs);
@@ -347,19 +352,30 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
return NULL;
}
- switch (disks) {
- case 4:
+ non_zero_srcs = 0;
+ for (i = 0; i < disks-2 && non_zero_srcs < 4; i++)
+ if (blocks[i])
+ non_zero_srcs++;
+ switch (non_zero_srcs) {
+ case 0:
+ case 1:
+ /* There must be at least 2 sources - the failed devices. */
+ BUG();
+
+ case 2:
/* dma devices do not uniformly understand a zero source pq
* operation (in contrast to the synchronous case), so
- * explicitly handle the 4 disk special case
+ * explicitly handle the special case of a 4 disk array with
+ * both data disks missing.
*/
- return __2data_recov_4(bytes, faila, failb, blocks, submit);
- case 5:
+ return __2data_recov_4(disks, bytes, faila, failb, blocks, submit);
+ case 3:
/* dma devices do not uniformly understand a single
* source pq operation (in contrast to the synchronous
- * case), so explicitly handle the 5 disk special case
+ * case), so explicitly handle the special case of a 5 disk
+ * array with 2 of 3 data disks missing.
*/
- return __2data_recov_5(bytes, faila, failb, blocks, submit);
+ return __2data_recov_5(disks, bytes, faila, failb, blocks, submit);
default:
return __2data_recov_n(disks, bytes, faila, failb, blocks, submit);
}
@@ -385,6 +401,7 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
dma_async_tx_callback cb_fn = submit->cb_fn;
void *cb_param = submit->cb_param;
void *scribble = submit->scribble;
+ int good_srcs, good, i;
struct page *srcs[2];
pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
@@ -394,11 +411,13 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
*/
if (!scribble) {
void **ptrs = (void **) blocks;
- int i;
async_tx_quiesce(&submit->depend_tx);
for (i = 0; i < disks; i++)
- ptrs[i] = page_address(blocks[i]);
+ if (blocks[i] == NULL)
+ ptrs[i] = (void*)raid6_empty_zero_page;
+ else
+ ptrs[i] = page_address(blocks[i]);
raid6_datap_recov(disks, bytes, faila, ptrs);
@@ -407,6 +426,20 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
return NULL;
}
+ good_srcs = 0;
+ good = -1;
+ for (i = 0; i < disks-2; i++) {
+ if (i == faila)
+ continue;
+ if (blocks[i]) {
+ good = i;
+ good_srcs++;
+ if (good_srcs > 1)
+ break;
+ }
+ }
+ BUG_ON(good_srcs == 0);
+
p = blocks[disks-2];
q = blocks[disks-1];
@@ -414,14 +447,13 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
* Use the dead data page as temporary storage for delta q
*/
dq = blocks[faila];
- blocks[faila] = (void *)raid6_empty_zero_page;
+ blocks[faila] = NULL;
blocks[disks-1] = dq;
- /* in the 4 disk case we only need to perform a single source
- * multiplication
+ /* in the 4-disk case we only need to perform a single source
+ * multiplication with the one good data block.
*/
- if (disks == 4) {
- int good = faila == 0 ? 1 : 0;
+ if (good_srcs == 1) {
struct page *g = blocks[good];
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL,
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index b459a9034aac..079ae8ca590b 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -44,20 +44,23 @@ do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
void *cb_param_orig = submit->cb_param;
enum async_tx_flags flags_orig = submit->flags;
enum dma_ctrl_flags dma_flags;
- int xor_src_cnt;
+ int xor_src_cnt = 0;
dma_addr_t dma_dest;
/* map the dest bidrectional in case it is re-used as a source */
dma_dest = dma_map_page(dma->dev, dest, offset, len, DMA_BIDIRECTIONAL);
for (i = 0; i < src_cnt; i++) {
/* only map the dest once */
+ if (!src_list[i])
+ continue;
if (unlikely(src_list[i] == dest)) {
- dma_src[i] = dma_dest;
+ dma_src[xor_src_cnt++] = dma_dest;
continue;
}
- dma_src[i] = dma_map_page(dma->dev, src_list[i], offset,
- len, DMA_TO_DEVICE);
+ dma_src[xor_src_cnt++] = dma_map_page(dma->dev, src_list[i], offset,
+ len, DMA_TO_DEVICE);
}
+ src_cnt = xor_src_cnt;
while (src_cnt) {
submit->flags = flags_orig;
@@ -123,7 +126,7 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
int src_cnt, size_t len, struct async_submit_ctl *submit)
{
int i;
- int xor_src_cnt;
+ int xor_src_cnt = 0;
int src_off = 0;
void *dest_buf;
void **srcs;
@@ -135,8 +138,9 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
/* convert to buffer pointers */
for (i = 0; i < src_cnt; i++)
- srcs[i] = page_address(src_list[i]) + offset;
-
+ if (src_list[i])
+ srcs[xor_src_cnt++] = page_address(src_list[i]) + offset;
+ src_cnt = xor_src_cnt;
/* set destination address */
dest_buf = page_address(dest) + offset;
@@ -230,6 +234,17 @@ static int page_is_zero(struct page *p, unsigned int offset, size_t len)
memcmp(a, a + 4, len - 4) == 0);
}
+static inline struct dma_chan *
+xor_val_chan(struct async_submit_ctl *submit, struct page *dest,
+ struct page **src_list, int src_cnt, size_t len)
+{
+ #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
+ return NULL;
+ #endif
+ return async_tx_find_channel(submit, DMA_XOR_VAL, &dest, 1, src_list,
+ src_cnt, len);
+}
+
/**
* async_xor_val - attempt a xor parity check with a dma engine.
* @dest: destination page used if the xor is performed synchronously
@@ -251,9 +266,7 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
int src_cnt, size_t len, enum sum_check_flags *result,
struct async_submit_ctl *submit)
{
- struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR_VAL,
- &dest, 1, src_list,
- src_cnt, len);
+ struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len);
struct dma_device *device = chan ? chan->device : NULL;
struct dma_async_tx_descriptor *tx = NULL;
dma_addr_t *dma_src = NULL;
diff --git a/crypto/gcm.c b/crypto/gcm.c
index 5fc3292483ef..c6547130624c 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -40,7 +40,7 @@ struct crypto_rfc4106_ctx {
struct crypto_gcm_ghash_ctx {
unsigned int cryptlen;
struct scatterlist *src;
- crypto_completion_t complete;
+ void (*complete)(struct aead_request *req, int err);
};
struct crypto_gcm_req_priv_ctx {
@@ -267,23 +267,26 @@ static int gcm_hash_final(struct aead_request *req,
return crypto_ahash_final(ahreq);
}
-static void gcm_hash_final_done(struct crypto_async_request *areq,
- int err)
+static void __gcm_hash_final_done(struct aead_request *req, int err)
{
- struct aead_request *req = areq->data;
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
if (!err)
crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16);
- gctx->complete(areq, err);
+ gctx->complete(req, err);
}
-static void gcm_hash_len_done(struct crypto_async_request *areq,
- int err)
+static void gcm_hash_final_done(struct crypto_async_request *areq, int err)
{
struct aead_request *req = areq->data;
+
+ __gcm_hash_final_done(req, err);
+}
+
+static void __gcm_hash_len_done(struct aead_request *req, int err)
+{
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
if (!err) {
@@ -292,13 +295,18 @@ static void gcm_hash_len_done(struct crypto_async_request *areq,
return;
}
- gcm_hash_final_done(areq, err);
+ __gcm_hash_final_done(req, err);
}
-static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
- int err)
+static void gcm_hash_len_done(struct crypto_async_request *areq, int err)
{
struct aead_request *req = areq->data;
+
+ __gcm_hash_len_done(req, err);
+}
+
+static void __gcm_hash_crypt_remain_done(struct aead_request *req, int err)
+{
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
if (!err) {
@@ -307,13 +315,19 @@ static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
return;
}
- gcm_hash_len_done(areq, err);
+ __gcm_hash_len_done(req, err);
}
-static void gcm_hash_crypt_done(struct crypto_async_request *areq,
- int err)
+static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
+ int err)
{
struct aead_request *req = areq->data;
+
+ __gcm_hash_crypt_remain_done(req, err);
+}
+
+static void __gcm_hash_crypt_done(struct aead_request *req, int err)
+{
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
unsigned int remain;
@@ -327,13 +341,18 @@ static void gcm_hash_crypt_done(struct crypto_async_request *areq,
return;
}
- gcm_hash_crypt_remain_done(areq, err);
+ __gcm_hash_crypt_remain_done(req, err);
}
-static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
- int err)
+static void gcm_hash_crypt_done(struct crypto_async_request *areq, int err)
{
struct aead_request *req = areq->data;
+
+ __gcm_hash_crypt_done(req, err);
+}
+
+static void __gcm_hash_assoc_remain_done(struct aead_request *req, int err)
+{
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
crypto_completion_t complete;
@@ -350,15 +369,21 @@ static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
}
if (remain)
- gcm_hash_crypt_done(areq, err);
+ __gcm_hash_crypt_done(req, err);
else
- gcm_hash_crypt_remain_done(areq, err);
+ __gcm_hash_crypt_remain_done(req, err);
}
-static void gcm_hash_assoc_done(struct crypto_async_request *areq,
- int err)
+static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
+ int err)
{
struct aead_request *req = areq->data;
+
+ __gcm_hash_assoc_remain_done(req, err);
+}
+
+static void __gcm_hash_assoc_done(struct aead_request *req, int err)
+{
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
unsigned int remain;
@@ -371,13 +396,18 @@ static void gcm_hash_assoc_done(struct crypto_async_request *areq,
return;
}
- gcm_hash_assoc_remain_done(areq, err);
+ __gcm_hash_assoc_remain_done(req, err);
}
-static void gcm_hash_init_done(struct crypto_async_request *areq,
- int err)
+static void gcm_hash_assoc_done(struct crypto_async_request *areq, int err)
{
struct aead_request *req = areq->data;
+
+ __gcm_hash_assoc_done(req, err);
+}
+
+static void __gcm_hash_init_done(struct aead_request *req, int err)
+{
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
crypto_completion_t complete;
unsigned int remain = 0;
@@ -393,9 +423,16 @@ static void gcm_hash_init_done(struct crypto_async_request *areq,
}
if (remain)
- gcm_hash_assoc_done(areq, err);
+ __gcm_hash_assoc_done(req, err);
else
- gcm_hash_assoc_remain_done(areq, err);
+ __gcm_hash_assoc_remain_done(req, err);
+}
+
+static void gcm_hash_init_done(struct crypto_async_request *areq, int err)
+{
+ struct aead_request *req = areq->data;
+
+ __gcm_hash_init_done(req, err);
}
static int gcm_hash(struct aead_request *req,
@@ -457,10 +494,8 @@ static void gcm_enc_copy_hash(struct aead_request *req,
crypto_aead_authsize(aead), 1);
}
-static void gcm_enc_hash_done(struct crypto_async_request *areq,
- int err)
+static void gcm_enc_hash_done(struct aead_request *req, int err)
{
- struct aead_request *req = areq->data;
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
if (!err)
@@ -469,8 +504,7 @@ static void gcm_enc_hash_done(struct crypto_async_request *areq,
aead_request_complete(req, err);
}
-static void gcm_encrypt_done(struct crypto_async_request *areq,
- int err)
+static void gcm_encrypt_done(struct crypto_async_request *areq, int err)
{
struct aead_request *req = areq->data;
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
@@ -479,9 +513,13 @@ static void gcm_encrypt_done(struct crypto_async_request *areq,
err = gcm_hash(req, pctx);
if (err == -EINPROGRESS || err == -EBUSY)
return;
+ else if (!err) {
+ crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16);
+ gcm_enc_copy_hash(req, pctx);
+ }
}
- gcm_enc_hash_done(areq, err);
+ aead_request_complete(req, err);
}
static int crypto_gcm_encrypt(struct aead_request *req)
@@ -538,9 +576,8 @@ static void gcm_decrypt_done(struct crypto_async_request *areq, int err)
aead_request_complete(req, err);
}
-static void gcm_dec_hash_done(struct crypto_async_request *areq, int err)
+static void gcm_dec_hash_done(struct aead_request *req, int err)
{
- struct aead_request *req = areq->data;
struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
struct ablkcipher_request *abreq = &pctx->u.abreq;
struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
@@ -552,9 +589,11 @@ static void gcm_dec_hash_done(struct crypto_async_request *areq, int err)
err = crypto_ablkcipher_decrypt(abreq);
if (err == -EINPROGRESS || err == -EBUSY)
return;
+ else if (!err)
+ err = crypto_gcm_verify(req, pctx);
}
- gcm_decrypt_done(areq, err);
+ aead_request_complete(req, err);
}
static int crypto_gcm_decrypt(struct aead_request *req)
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 0ed42d8870c7..93d2c7971df6 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -218,10 +218,10 @@ config ACPI_PROCESSOR_AGGREGATOR
depends on X86
help
ACPI 4.0 defines processor Aggregator, which enables OS to perform
- specfic processor configuration and control that applies to all
+ specific processor configuration and control that applies to all
processors in the platform. Currently only logical processor idling
is defined, which is to reduce power consumption. This driver
- support the new device.
+ supports the new device.
config ACPI_THERMAL
tristate "Thermal Zone"
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 98b9690b0159..b6ed60b57b0d 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -245,6 +245,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event,
(u32) ac->state);
+ acpi_notifier_call_chain(device, event, (u32) ac->state);
#ifdef CONFIG_ACPI_SYSFS_POWER
kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
#endif
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h
index 8e679ef5b231..a4471e3d3853 100644
--- a/drivers/acpi/acpica/acconfig.h
+++ b/drivers/acpi/acpica/acconfig.h
@@ -103,9 +103,9 @@
#define ACPI_MAX_REFERENCE_COUNT 0x1000
-/* Size of cached memory mapping for system memory operation region */
+/* Default page size for use in mapping memory for operation regions */
-#define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096
+#define ACPI_DEFAULT_PAGE_SIZE 4096 /* Must be power of 2 */
/* owner_id tracking. 8 entries allows for 255 owner_ids */
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index cd80d1dd1950..57bdaf6ffab1 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -203,8 +203,9 @@ static const union acpi_predefined_info predefined_names[] =
{{"_BCT", 1, ACPI_RTYPE_INTEGER}},
{{"_BDN", 0, ACPI_RTYPE_INTEGER}},
{{"_BFS", 1, 0}},
- {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */
- {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}},
+ {{"_BIF", 0, ACPI_RTYPE_PACKAGE} }, /* Fixed-length (9 Int),(4 Str/Buf) */
+ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9,
+ ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER}, 4, 0} },
{{"_BIX", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int),(4 Str) */
{{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4,
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
index 3a54b737d2da..2bd83ac57c3a 100644
--- a/drivers/acpi/acpica/exregion.c
+++ b/drivers/acpi/acpica/exregion.c
@@ -77,7 +77,8 @@ acpi_ex_system_memory_space_handler(u32 function,
void *logical_addr_ptr = NULL;
struct acpi_mem_space_context *mem_info = region_context;
u32 length;
- acpi_size window_size;
+ acpi_size map_length;
+ acpi_size page_boundary_map_length;
#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
u32 remainder;
#endif
@@ -144,25 +145,39 @@ acpi_ex_system_memory_space_handler(u32 function,
}
/*
- * Don't attempt to map memory beyond the end of the region, and
- * constrain the maximum mapping size to something reasonable.
+ * Attempt to map from the requested address to the end of the region.
+ * However, we will never map more than one page, nor will we cross
+ * a page boundary.
*/
- window_size = (acpi_size)
+ map_length = (acpi_size)
((mem_info->address + mem_info->length) - address);
- if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
- window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
+ /*
+ * If mapping the entire remaining portion of the region will cross
+ * a page boundary, just map up to the page boundary, do not cross.
+ * On some systems, crossing a page boundary while mapping regions
+ * can cause warnings if the pages have different attributes
+ * due to resource management
+ */
+ page_boundary_map_length =
+ ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address;
+
+ if (!page_boundary_map_length) {
+ page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE;
+ }
+
+ if (map_length > page_boundary_map_length) {
+ map_length = page_boundary_map_length;
}
/* Create a new mapping starting at the address given */
- mem_info->mapped_logical_address =
- acpi_os_map_memory((acpi_physical_address) address, window_size);
+ mem_info->mapped_logical_address = acpi_os_map_memory((acpi_physical_address) address, map_length);
if (!mem_info->mapped_logical_address) {
ACPI_ERROR((AE_INFO,
"Could not map memory at %8.8X%8.8X, size %X",
ACPI_FORMAT_NATIVE_UINT(address),
- (u32) window_size));
+ (u32) map_length));
mem_info->mapped_length = 0;
return_ACPI_STATUS(AE_NO_MEMORY);
}
@@ -170,7 +185,7 @@ acpi_ex_system_memory_space_handler(u32 function,
/* Save the physical address and mapping size */
mem_info->mapped_physical_address = address;
- mem_info->mapped_length = window_size;
+ mem_info->mapped_length = map_length;
}
/*
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index e56b2a7b53db..23e5a0519af5 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -224,6 +224,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
* _OSI(Linux) helps sound
* DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"),
* DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"),
+ * T400, T500
* _OSI(Linux) has Linux specific hooks
* DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
* _OSI(Linux) is a NOP:
@@ -254,6 +255,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
},
},
+ {
+ .callback = dmi_enable_osi_linux,
+ .ident = "Lenovo ThinkPad T400",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T400"),
+ },
+ },
+ {
+ .callback = dmi_enable_osi_linux,
+ .ident = "Lenovo ThinkPad T500",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"),
+ },
+ },
{}
};
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 9335b87c5174..0c9c6a9a002c 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -251,6 +251,9 @@ int acpi_lid_open(void)
acpi_status status;
unsigned long long state;
+ if (!lid_device)
+ return -ENODEV;
+
status = acpi_evaluate_integer(lid_device->handle, "_LID", NULL,
&state);
if (ACPI_FAILURE(status))
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 31122214e0ec..1af808171d46 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -389,6 +389,17 @@ struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
pbus = pdev->subordinate;
pci_dev_put(pdev);
+
+ /*
+ * This function may be called for a non-PCI device that has a
+ * PCI parent (eg. a disk under a PCI SATA controller). In that
+ * case pdev->subordinate will be NULL for the parent.
+ */
+ if (!pbus) {
+ dev_dbg(&pdev->dev, "Not a PCI-to-PCI bridge\n");
+ pdev = NULL;
+ break;
+ }
}
out:
list_for_each_entry_safe(node, tmp, &device_list, node)
diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c
index e6bfd77986b8..2ef7030a0c28 100644
--- a/drivers/acpi/power_meter.c
+++ b/drivers/acpi/power_meter.c
@@ -294,7 +294,11 @@ static int set_acpi_trip(struct acpi_power_meter_resource *resource)
return -EINVAL;
}
- return data;
+ /* _PTP returns 0 on success, nonzero otherwise */
+ if (data)
+ return -EINVAL;
+
+ return 0;
}
static ssize_t set_trip(struct device *dev, struct device_attribute *devattr,
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index f8b6f555ba52..d0d25e2e1ced 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -393,7 +393,7 @@ acpi_system_write_wakeup_device(struct file *file,
struct list_head *node, *next;
char strbuf[5];
char str[5] = "";
- int len = count;
+ unsigned int len = count;
struct acpi_device *found_dev = NULL;
if (len > 4)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index c567b46dfa0f..ec742a4e5635 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -770,7 +770,7 @@ static struct notifier_block acpi_cpu_notifier =
.notifier_call = acpi_cpu_soft_notify,
};
-static int acpi_processor_add(struct acpi_device *device)
+static int __cpuinit acpi_processor_add(struct acpi_device *device)
{
struct acpi_processor *pr = NULL;
int result = 0;
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 4c6c14c1e307..1c5d7a8b2fdf 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -1133,15 +1133,15 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
int result = 0;
struct acpi_processor_throttling *pthrottling;
+ if (!pr)
+ return -EINVAL;
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
pr->throttling.address,
pr->throttling.duty_offset,
pr->throttling.duty_width));
- if (!pr)
- return -EINVAL;
-
/*
* Evaluate _PTC, _TSS and _TPC
* They must all be present or none of them can be used.
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index a90afcc723ab..5f2c379ab7bf 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -413,6 +413,38 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
},
},
{
+ .callback = init_set_sci_en_on_resume,
+ .ident = "Hewlett-Packard Pavilion dv4",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4"),
+ },
+ },
+ {
+ .callback = init_set_sci_en_on_resume,
+ .ident = "Hewlett-Packard Pavilion dv7",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7"),
+ },
+ },
+ {
+ .callback = init_set_sci_en_on_resume,
+ .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"),
+ },
+ },
+ {
+ .callback = init_set_sci_en_on_resume,
+ .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario CQ40 Notebook PC"),
+ },
+ },
+ {
.callback = init_old_suspend_ordering,
.ident = "Panasonic CF51-2L",
.matches = {
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index f6e54bf8dd96..05dff631591c 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1109,7 +1109,12 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
*/
/* Does this device support video switching? */
- if (video->cap._DOS) {
+ if (video->cap._DOS || video->cap._DOD) {
+ if (!video->cap._DOS) {
+ printk(KERN_WARNING FW_BUG
+ "ACPI(%s) defines _DOD but not _DOS\n",
+ acpi_device_bid(video->device));
+ }
video->flags.multihead = 1;
status = 0;
}
@@ -1218,7 +1223,7 @@ acpi_video_device_write_state(struct file *file,
u32 state = 0;
- if (!dev || count + 1 > sizeof str)
+ if (!dev || count >= sizeof(str))
return -EINVAL;
if (copy_from_user(str, buffer, count))
@@ -1275,7 +1280,7 @@ acpi_video_device_write_brightness(struct file *file,
int i;
- if (!dev || !dev->brightness || count + 1 > sizeof str)
+ if (!dev || !dev->brightness || count >= sizeof(str))
return -EINVAL;
if (copy_from_user(str, buffer, count))
@@ -1557,7 +1562,7 @@ acpi_video_bus_write_POST(struct file *file,
unsigned long long opt, options;
- if (!video || count + 1 > sizeof str)
+ if (!video || count >= sizeof(str))
return -EINVAL;
status = acpi_video_bus_POST_options(video, &options);
@@ -1597,7 +1602,7 @@ acpi_video_bus_write_DOS(struct file *file,
unsigned long opt;
- if (!video || count + 1 > sizeof str)
+ if (!video || count >= sizeof(str))
return -EINVAL;
if (copy_from_user(str, buffer, count))
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 7032f25da9b5..575593a8b4e6 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -84,7 +84,7 @@ long acpi_is_video_device(struct acpi_device *device)
return 0;
/* Does this device able to support video switching ? */
- if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) ||
ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index b1a257746a19..a3241a1a710b 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -575,7 +575,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */
/* AMD */
- { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD SB900 */
+ { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
/* AMD is using RAID class only for ahci controllers */
{ PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
@@ -605,6 +605,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci_yesncq }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq }, /* Linux ID */
{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */
{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */
{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */
@@ -2717,6 +2718,30 @@ static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
},
.driver_data = "20071026", /* yyyymmdd */
},
+ /*
+ * All BIOS versions for the MSI K9A2 Platinum (MS-7376)
+ * support 64bit DMA.
+ *
+ * BIOS versions earlier than 1.5 had the Manufacturer DMI
+ * fields as "MICRO-STAR INTERANTIONAL CO.,LTD".
+ * This spelling mistake was fixed in BIOS version 1.5, so
+ * 1.5 and later have the Manufacturer as
+ * "MICRO-STAR INTERNATIONAL CO.,LTD".
+ * So try to match on DMI_BOARD_VENDOR of "MICRO-STAR INTER".
+ *
+ * BIOS versions earlier than 1.9 had a Board Product Name
+ * DMI field of "MS-7376". This was changed to be
+ * "K9A2 Platinum (MS-7376)" in version 1.9, but we can still
+ * match on DMI_BOARD_NAME of "MS-7376".
+ */
+ {
+ .ident = "MSI K9A2 Platinum",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR,
+ "MICRO-STAR INTER"),
+ DMI_MATCH(DMI_BOARD_NAME, "MS-7376"),
+ },
+ },
{ }
};
const struct dmi_system_id *match;
@@ -2728,18 +2753,24 @@ static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
!match)
return false;
+ if (!match->driver_data)
+ goto enable_64bit;
+
dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
- if (strcmp(buf, match->driver_data) >= 0) {
- dev_printk(KERN_WARNING, &pdev->dev, "%s: enabling 64bit DMA\n",
- match->ident);
- return true;
- } else {
+ if (strcmp(buf, match->driver_data) >= 0)
+ goto enable_64bit;
+ else {
dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, "
"forcing 32bit DMA, update BIOS\n", match->ident);
return false;
}
+
+enable_64bit:
+ dev_printk(KERN_WARNING, &pdev->dev, "%s: enabling 64bit DMA\n",
+ match->ident);
+ return true;
}
static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b525a0981348..dc72690ed5db 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4919,10 +4919,11 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev)
*/
void ata_qc_free(struct ata_queued_cmd *qc)
{
- struct ata_port *ap = qc->ap;
+ struct ata_port *ap;
unsigned int tag;
WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
+ ap = qc->ap;
qc->flags = 0;
tag = qc->tag;
@@ -4934,11 +4935,13 @@ void ata_qc_free(struct ata_queued_cmd *qc)
void __ata_qc_complete(struct ata_queued_cmd *qc)
{
- struct ata_port *ap = qc->ap;
- struct ata_link *link = qc->dev->link;
+ struct ata_port *ap;
+ struct ata_link *link;
WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE));
+ ap = qc->ap;
+ link = qc->dev->link;
if (likely(qc->flags & ATA_QCFLAG_DMAMAP))
ata_sg_clean(qc);
@@ -5028,12 +5031,14 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
qc->flags |= ATA_QCFLAG_FAILED;
if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
- if (!ata_tag_internal(qc->tag)) {
- /* always fill result TF for failed qc */
- fill_result_tf(qc);
+ /* always fill result TF for failed qc */
+ fill_result_tf(qc);
+
+ if (!ata_tag_internal(qc->tag))
ata_qc_schedule_eh(qc);
- return;
- }
+ else
+ __ata_qc_complete(qc);
+ return;
}
WARN_ON_ONCE(ap->pflags & ATA_PFLAG_FROZEN);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 0a97822da211..bba2ae5df1c2 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2981,12 +2981,14 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
* device detection messages backwards.
*/
ata_for_each_dev(dev, link, ALL) {
- if (!(new_mask & (1 << dev->devno)) ||
- dev->class == ATA_DEV_PMP)
+ if (!(new_mask & (1 << dev->devno)))
continue;
dev->class = ehc->classes[dev->devno];
+ if (dev->class == ATA_DEV_PMP)
+ continue;
+
ehc->i.flags |= ATA_EHI_PRINTINFO;
rc = ata_dev_configure(dev);
ehc->i.flags &= ~ATA_EHI_PRINTINFO;
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index aa4b3f6ae771..ae4454d4e955 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -246,7 +246,7 @@ static const struct pci_device_id atiixp[] = {
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), },
- { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_SB900_IDE), },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), },
{ },
};
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index dc99e26f8e5b..1b392c9e8531 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -177,9 +177,6 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
.drain_fifo = pcmcia_8bit_drain_fifo,
};
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
struct pcmcia_config_check {
unsigned long ctl_base;
@@ -252,7 +249,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
struct ata_port *ap;
struct ata_pcmcia_info *info;
struct pcmcia_config_check *stk = NULL;
- int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
+ int is_kme = 0, ret = -ENOMEM, p;
unsigned long io_base, ctl_base;
void __iomem *io_addr, *ctl_addr;
int n_ports = 1;
@@ -271,7 +268,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
pdev->io.IOAddrLines = 3;
pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- pdev->irq.IRQInfo1 = IRQ_LEVEL_ID;
pdev->conf.Attributes = CONF_ENABLE_IRQ;
pdev->conf.IntType = INT_MEMORY_AND_IO;
@@ -296,8 +292,13 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
}
io_base = pdev->io.BasePort1;
ctl_base = stk->ctl_base;
- CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
+ ret = pcmcia_request_irq(pdev, &pdev->irq);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_configuration(pdev, &pdev->conf);
+ if (ret)
+ goto failed;
/* iomap */
ret = -ENOMEM;
@@ -351,8 +352,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
kfree(stk);
return 0;
-cs_failed:
- cs_error(pdev, last_fn, last_ret);
failed:
kfree(stk);
info->ndev = 0;
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index f49814d6fd2e..3bbed8322ecf 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -235,8 +235,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA2,
.port_ops = &sc1200_port_ops
};
- /* Can't enable port 2 yet, see top comments */
- const struct ata_port_info *ppi[] = { &info, };
+ const struct ata_port_info *ppi[] = { &info, NULL };
return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
}
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 45657cacec43..88984b803d6d 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -111,7 +111,7 @@ static const struct via_isa_bridge {
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
- { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
+ { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0xff, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
{ "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index d344db42a002..172b57e6543f 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -707,34 +707,17 @@ static unsigned int sata_fsl_dev_classify(struct ata_port *ap)
return ata_dev_classify(&tf);
}
-static int sata_fsl_prereset(struct ata_link *link, unsigned long deadline)
-{
- /* FIXME: Never skip softreset, sata_fsl_softreset() is
- * combination of soft and hard resets. sata_fsl_softreset()
- * needs to be splitted into soft and hard resets.
- */
- return 0;
-}
-
-static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
+static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
struct ata_port *ap = link->ap;
- struct sata_fsl_port_priv *pp = ap->private_data;
struct sata_fsl_host_priv *host_priv = ap->host->private_data;
void __iomem *hcr_base = host_priv->hcr_base;
- int pmp = sata_srst_pmp(link);
u32 temp;
- struct ata_taskfile tf;
- u8 *cfis;
- u32 Serror;
int i = 0;
unsigned long start_jiffies;
- DPRINTK("in xx_softreset\n");
-
- if (pmp != SATA_PMP_CTRL_PORT)
- goto issue_srst;
+ DPRINTK("in xx_hardreset\n");
try_offline_again:
/*
@@ -749,7 +732,7 @@ try_offline_again:
if (temp & ONLINE) {
ata_port_printk(ap, KERN_ERR,
- "Softreset failed, not off-lined %d\n", i);
+ "Hardreset failed, not off-lined %d\n", i);
/*
* Try to offline controller atleast twice
@@ -761,7 +744,7 @@ try_offline_again:
goto try_offline_again;
}
- DPRINTK("softreset, controller off-lined\n");
+ DPRINTK("hardreset, controller off-lined\n");
VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
@@ -786,11 +769,11 @@ try_offline_again:
if (!(temp & ONLINE)) {
ata_port_printk(ap, KERN_ERR,
- "Softreset failed, not on-lined\n");
+ "Hardreset failed, not on-lined\n");
goto err;
}
- DPRINTK("softreset, controller off-lined & on-lined\n");
+ DPRINTK("hardreset, controller off-lined & on-lined\n");
VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
@@ -806,7 +789,7 @@ try_offline_again:
"No Device OR PHYRDY change,Hstatus = 0x%x\n",
ioread32(hcr_base + HSTATUS));
*class = ATA_DEV_NONE;
- goto out;
+ return 0;
}
/*
@@ -819,11 +802,44 @@ try_offline_again:
if ((temp & 0xFF) != 0x18) {
ata_port_printk(ap, KERN_WARNING, "No Signature Update\n");
*class = ATA_DEV_NONE;
- goto out;
+ goto do_followup_srst;
} else {
ata_port_printk(ap, KERN_INFO,
"Signature Update detected @ %d msecs\n",
jiffies_to_msecs(jiffies - start_jiffies));
+ *class = sata_fsl_dev_classify(ap);
+ return 0;
+ }
+
+do_followup_srst:
+ /*
+ * request libATA to perform follow-up softreset
+ */
+ return -EAGAIN;
+
+err:
+ return -EIO;
+}
+
+static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
+{
+ struct ata_port *ap = link->ap;
+ struct sata_fsl_port_priv *pp = ap->private_data;
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ int pmp = sata_srst_pmp(link);
+ u32 temp;
+ struct ata_taskfile tf;
+ u8 *cfis;
+ u32 Serror;
+
+ DPRINTK("in xx_softreset\n");
+
+ if (ata_link_offline(link)) {
+ DPRINTK("PHY reports no device\n");
+ *class = ATA_DEV_NONE;
+ return 0;
}
/*
@@ -834,7 +850,6 @@ try_offline_again:
* reached here, we can send a command to the target device
*/
-issue_srst:
DPRINTK("Sending SRST/device reset\n");
ata_tf_init(link->device, &tf);
@@ -860,6 +875,8 @@ issue_srst:
ioread32(CA + hcr_base), ioread32(CC + hcr_base));
iowrite32(0xFFFF, CC + hcr_base);
+ if (pmp != SATA_PMP_CTRL_PORT)
+ iowrite32(pmp, CQPMP + hcr_base);
iowrite32(1, CQ + hcr_base);
temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
@@ -926,7 +943,6 @@ issue_srst:
VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE));
}
-out:
return 0;
err:
@@ -988,18 +1004,6 @@ static void sata_fsl_error_intr(struct ata_port *ap)
ehi->err_mask |= AC_ERR_ATA_BUS;
ehi->action |= ATA_EH_SOFTRESET;
- /*
- * Ignore serror in case of fatal errors as we always want
- * to do a soft-reset of the FSL SATA controller. Analyzing
- * serror may cause libata to schedule a hard-reset action,
- * and hard-reset currently does not do controller
- * offline/online, causing command timeouts and leads to an
- * un-recoverable state, hence make libATA ignore
- * autopsy in case of fatal errors.
- */
-
- ehi->flags |= ATA_EHI_NO_AUTOPSY;
-
freeze = 1;
}
@@ -1267,8 +1271,8 @@ static struct ata_port_operations sata_fsl_ops = {
.freeze = sata_fsl_freeze,
.thaw = sata_fsl_thaw,
- .prereset = sata_fsl_prereset,
.softreset = sata_fsl_softreset,
+ .hardreset = sata_fsl_hardreset,
.pmp_softreset = sata_fsl_softreset,
.error_handler = sata_fsl_error_handler,
.post_internal_cmd = sata_fsl_post_internal_cmd,
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 17f9ff9067a2..6f5093b7c8c5 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1382,6 +1382,25 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
*/
if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH)
return ATA_DEFER_PORT;
+
+ /* PIO commands need exclusive link: no other commands [DMA or PIO]
+ * can run concurrently.
+ * set excl_link when we want to send a PIO command in DMA mode
+ * or a non-NCQ command in NCQ mode.
+ * When we receive a command from that link, and there are no
+ * outstanding commands, mark a flag to clear excl_link and let
+ * the command go through.
+ */
+ if (unlikely(ap->excl_link)) {
+ if (link == ap->excl_link) {
+ if (ap->nr_active_links)
+ return ATA_DEFER_PORT;
+ qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
+ return 0;
+ } else
+ return ATA_DEFER_PORT;
+ }
+
/*
* If the port is completely idle, then allow the new qc.
*/
@@ -1395,8 +1414,14 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
* doesn't allow it.
*/
if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
- (pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol))
- return 0;
+ (pp->pp_flags & MV_PP_FLAG_NCQ_EN)) {
+ if (ata_is_ncq(qc->tf.protocol))
+ return 0;
+ else {
+ ap->excl_link = link;
+ return ATA_DEFER_PORT;
+ }
+ }
return ATA_DEFER_PORT;
}
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 86a40582999c..1eb4e020eb5c 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1594,9 +1594,21 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class,
!ata_dev_enabled(link->device))
sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
NULL, NULL);
- else if (!(ehc->i.flags & ATA_EHI_QUIET))
- ata_link_printk(link, KERN_INFO,
- "nv: skipping hardreset on occupied port\n");
+ else {
+ const unsigned long *timing = sata_ehc_deb_timing(ehc);
+ int rc;
+
+ if (!(ehc->i.flags & ATA_EHI_QUIET))
+ ata_link_printk(link, KERN_INFO, "nv: skipping "
+ "hardreset on occupied port\n");
+
+ /* make sure the link is online */
+ rc = sata_link_resume(link, timing, deadline);
+ /* whine about phy resume failure but proceed */
+ if (rc && rc != -EOPNOTSUPP)
+ ata_link_printk(link, KERN_WARNING, "failed to resume "
+ "link (errno=%d)\n", rc);
+ }
/* device signature acquisition is unreliable */
return -EAGAIN;
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index bdd43c7f432e..02efd9a83d26 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -93,7 +93,6 @@ static const struct pci_device_id svia_pci_tbl[] = {
{ PCI_VDEVICE(VIA, 0x7372), vt6420 },
{ PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */
{ PCI_VDEVICE(VIA, 0x9000), vt8251 },
- { PCI_VDEVICE(VIA, 0x9040), vt8251 },
{ } /* terminate list */
};
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 973bf2ad4e0d..63c143e54a57 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -689,15 +689,19 @@ int bus_add_driver(struct device_driver *drv)
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
__func__, drv->name);
}
- error = add_bind_files(drv);
- if (error) {
- /* Ditto */
- printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
- __func__, drv->name);
+
+ if (!drv->suppress_bind_attrs) {
+ error = add_bind_files(drv);
+ if (error) {
+ /* Ditto */
+ printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
+ __func__, drv->name);
+ }
}
kobject_uevent(&priv->kobj, KOBJ_ADD);
return 0;
+
out_unregister:
kfree(drv->p);
drv->p = NULL;
@@ -720,7 +724,8 @@ void bus_remove_driver(struct device_driver *drv)
if (!drv->bus)
return;
- remove_bind_files(drv);
+ if (!drv->suppress_bind_attrs)
+ remove_bind_files(drv);
driver_remove_attrs(drv->bus, drv);
driver_remove_file(drv, &driver_attr_uevent);
klist_remove(&drv->p->knode_bus);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index ed2ebd3c287d..f367885a7646 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -236,7 +236,7 @@ int driver_register(struct device_driver *drv)
put_driver(other);
printk(KERN_ERR "Error: Driver '%s' is already registered, "
"aborting...\n", drv->name);
- return -EEXIST;
+ return -EBUSY;
}
ret = bus_add_driver(drv);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index ed156a13aa40..4fa954b07ac4 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -521,11 +521,15 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
{
int retval, code;
+ /* make sure driver won't have bind/unbind attributes */
+ drv->driver.suppress_bind_attrs = true;
+
/* temporary section violation during probe() */
drv->probe = probe;
retval = code = platform_driver_register(drv);
- /* Fixup that section violation, being paranoid about code scanning
+ /*
+ * Fixup that section violation, being paranoid about code scanning
* the list of drivers in order to probe new devices. Check to see
* if the probe was successful, and make sure any forced probes of
* new devices fail.
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index e0dc4071e088..8aa2443182d5 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -511,6 +511,7 @@ static void dpm_complete(pm_message_t state)
INIT_LIST_HEAD(&list);
mutex_lock(&dpm_list_mtx);
+ transition_started = false;
while (!list_empty(&dpm_list)) {
struct device *dev = to_device(dpm_list.prev);
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 38556f6cc22d..846d89e3d122 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -51,8 +51,6 @@ static int __pm_runtime_idle(struct device *dev)
{
int retval = 0;
- dev_dbg(dev, "__pm_runtime_idle()!\n");
-
if (dev->power.runtime_error)
retval = -EINVAL;
else if (dev->power.idle_notification)
@@ -93,8 +91,6 @@ static int __pm_runtime_idle(struct device *dev)
wake_up_all(&dev->power.wait_queue);
out:
- dev_dbg(dev, "__pm_runtime_idle() returns %d!\n", retval);
-
return retval;
}
@@ -332,11 +328,11 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
* necessary.
*/
parent = dev->parent;
- spin_unlock_irq(&dev->power.lock);
+ spin_unlock(&dev->power.lock);
pm_runtime_get_noresume(parent);
- spin_lock_irq(&parent->power.lock);
+ spin_lock(&parent->power.lock);
/*
* We can resume if the parent's run-time PM is disabled or it
* is set to ignore children.
@@ -347,9 +343,9 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
if (parent->power.runtime_status != RPM_ACTIVE)
retval = -EBUSY;
}
- spin_unlock_irq(&parent->power.lock);
+ spin_unlock(&parent->power.lock);
- spin_lock_irq(&dev->power.lock);
+ spin_lock(&dev->power.lock);
if (retval)
goto out;
goto repeat;
@@ -781,7 +777,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
}
if (parent) {
- spin_lock_irq(&parent->power.lock);
+ spin_lock(&parent->power.lock);
/*
* It is invalid to put an active child under a parent that is
@@ -797,7 +793,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
atomic_inc(&parent->power.child_count);
}
- spin_unlock_irq(&parent->power.lock);
+ spin_unlock(&parent->power.lock);
if (error)
goto out;
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 965ece2c7e4d..13bb69d2abb3 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -735,6 +735,21 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
part_stat_unlock();
}
+/*
+ * Ensure we don't create aliases in VI caches
+ */
+static inline void
+killalias(struct bio *bio)
+{
+ struct bio_vec *bv;
+ int i;
+
+ if (bio_data_dir(bio) == READ)
+ __bio_for_each_segment(bv, bio, i, 0) {
+ flush_dcache_page(bv->bv_page);
+ }
+}
+
void
aoecmd_ata_rsp(struct sk_buff *skb)
{
@@ -853,8 +868,12 @@ aoecmd_ata_rsp(struct sk_buff *skb)
if (buf && --buf->nframesout == 0 && buf->resid == 0) {
diskstats(d->gd, buf->bio, jiffies - buf->stime, buf->sector);
- n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
- bio_endio(buf->bio, n);
+ if (buf->flags & BUFFL_FAIL)
+ bio_endio(buf->bio, -EIO);
+ else {
+ killalias(buf->bio);
+ bio_endio(buf->bio, 0);
+ }
mempool_free(buf, d->bufpool);
}
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 6399e5090df4..92b126394fa1 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -482,7 +482,7 @@ static ssize_t host_store_rescan(struct device *dev,
return count;
}
-DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
+static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
static ssize_t dev_show_unique_id(struct device *dev,
struct device_attribute *attr,
@@ -512,7 +512,7 @@ static ssize_t dev_show_unique_id(struct device *dev,
sn[8], sn[9], sn[10], sn[11],
sn[12], sn[13], sn[14], sn[15]);
}
-DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL);
+static DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL);
static ssize_t dev_show_vendor(struct device *dev,
struct device_attribute *attr,
@@ -536,7 +536,7 @@ static ssize_t dev_show_vendor(struct device *dev,
else
return snprintf(buf, sizeof(vendor) + 1, "%s\n", drv->vendor);
}
-DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL);
+static DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL);
static ssize_t dev_show_model(struct device *dev,
struct device_attribute *attr,
@@ -560,7 +560,7 @@ static ssize_t dev_show_model(struct device *dev,
else
return snprintf(buf, sizeof(model) + 1, "%s\n", drv->model);
}
-DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
+static DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
static ssize_t dev_show_rev(struct device *dev,
struct device_attribute *attr,
@@ -584,7 +584,7 @@ static ssize_t dev_show_rev(struct device *dev,
else
return snprintf(buf, sizeof(rev) + 1, "%s\n", drv->rev);
}
-DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
+static DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
static ssize_t cciss_show_lunid(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -609,7 +609,7 @@ static ssize_t cciss_show_lunid(struct device *dev,
lunid[0], lunid[1], lunid[2], lunid[3],
lunid[4], lunid[5], lunid[6], lunid[7]);
}
-DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL);
+static DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL);
static ssize_t cciss_show_raid_level(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -632,7 +632,7 @@ static ssize_t cciss_show_raid_level(struct device *dev,
return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n",
raid_label[raid]);
}
-DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL);
+static DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL);
static ssize_t cciss_show_usage_count(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -651,7 +651,7 @@ static ssize_t cciss_show_usage_count(struct device *dev,
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
return snprintf(buf, 20, "%d\n", count);
}
-DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
+static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
static struct attribute *cciss_host_attrs[] = {
&dev_attr_rescan.attr,
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index edda9ea7c626..bd112c8c7bcd 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -949,7 +949,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
lo->lo_state = Lo_unbound;
/* This is safe: open() is still holding a reference. */
module_put(THIS_MODULE);
- if (max_part > 0)
+ if (max_part > 0 && bdev)
ioctl_by_bdev(bdev, BLKRRPART, 0);
mutex_unlock(&lo->lo_ctl_mutex);
/*
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 43f19389647a..51042f0ba7e1 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -3,7 +3,6 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/virtio.h>
-#include <linux/virtio_ids.h>
#include <linux/virtio_blk.h>
#include <linux/scatterlist.h>
@@ -183,34 +182,6 @@ static void do_virtblk_request(struct request_queue *q)
vblk->vq->vq_ops->kick(vblk->vq);
}
-/* return ATA identify data
- */
-static int virtblk_identify(struct gendisk *disk, void *argp)
-{
- struct virtio_blk *vblk = disk->private_data;
- void *opaque;
- int err = -ENOMEM;
-
- opaque = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
- if (!opaque)
- goto out;
-
- err = virtio_config_buf(vblk->vdev, VIRTIO_BLK_F_IDENTIFY,
- offsetof(struct virtio_blk_config, identify), opaque,
- VIRTIO_BLK_ID_BYTES);
-
- if (err)
- goto out_kfree;
-
- if (copy_to_user(argp, opaque, VIRTIO_BLK_ID_BYTES))
- err = -EFAULT;
-
-out_kfree:
- kfree(opaque);
-out:
- return err;
-}
-
static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
{
req->cmd_type = REQ_TYPE_LINUX_BLOCK;
@@ -222,10 +193,6 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
{
struct gendisk *disk = bdev->bd_disk;
struct virtio_blk *vblk = disk->private_data;
- void __user *argp = (void __user *)data;
-
- if (cmd == HDIO_GET_IDENTITY)
- return virtblk_identify(disk, argp);
/*
* Only allow the generic SCSI ioctls if the host can support it.
@@ -233,7 +200,8 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
return -ENOTTY;
- return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
+ return scsi_cmd_ioctl(disk->queue, disk, mode, cmd,
+ (void __user *)data);
}
/* We provide getgeo only to please some old bootloader/partitioning tools */
@@ -332,7 +300,6 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
}
vblk->disk->queue->queuedata = vblk;
- queue_flag_set_unlocked(QUEUE_FLAG_VIRT, vblk->disk->queue);
if (index < 26) {
sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
@@ -445,7 +412,7 @@ static struct virtio_device_id id_table[] = {
static unsigned int features[] = {
VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
- VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH
+ VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_FLUSH
};
/*
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index b0e569ba730d..2acdc605cb4b 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -867,11 +867,9 @@ static int bluecard_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = bluecard_interrupt;
- link->irq.Instance = info;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -905,22 +903,16 @@ static int bluecard_config(struct pcmcia_device *link)
break;
}
- if (i != 0) {
- cs_error(link, RequestIO, i);
+ if (i != 0)
goto failed;
- }
i = pcmcia_request_irq(link, &link->irq);
- if (i != 0) {
- cs_error(link, RequestIRQ, i);
+ if (i != 0)
link->irq.AssignedIRQ = 0;
- }
i = pcmcia_request_configuration(link, &link->conf);
- if (i != 0) {
- cs_error(link, RequestConfiguration, i);
+ if (i != 0)
goto failed;
- }
if (bluecard_open(info) != 0)
goto failed;
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index d58e22b9f06a..d814a2755ccb 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -659,11 +659,9 @@ static int bt3c_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = bt3c_interrupt;
- link->irq.Instance = info;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -740,21 +738,16 @@ static int bt3c_config(struct pcmcia_device *link)
goto found_port;
BT_ERR("No usable port range found");
- cs_error(link, RequestIO, -ENODEV);
goto failed;
found_port:
i = pcmcia_request_irq(link, &link->irq);
- if (i != 0) {
- cs_error(link, RequestIRQ, i);
+ if (i != 0)
link->irq.AssignedIRQ = 0;
- }
i = pcmcia_request_configuration(link, &link->conf);
- if (i != 0) {
- cs_error(link, RequestConfiguration, i);
+ if (i != 0)
goto failed;
- }
if (bt3c_open(info) != 0)
goto failed;
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index efd689a062eb..d339464dc15e 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -588,11 +588,9 @@ static int btuart_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = btuart_interrupt;
- link->irq.Instance = info;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -669,21 +667,16 @@ static int btuart_config(struct pcmcia_device *link)
goto found_port;
BT_ERR("No usable port range found");
- cs_error(link, RequestIO, -ENODEV);
goto failed;
found_port:
i = pcmcia_request_irq(link, &link->irq);
- if (i != 0) {
- cs_error(link, RequestIRQ, i);
+ if (i != 0)
link->irq.AssignedIRQ = 0;
- }
i = pcmcia_request_configuration(link, &link->conf);
- if (i != 0) {
- cs_error(link, RequestConfiguration, i);
+ if (i != 0)
goto failed;
- }
if (btuart_open(info) != 0)
goto failed;
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 7ba91aa3fe8b..44bc8bbabf54 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -591,6 +591,7 @@ static int btusb_close(struct hci_dev *hdev)
return 0;
cancel_work_sync(&data->work);
+ cancel_work_sync(&data->waker);
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
@@ -599,11 +600,13 @@ static int btusb_close(struct hci_dev *hdev)
btusb_stop_traffic(data);
err = usb_autopm_get_interface(data->intf);
if (err < 0)
- return 0;
+ goto failed;
data->intf->needs_remote_wakeup = 0;
usb_autopm_put_interface(data->intf);
+failed:
+ usb_scuttle_anchored_urbs(&data->deferred);
return 0;
}
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index b881a9cd8741..4f02a6f3c980 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -573,11 +573,9 @@ static int dtl1_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = dtl1_interrupt;
- link->irq.Instance = info;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -622,16 +620,12 @@ static int dtl1_config(struct pcmcia_device *link)
goto failed;
i = pcmcia_request_irq(link, &link->irq);
- if (i != 0) {
- cs_error(link, RequestIRQ, i);
+ if (i != 0)
link->irq.AssignedIRQ = 0;
- }
i = pcmcia_request_configuration(link, &link->conf);
- if (i != 0) {
- cs_error(link, RequestConfiguration, i);
+ if (i != 0)
goto failed;
- }
if (dtl1_open(info) != 0)
goto failed;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 08a6f50ae791..6aad99ec4e0f 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -323,7 +323,7 @@ config SPECIALIX
config SX
tristate "Specialix SX (and SI) card support"
- depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
+ depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN
help
This is a driver for the SX and SI multiport serial cards.
Please read the file <file:Documentation/serial/sx.txt> for details.
@@ -334,7 +334,7 @@ config SX
config RIO
tristate "Specialix RIO system support"
- depends on SERIAL_NONSTANDARD
+ depends on SERIAL_NONSTANDARD && BROKEN
help
This is a driver for the Specialix RIO, a smart serial card which
drives an outboard box that can support up to 128 ports. Product
@@ -395,7 +395,7 @@ config NOZOMI
config A2232
tristate "Commodore A2232 serial support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP
+ depends on EXPERIMENTAL && ZORRO && BROKEN
---help---
This option supports the 2232 7-port serial card shipped with the
Amiga 2000 and other Zorro-bus machines, dating from 1989. At
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index ccb1fa89de29..2fb3a480f6b0 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -56,9 +56,8 @@ config AGP_AMD
X on AMD Irongate, 761, and 762 chipsets.
config AGP_AMD64
- tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU
+ tristate "AMD Opteron/Athlon64 on-CPU GART support"
depends on AGP && X86
- default y if GART_IOMMU
help
This option gives you AGP support for the GLX component of
X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs.
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 4068467ce7b9..3cb56a049e24 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -62,6 +62,7 @@
#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042
#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044
#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062
+#define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB 0x006a
#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046
/* cover 915 and 945 variants */
@@ -96,7 +97,8 @@
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB)
extern int agp_memory_reserved;
@@ -1161,12 +1163,6 @@ static int intel_i915_configure(void)
intel_i9xx_setup_flush();
-#ifdef USE_PCI_DMA_API
- if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
- dev_err(&intel_private.pcidev->dev,
- "set gfx device dma mask 36bit failed!\n");
-#endif
-
return 0;
}
@@ -1364,6 +1360,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
+ case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB:
*gtt_offset = *gtt_size = MB(2);
break;
default:
@@ -2365,6 +2362,8 @@ static const struct intel_driver_description {
"IGDNG/M", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
"IGDNG/MA", NULL, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
+ "IGDNG/MC2", NULL, &intel_i965_driver },
{ 0, 0, 0, NULL, NULL, NULL }
};
@@ -2456,6 +2455,11 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
&bridge->mode);
}
+ if (bridge->driver->mask_memory == intel_i965_mask_memory)
+ if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
+ dev_err(&intel_private.pcidev->dev,
+ "set gfx device dma mask 36bit failed!\n");
+
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
@@ -2561,6 +2565,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
+ ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB),
{ }
};
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
index eba999f8598d..a6ee32b599a8 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -55,7 +55,7 @@ static inline void notify_daemon(void)
notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
}
-static int write_console(uint32_t vtermno, const char *data, int len)
+static int __write_console(const char *data, int len)
{
struct xencons_interface *intf = xencons_interface();
XENCONS_RING_IDX cons, prod;
@@ -76,6 +76,29 @@ static int write_console(uint32_t vtermno, const char *data, int len)
return sent;
}
+static int write_console(uint32_t vtermno, const char *data, int len)
+{
+ int ret = len;
+
+ /*
+ * Make sure the whole buffer is emitted, polling if
+ * necessary. We don't ever want to rely on the hvc daemon
+ * because the most interesting console output is when the
+ * kernel is crippled.
+ */
+ while (len) {
+ int sent = __write_console(data, len);
+
+ data += sent;
+ len -= sent;
+
+ if (unlikely(len))
+ HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
+ }
+
+ return ret;
+}
+
static int read_console(uint32_t vtermno, char *buf, int len)
{
struct xencons_interface *intf = xencons_interface();
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 962968f05b94..915157fcff98 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -21,7 +21,6 @@
#include <linux/scatterlist.h>
#include <linux/spinlock.h>
#include <linux/virtio.h>
-#include <linux/virtio_ids.h>
#include <linux/virtio_rng.h>
/* The host will fill any buffer we give it with sweet, sweet randomness. We
@@ -117,7 +116,7 @@ static int virtrng_probe(struct virtio_device *vdev)
return 0;
}
-static void virtrng_remove(struct virtio_device *vdev)
+static void __devexit virtrng_remove(struct virtio_device *vdev)
{
vdev->config->reset(vdev);
hwrng_unregister(&virtio_hwrng);
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 737be953cc58..950837cf9e9c 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
if (keycode >= NR_KEYS)
if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
- keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
+ keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
else
return;
else
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index c250a31efa53..2db4c0a29b05 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -23,8 +23,6 @@
* All rights reserved. Licensed under dual BSD/GPL license.
*/
-/* #define PCMCIA_DEBUG 6 */
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -47,18 +45,17 @@
/* #define ATR_CSUM */
-#ifdef PCMCIA_DEBUG
-#define reader_to_dev(x) (&handle_to_dev(x->p_dev))
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0600);
-#define DEBUGP(n, rdr, x, args...) do { \
- if (pc_debug >= (n)) \
- dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
- __func__ , ## args); \
+#define reader_to_dev(x) (&x->p_dev->dev)
+
+/* n (debug level) is ignored */
+/* additional debug output may be enabled by re-compiling with
+ * CM4000_DEBUG set */
+/* #define CM4000_DEBUG */
+#define DEBUGP(n, rdr, x, args...) do { \
+ dev_dbg(reader_to_dev(rdr), "%s:" x, \
+ __func__ , ## args); \
} while (0)
-#else
-#define DEBUGP(n, rdr, x, args...)
-#endif
+
static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
#define T_1SEC (HZ)
@@ -174,14 +171,13 @@ static unsigned char fi_di_table[10][14] = {
/* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
};
-#ifndef PCMCIA_DEBUG
+#ifndef CM4000_DEBUG
#define xoutb outb
#define xinb inb
#else
static inline void xoutb(unsigned char val, unsigned short port)
{
- if (pc_debug >= 7)
- printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+ pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
outb(val, port);
}
static inline unsigned char xinb(unsigned short port)
@@ -189,8 +185,7 @@ static inline unsigned char xinb(unsigned short port)
unsigned char val;
val = inb(port);
- if (pc_debug >= 7)
- printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+ pr_debug("%.2x=inb(%.4x)\n", val, port);
return val;
}
@@ -514,12 +509,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
for (i = 0; i < 4; i++) {
xoutb(i, REG_BUF_ADDR(iobase));
xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */
-#ifdef PCMCIA_DEBUG
- if (pc_debug >= 5)
- printk("0x%.2x ", dev->pts[i]);
+#ifdef CM4000_DEBUG
+ pr_debug("0x%.2x ", dev->pts[i]);
}
- if (pc_debug >= 5)
- printk("\n");
+ pr_debug("\n");
#else
}
#endif
@@ -579,14 +572,13 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
pts_reply[i] = inb(REG_BUF_DATA(iobase));
}
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
DEBUGP(2, dev, "PTSreply: ");
for (i = 0; i < num_bytes_read; i++) {
- if (pc_debug >= 5)
- printk("0x%.2x ", pts_reply[i]);
+ pr_debug("0x%.2x ", pts_reply[i]);
}
- printk("\n");
-#endif /* PCMCIA_DEBUG */
+ pr_debug("\n");
+#endif /* CM4000_DEBUG */
DEBUGP(5, dev, "Clear Tactive in Flags1\n");
xoutb(0x20, REG_FLAGS1(iobase));
@@ -655,7 +647,7 @@ static void terminate_monitor(struct cm4000_dev *dev)
DEBUGP(5, dev, "Delete timer\n");
del_timer_sync(&dev->timer);
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
dev->monitor_running = 0;
#endif
@@ -898,7 +890,7 @@ static void monitor_card(unsigned long p)
DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
"be zero) failed\n", dev->atr_csum);
}
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
DEBUGP(4, dev, "ATR length error\n");
} else {
@@ -1415,7 +1407,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
int size;
int rc;
void __user *argp = (void __user *)arg;
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
char *ioctl_names[CM_IOC_MAXNR + 1] = {
[_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
[_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
@@ -1423,9 +1415,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
[_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
[_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
};
-#endif
DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
iminor(inode), ioctl_names[_IOC_NR(cmd)]);
+#endif
lock_kernel();
rc = -ENODEV;
@@ -1523,7 +1515,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
case CM_IOCARDOFF:
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
if (dev->flags0 & 0x01) {
DEBUGP(4, dev, " Card inserted\n");
@@ -1625,18 +1617,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
break;
-#ifdef PCMCIA_DEBUG
- case CM_IOSDBGLVL: /* set debug log level */
- {
- int old_pc_debug = 0;
-
- old_pc_debug = pc_debug;
- if (copy_from_user(&pc_debug, argp, sizeof(int)))
- rc = -EFAULT;
- else if (old_pc_debug != pc_debug)
- DEBUGP(0, dev, "Changed debug log level "
- "to %i\n", pc_debug);
- }
+#ifdef CM4000_DEBUG
+ case CM_IOSDBGLVL:
+ rc = -ENOTTY;
break;
#endif
default:
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 4f0723b07974..a6a70e476bea 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -17,8 +17,6 @@
* All rights reserved, Dual BSD/GPL Licensed.
*/
-/* #define PCMCIA_DEBUG 6 */
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -41,18 +39,16 @@
#include "cm4040_cs.h"
-#ifdef PCMCIA_DEBUG
-#define reader_to_dev(x) (&handle_to_dev(x->p_dev))
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0600);
-#define DEBUGP(n, rdr, x, args...) do { \
- if (pc_debug >= (n)) \
- dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
- __func__ , ##args); \
+#define reader_to_dev(x) (&x->p_dev->dev)
+
+/* n (debug level) is ignored */
+/* additional debug output may be enabled by re-compiling with
+ * CM4040_DEBUG set */
+/* #define CM4040_DEBUG */
+#define DEBUGP(n, rdr, x, args...) do { \
+ dev_dbg(reader_to_dev(rdr), "%s:" x, \
+ __func__ , ## args); \
} while (0)
-#else
-#define DEBUGP(n, rdr, x, args...)
-#endif
static char *version =
"OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte";
@@ -90,14 +86,13 @@ struct reader_dev {
static struct pcmcia_device *dev_table[CM_MAX_DEV];
-#ifndef PCMCIA_DEBUG
+#ifndef CM4040_DEBUG
#define xoutb outb
#define xinb inb
#else
static inline void xoutb(unsigned char val, unsigned short port)
{
- if (pc_debug >= 7)
- printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+ pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
outb(val, port);
}
@@ -106,8 +101,7 @@ static inline unsigned char xinb(unsigned short port)
unsigned char val;
val = inb(port);
- if (pc_debug >= 7)
- printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+ pr_debug("%.2x=inb(%.4x)\n", val, port);
return val;
}
#endif
@@ -260,23 +254,22 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
return -EIO;
}
dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN);
-#ifdef PCMCIA_DEBUG
- if (pc_debug >= 6)
- printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+#ifdef CM4040_DEBUG
+ pr_debug("%lu:%2x ", i, dev->r_buf[i]);
}
- printk("\n");
+ pr_debug("\n");
#else
}
#endif
bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]);
- DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read);
+ DEBUGP(6, dev, "BytesToRead=%zu\n", bytes_to_read);
min_bytes_to_read = min(count, bytes_to_read + 5);
min_bytes_to_read = min_t(size_t, min_bytes_to_read, READ_WRITE_BUFFER_SIZE);
- DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read);
+ DEBUGP(6, dev, "Min=%zu\n", min_bytes_to_read);
for (i = 0; i < (min_bytes_to_read-5); i++) {
rc = wait_for_bulk_in_ready(dev);
@@ -288,11 +281,10 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
return -EIO;
}
dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN);
-#ifdef PCMCIA_DEBUG
- if (pc_debug >= 6)
- printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+#ifdef CM4040_DEBUG
+ pr_debug("%lu:%2x ", i, dev->r_buf[i]);
}
- printk("\n");
+ pr_debug("\n");
#else
}
#endif
@@ -547,7 +539,7 @@ static int cm4040_config_check(struct pcmcia_device *p_dev,
p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
rc = pcmcia_request_io(p_dev, &p_dev->io);
- dev_printk(KERN_INFO, &handle_to_dev(p_dev),
+ dev_printk(KERN_INFO, &p_dev->dev,
"pcmcia_request_io returned 0x%x\n", rc);
return rc;
}
@@ -569,7 +561,7 @@ static int reader_config(struct pcmcia_device *link, int devno)
fail_rc = pcmcia_request_configuration(link, &link->conf);
if (fail_rc != 0) {
- dev_printk(KERN_INFO, &handle_to_dev(link),
+ dev_printk(KERN_INFO, &link->dev,
"pcmcia_request_configuration failed 0x%x\n",
fail_rc);
goto cs_release;
diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c
index 4c1820cad712..99cffdab1056 100644
--- a/drivers/char/pcmcia/ipwireless/hardware.c
+++ b/drivers/char/pcmcia/ipwireless/hardware.c
@@ -1213,12 +1213,12 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
irqreturn_t ipwireless_interrupt(int irq, void *dev_id)
{
- struct ipw_hardware *hw = dev_id;
+ struct ipw_dev *ipw = dev_id;
- if (hw->hw_version == HW_VERSION_1)
- return ipwireless_handle_v1_interrupt(irq, hw);
+ if (ipw->hardware->hw_version == HW_VERSION_1)
+ return ipwireless_handle_v1_interrupt(irq, ipw->hardware);
else
- return ipwireless_handle_v2_v3_interrupt(irq, hw);
+ return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware);
}
static void flush_packets_to_hw(struct ipw_hardware *hw)
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c
index 5216fce0c62d..dff24dae1485 100644
--- a/drivers/char/pcmcia/ipwireless/main.c
+++ b/drivers/char/pcmcia/ipwireless/main.c
@@ -65,10 +65,7 @@ static void signalled_reboot_work(struct work_struct *work_reboot)
struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
work_reboot);
struct pcmcia_device *link = ipw->link;
- int ret = pcmcia_reset_card(link->socket);
-
- if (ret != 0)
- cs_error(link, ResetCard, ret);
+ pcmcia_reset_card(link->socket);
}
static void signalled_reboot_callback(void *callback_data)
@@ -79,208 +76,127 @@ static void signalled_reboot_callback(void *callback_data)
schedule_work(&ipw->work_reboot);
}
-static int config_ipwireless(struct ipw_dev *ipw)
+static int ipwireless_probe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
{
- struct pcmcia_device *link = ipw->link;
- int ret;
- tuple_t tuple;
- unsigned short buf[64];
- cisparse_t parse;
- unsigned short cor_value;
+ struct ipw_dev *ipw = priv_data;
+ struct resource *io_resource;
memreq_t memreq_attr_memory;
memreq_t memreq_common_memory;
+ int ret;
- ipw->is_v2_card = 0;
-
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- tuple.DesiredTuple = RETURN_FIRST_TUPLE;
-
- ret = pcmcia_get_first_tuple(link, &tuple);
-
- while (ret == 0) {
- ret = pcmcia_get_tuple_data(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
- ret = pcmcia_get_next_tuple(link, &tuple);
- }
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
- ret = pcmcia_get_first_tuple(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetFirstTuple, ret);
- goto exit0;
- }
-
- ret = pcmcia_get_tuple_data(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
-
- ret = pcmcia_parse_tuple(&tuple, &parse);
-
- if (ret != 0) {
- cs_error(link, ParseTuple, ret);
- goto exit0;
- }
-
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
- link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
- link->io.IOAddrLines = 16;
-
- link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ p_dev->io.BasePort1 = cfg->io.win[0].base;
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+ p_dev->io.IOAddrLines = 16;
/* 0x40 causes it to generate level mode interrupts. */
/* 0x04 enables IREQ pin. */
- cor_value = parse.cftable_entry.index | 0x44;
- link->conf.ConfigIndex = cor_value;
+ p_dev->conf.ConfigIndex = cfg->index | 0x44;
+ ret = pcmcia_request_io(p_dev, &p_dev->io);
+ if (ret)
+ return ret;
- /* IRQ and I/O settings */
- tuple.DesiredTuple = CISTPL_CONFIG;
+ io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1,
+ IPWIRELESS_PCCARD_NAME);
- ret = pcmcia_get_first_tuple(link, &tuple);
+ if (cfg->mem.nwin == 0)
+ return 0;
- if (ret != 0) {
- cs_error(link, GetFirstTuple, ret);
- goto exit0;
- }
+ ipw->request_common_memory.Attributes =
+ WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
+ ipw->request_common_memory.Base = cfg->mem.win[0].host_addr;
+ ipw->request_common_memory.Size = cfg->mem.win[0].len;
+ if (ipw->request_common_memory.Size < 0x1000)
+ ipw->request_common_memory.Size = 0x1000;
+ ipw->request_common_memory.AccessSpeed = 0;
- ret = pcmcia_get_tuple_data(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
+ ret = pcmcia_request_window(p_dev, &ipw->request_common_memory,
+ &ipw->handle_common_memory);
- ret = pcmcia_parse_tuple(&tuple, &parse);
+ if (ret != 0)
+ goto exit1;
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
- link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
- link->conf.IntType = INT_MEMORY_AND_IO;
+ memreq_common_memory.CardOffset = cfg->mem.win[0].card_addr;
+ memreq_common_memory.Page = 0;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- link->irq.Handler = ipwireless_interrupt;
- link->irq.Instance = ipw->hardware;
+ ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory,
+ &memreq_common_memory);
- ret = pcmcia_request_io(link, &link->io);
+ if (ret != 0)
+ goto exit2;
- if (ret != 0) {
- cs_error(link, RequestIO, ret);
- goto exit0;
- }
+ ipw->is_v2_card = cfg->mem.win[0].len == 0x100;
- request_region(link->io.BasePort1, link->io.NumPorts1,
+ ipw->common_memory = ioremap(ipw->request_common_memory.Base,
+ ipw->request_common_memory.Size);
+ request_mem_region(ipw->request_common_memory.Base,
+ ipw->request_common_memory.Size,
IPWIRELESS_PCCARD_NAME);
- /* memory settings */
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
- ret = pcmcia_get_first_tuple(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetFirstTuple, ret);
- goto exit1;
- }
-
- ret = pcmcia_get_tuple_data(link, &tuple);
+ ipw->request_attr_memory.Attributes =
+ WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
+ ipw->request_attr_memory.Base = 0;
+ ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */
+ ipw->request_attr_memory.AccessSpeed = 0;
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit1;
- }
-
- ret = pcmcia_parse_tuple(&tuple, &parse);
-
- if (ret != 0) {
- cs_error(link, ParseTuple, ret);
- goto exit1;
- }
+ ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory,
+ &ipw->handle_attr_memory);
- if (parse.cftable_entry.mem.nwin > 0) {
- ipw->request_common_memory.Attributes =
- WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
- ipw->request_common_memory.Base =
- parse.cftable_entry.mem.win[0].host_addr;
- ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
- if (ipw->request_common_memory.Size < 0x1000)
- ipw->request_common_memory.Size = 0x1000;
- ipw->request_common_memory.AccessSpeed = 0;
-
- ret = pcmcia_request_window(&link, &ipw->request_common_memory,
- &ipw->handle_common_memory);
+ if (ret != 0)
+ goto exit2;
- if (ret != 0) {
- cs_error(link, RequestWindow, ret);
- goto exit1;
- }
+ memreq_attr_memory.CardOffset = 0;
+ memreq_attr_memory.Page = 0;
- memreq_common_memory.CardOffset =
- parse.cftable_entry.mem.win[0].card_addr;
- memreq_common_memory.Page = 0;
+ ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory,
+ &memreq_attr_memory);
- ret = pcmcia_map_mem_page(ipw->handle_common_memory,
- &memreq_common_memory);
+ if (ret != 0)
+ goto exit3;
- if (ret != 0) {
- cs_error(link, MapMemPage, ret);
- goto exit1;
- }
+ ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
+ ipw->request_attr_memory.Size);
+ request_mem_region(ipw->request_attr_memory.Base,
+ ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME);
- ipw->is_v2_card =
- parse.cftable_entry.mem.win[0].len == 0x100;
+ return 0;
- ipw->common_memory = ioremap(ipw->request_common_memory.Base,
+exit3:
+ pcmcia_release_window(p_dev, ipw->handle_attr_memory);
+exit2:
+ if (ipw->common_memory) {
+ release_mem_region(ipw->request_common_memory.Base,
ipw->request_common_memory.Size);
- request_mem_region(ipw->request_common_memory.Base,
- ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME);
-
- ipw->request_attr_memory.Attributes =
- WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
- ipw->request_attr_memory.Base = 0;
- ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */
- ipw->request_attr_memory.AccessSpeed = 0;
-
- ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
- &ipw->handle_attr_memory);
+ iounmap(ipw->common_memory);
+ pcmcia_release_window(p_dev, ipw->handle_common_memory);
+ } else
+ pcmcia_release_window(p_dev, ipw->handle_common_memory);
+exit1:
+ release_resource(io_resource);
+ pcmcia_disable_device(p_dev);
+ return -1;
+}
- if (ret != 0) {
- cs_error(link, RequestWindow, ret);
- goto exit2;
- }
+static int config_ipwireless(struct ipw_dev *ipw)
+{
+ struct pcmcia_device *link = ipw->link;
+ int ret = 0;
- memreq_attr_memory.CardOffset = 0;
- memreq_attr_memory.Page = 0;
+ ipw->is_v2_card = 0;
- ret = pcmcia_map_mem_page(ipw->handle_attr_memory,
- &memreq_attr_memory);
+ ret = pcmcia_loop_config(link, ipwireless_probe, ipw);
+ if (ret != 0)
+ return ret;
- if (ret != 0) {
- cs_error(link, MapMemPage, ret);
- goto exit2;
- }
+ link->conf.Attributes = CONF_ENABLE_IRQ;
+ link->conf.IntType = INT_MEMORY_AND_IO;
- ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
- ipw->request_attr_memory.Size);
- request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size,
- IPWIRELESS_PCCARD_NAME);
- }
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+ link->irq.Handler = ipwireless_interrupt;
INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
@@ -291,10 +207,8 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_request_irq(link, &link->irq);
- if (ret != 0) {
- cs_error(link, RequestIRQ, ret);
- goto exit3;
- }
+ if (ret != 0)
+ goto exit;
printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
ipw->is_v2_card ? "V2/V3" : "V1");
@@ -316,12 +230,12 @@ static int config_ipwireless(struct ipw_dev *ipw)
ipw->network = ipwireless_network_create(ipw->hardware);
if (!ipw->network)
- goto exit3;
+ goto exit;
ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network,
ipw->nodes);
if (!ipw->tty)
- goto exit3;
+ goto exit;
ipwireless_init_hardware_v2_v3(ipw->hardware);
@@ -331,35 +245,27 @@ static int config_ipwireless(struct ipw_dev *ipw)
*/
ret = pcmcia_request_configuration(link, &link->conf);
- if (ret != 0) {
- cs_error(link, RequestConfiguration, ret);
- goto exit4;
- }
+ if (ret != 0)
+ goto exit;
link->dev_node = &ipw->nodes[0];
return 0;
-exit4:
- pcmcia_disable_device(link);
-exit3:
+exit:
if (ipw->attr_memory) {
release_mem_region(ipw->request_attr_memory.Base,
ipw->request_attr_memory.Size);
iounmap(ipw->attr_memory);
- pcmcia_release_window(ipw->handle_attr_memory);
- pcmcia_disable_device(link);
+ pcmcia_release_window(link, ipw->handle_attr_memory);
}
-exit2:
if (ipw->common_memory) {
release_mem_region(ipw->request_common_memory.Base,
ipw->request_common_memory.Size);
iounmap(ipw->common_memory);
- pcmcia_release_window(ipw->handle_common_memory);
+ pcmcia_release_window(link, ipw->handle_common_memory);
}
-exit1:
pcmcia_disable_device(link);
-exit0:
return -1;
}
@@ -378,9 +284,9 @@ static void release_ipwireless(struct ipw_dev *ipw)
iounmap(ipw->attr_memory);
}
if (ipw->common_memory)
- pcmcia_release_window(ipw->handle_common_memory);
+ pcmcia_release_window(ipw->link, ipw->handle_common_memory);
if (ipw->attr_memory)
- pcmcia_release_window(ipw->handle_attr_memory);
+ pcmcia_release_window(ipw->link, ipw->handle_attr_memory);
/* Break the link with Card Services */
pcmcia_disable_device(ipw->link);
@@ -406,7 +312,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
ipw->link = link;
link->priv = ipw;
- link->irq.Instance = ipw;
/* Link this device into our device list. */
link->dev_node = &ipw->nodes[0];
@@ -421,7 +326,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
ret = config_ipwireless(ipw);
if (ret != 0) {
- cs_error(link, RegisterClient, ret);
ipwireless_detach(link);
return ret;
}
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index caf6e4d19469..c31a0d913d37 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -554,7 +554,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
link->conf.Attributes = 0;
@@ -572,69 +571,51 @@ static int mgslpc_probe(struct pcmcia_device *link)
/* Card has been inserted.
*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->io.nwin > 0) {
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(cfg->io.flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(cfg->io.flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = cfg->io.win[0].base;
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+ return pcmcia_request_io(p_dev, &p_dev->io);
+ }
+ return -ENODEV;
+}
static int mgslpc_config(struct pcmcia_device *link)
{
MGSLPC_INFO *info = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_fn, last_ret;
- u_char buf[64];
- cistpl_cftable_entry_t dflt = { 0 };
- cistpl_cftable_entry_t *cfg;
+ int ret;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_config(0x%p)\n", link);
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- /* get CIS configuration entry */
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-
- cfg = &(parse.cftable_entry);
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
- if (cfg->index == 0)
- goto cs_failed;
-
- link->conf.ConfigIndex = cfg->index;
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
- }
+ ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
+ if (ret != 0)
+ goto failed;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 8;
link->conf.Present = PRESENT_OPTION;
- link->irq.Attributes |= IRQ_HANDLE_PRESENT;
link->irq.Handler = mgslpc_isr;
- link->irq.Instance = info;
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
info->io_base = link->io.BasePort1;
info->irq_level = link->irq.AssignedIRQ;
@@ -654,8 +635,7 @@ static int mgslpc_config(struct pcmcia_device *link)
printk("\n");
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
+failed:
mgslpc_release((u_long)link);
return -ENODEV;
}
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 47c2d2763456..f06bb37defb1 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -31,7 +31,7 @@
enum tpm_const {
TPM_MINOR = 224, /* officially assigned */
- TPM_BUFSIZE = 2048,
+ TPM_BUFSIZE = 4096,
TPM_NUM_DEVICES = 256,
};
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 0b73e4ec1add..2405f17b29dd 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -257,6 +257,10 @@ out:
return size;
}
+static int itpm;
+module_param(itpm, bool, 0444);
+MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)");
+
/*
* If interrupts are used (signaled by an irq set in the vendor structure)
* tpm.c can skip polling for the data to be available as the interrupt is
@@ -293,7 +297,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
&chip->vendor.int_queue);
status = tpm_tis_status(chip);
- if ((status & TPM_STS_DATA_EXPECT) == 0) {
+ if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
rc = -EIO;
goto out_err;
}
@@ -467,6 +471,10 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
"1.2 TPM (device-id 0x%X, rev-id %d)\n",
vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
+ if (itpm)
+ dev_info(dev, "Intel iTPM workaround enabled\n");
+
+
/* Figure out the capabilities */
intfcaps =
ioread32(chip->vendor.iobase +
@@ -629,6 +637,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
{"", 0}, /* User Specified */
{"", 0} /* Terminator */
};
+MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev)
{
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index 3108991c5c8b..66fa4e10d76b 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -402,28 +402,26 @@ static void flush_to_ldisc(struct work_struct *work)
container_of(work, struct tty_struct, buf.work.work);
unsigned long flags;
struct tty_ldisc *disc;
- struct tty_buffer *tbuf, *head;
- char *char_buf;
- unsigned char *flag_buf;
disc = tty_ldisc_ref(tty);
if (disc == NULL) /* !TTY_LDISC */
return;
spin_lock_irqsave(&tty->buf.lock, flags);
- /* So we know a flush is running */
- set_bit(TTY_FLUSHING, &tty->flags);
- head = tty->buf.head;
- if (head != NULL) {
- tty->buf.head = NULL;
- for (;;) {
- int count = head->commit - head->read;
+
+ if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
+ struct tty_buffer *head;
+ while ((head = tty->buf.head) != NULL) {
+ int count;
+ char *char_buf;
+ unsigned char *flag_buf;
+
+ count = head->commit - head->read;
if (!count) {
if (head->next == NULL)
break;
- tbuf = head;
- head = head->next;
- tty_buffer_free(tty, tbuf);
+ tty->buf.head = head->next;
+ tty_buffer_free(tty, head);
continue;
}
/* Ldisc or user is trying to flush the buffers
@@ -445,9 +443,9 @@ static void flush_to_ldisc(struct work_struct *work)
flag_buf, count);
spin_lock_irqsave(&tty->buf.lock, flags);
}
- /* Restore the queue head */
- tty->buf.head = head;
+ clear_bit(TTY_FLUSHING, &tty->flags);
}
+
/* We may have a deferred request to flush the input buffer,
if so pull the chain under the lock and empty the queue */
if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
@@ -455,7 +453,6 @@ static void flush_to_ldisc(struct work_struct *work)
clear_bit(TTY_FLUSHPENDING, &tty->flags);
wake_up(&tty->read_wait);
}
- clear_bit(TTY_FLUSHING, &tty->flags);
spin_unlock_irqrestore(&tty->buf.lock, flags);
tty_ldisc_deref(disc);
@@ -471,7 +468,7 @@ static void flush_to_ldisc(struct work_struct *work)
*/
void tty_flush_to_ldisc(struct tty_struct *tty)
{
- flush_to_ldisc(&tty->buf.work.work);
+ flush_delayed_work(&tty->buf.work);
}
/**
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index a4bbb28f10be..c63f3d33914a 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -219,8 +219,14 @@ int tty_port_block_til_ready(struct tty_port *port,
/* if non-blocking mode is set we can pass directly to open unless
the port has just hung up or is in another error state */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
+ if (tty->flags & (1 << TTY_IO_ERROR)) {
+ port->flags |= ASYNC_NORMAL_ACTIVE;
+ return 0;
+ }
+ if (filp->f_flags & O_NONBLOCK) {
+ /* Indicate we are open */
+ if (tty->termios->c_cflag & CBAUD)
+ tty_port_raise_dtr_rts(port);
port->flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 0d328b59568d..a035ae39a359 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -31,7 +31,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/virtio.h>
-#include <linux/virtio_ids.h>
#include <linux/virtio_console.h>
#include "hvc_console.h"
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 6b36ee56e6fe..6aa10284104a 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -103,8 +103,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
ve->event.event = event;
/* kernel view is consoles 0..n-1, user space view is
console 1..n with 0 meaning current, so we must bias */
- ve->event.old = old + 1;
- ve->event.new = new + 1;
+ ve->event.oldev = old + 1;
+ ve->event.newev = new + 1;
wake = 1;
ve->done = 1;
}
@@ -186,7 +186,7 @@ int vt_waitactive(int n)
vt_event_wait(&vw);
if (vw.done == 0)
return -EINTR;
- } while (vw.event.new != n);
+ } while (vw.event.newev != n);
return 0;
}
@@ -1532,7 +1532,7 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
case PIO_UNIMAP:
case GIO_UNIMAP:
- ret = do_unimap_ioctl(cmd, up, perm, vc);
+ ret = compat_unimap_ioctl(cmd, up, perm, vc);
break;
/*
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 3938c7817095..ff57c40e9b8b 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -41,7 +41,7 @@ static struct cpufreq_driver *cpufreq_driver;
static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
#ifdef CONFIG_HOTPLUG_CPU
/* This one keeps track of the previously set governor of a removed CPU */
-static DEFINE_PER_CPU(struct cpufreq_governor *, cpufreq_cpu_governor);
+static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
#endif
static DEFINE_SPINLOCK(cpufreq_driver_lock);
@@ -774,10 +774,12 @@ int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy,
#ifdef CONFIG_SMP
unsigned long flags;
unsigned int j;
-
#ifdef CONFIG_HOTPLUG_CPU
- if (per_cpu(cpufreq_cpu_governor, cpu)) {
- policy->governor = per_cpu(cpufreq_cpu_governor, cpu);
+ struct cpufreq_governor *gov;
+
+ gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
+ if (gov) {
+ policy->governor = gov;
dprintk("Restoring governor %s for cpu %d\n",
policy->governor->name, cpu);
}
@@ -949,10 +951,13 @@ err_out_kobj_put:
static int cpufreq_add_dev(struct sys_device *sys_dev)
{
unsigned int cpu = sys_dev->id;
- int ret = 0;
+ int ret = 0, found = 0;
struct cpufreq_policy *policy;
unsigned long flags;
unsigned int j;
+#ifdef CONFIG_HOTPLUG_CPU
+ int sibling;
+#endif
if (cpu_is_offline(cpu))
return 0;
@@ -999,7 +1004,19 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
INIT_WORK(&policy->update, handle_update);
/* Set governor before ->init, so that driver could check it */
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+#ifdef CONFIG_HOTPLUG_CPU
+ for_each_online_cpu(sibling) {
+ struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
+ if (cp && cp->governor &&
+ (cpumask_test_cpu(cpu, cp->related_cpus))) {
+ policy->governor = cp->governor;
+ found = 1;
+ break;
+ }
+ }
+#endif
+ if (!found)
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
/* call driver. From then on the cpufreq must be able
* to accept all calls to ->verify and ->setpolicy for this CPU
*/
@@ -1111,7 +1128,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
#ifdef CONFIG_SMP
#ifdef CONFIG_HOTPLUG_CPU
- per_cpu(cpufreq_cpu_governor, cpu) = data->governor;
+ strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
+ CPUFREQ_NAME_LEN);
#endif
/* if we have other CPUs still registered, we need to unlink them,
@@ -1135,7 +1153,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
continue;
dprintk("removing link for cpu %u\n", j);
#ifdef CONFIG_HOTPLUG_CPU
- per_cpu(cpufreq_cpu_governor, j) = data->governor;
+ strncpy(per_cpu(cpufreq_cpu_governor, j),
+ data->governor->name, CPUFREQ_NAME_LEN);
#endif
cpu_sys_dev = get_cpu_sysdev(j);
sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
@@ -1606,9 +1625,22 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor);
void cpufreq_unregister_governor(struct cpufreq_governor *governor)
{
+#ifdef CONFIG_HOTPLUG_CPU
+ int cpu;
+#endif
+
if (!governor)
return;
+#ifdef CONFIG_HOTPLUG_CPU
+ for_each_present_cpu(cpu) {
+ if (cpu_online(cpu))
+ continue;
+ if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
+ strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
+ }
+#endif
+
mutex_lock(&cpufreq_governor_mutex);
list_del(&governor->governor_list);
mutex_unlock(&cpufreq_governor_mutex);
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index bc33ddc9c97c..c7b081b839ff 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -116,9 +116,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
idle_time = cputime64_sub(cur_wall_time, busy_time);
if (wall)
- *wall = cur_wall_time;
+ *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time);
- return idle_time;
+ return (cputime64_t)jiffies_to_usecs(idle_time);;
}
static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 071699de50ee..4b34ade2332b 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -133,9 +133,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
idle_time = cputime64_sub(cur_wall_time, busy_time);
if (wall)
- *wall = cur_wall_time;
+ *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time);
- return idle_time;
+ return (cputime64_t)jiffies_to_usecs(idle_time);
}
static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index ad41f19b8e3f..12fdd3987a36 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -76,8 +76,11 @@ static void cpuidle_idle_call(void)
#endif
/* ask the governor for the next state */
next_state = cpuidle_curr_governor->select(dev);
- if (need_resched())
+ if (need_resched()) {
+ local_irq_enable();
return;
+ }
+
target_state = &dev->states[next_state];
/* enter the state and update stats */
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index a9952b1236b0..84c51e177269 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -236,7 +236,7 @@ static inline void ecb_crypt(const u8 *in, u8 *out, u32 *key,
/* Padlock in ECB mode fetches at least ecb_fetch_bytes of data.
* We could avoid some copying here but it's probably not worth it.
*/
- if (unlikely(((unsigned long)in & PAGE_SIZE) + ecb_fetch_bytes > PAGE_SIZE)) {
+ if (unlikely(((unsigned long)in & ~PAGE_MASK) + ecb_fetch_bytes > PAGE_SIZE)) {
ecb_crypt_copy(in, out, key, cword, count);
return;
}
@@ -248,7 +248,7 @@ static inline u8 *cbc_crypt(const u8 *in, u8 *out, u32 *key,
u8 *iv, struct cword *cword, int count)
{
/* Padlock in CBC mode fetches at least cbc_fetch_bytes of data. */
- if (unlikely(((unsigned long)in & PAGE_SIZE) + cbc_fetch_bytes > PAGE_SIZE))
+ if (unlikely(((unsigned long)in & ~PAGE_MASK) + cbc_fetch_bytes > PAGE_SIZE))
return cbc_crypt_copy(in, out, key, iv, cword, count);
return rep_xcrypt_cbc(in, out, key, iv, cword, count);
diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c
index 76cb6b345e7b..0af80577dc7b 100644
--- a/drivers/crypto/padlock-sha.c
+++ b/drivers/crypto/padlock-sha.c
@@ -24,6 +24,12 @@
#include <asm/i387.h>
#include "padlock.h"
+#ifdef CONFIG_64BIT
+#define STACK_ALIGN 16
+#else
+#define STACK_ALIGN 4
+#endif
+
struct padlock_sha_desc {
struct shash_desc fallback;
};
@@ -64,7 +70,9 @@ static int padlock_sha1_finup(struct shash_desc *desc, const u8 *in,
/* We can't store directly to *out as it may be unaligned. */
/* BTW Don't reduce the buffer size below 128 Bytes!
* PadLock microcode needs it that big. */
- char result[128] __attribute__ ((aligned(PADLOCK_ALIGNMENT)));
+ char buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
+ ((aligned(STACK_ALIGN)));
+ char *result = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
struct sha1_state state;
unsigned int space;
@@ -128,7 +136,9 @@ static int padlock_sha256_finup(struct shash_desc *desc, const u8 *in,
/* We can't store directly to *out as it may be unaligned. */
/* BTW Don't reduce the buffer size below 128 Bytes!
* PadLock microcode needs it that big. */
- char result[128] __attribute__ ((aligned(PADLOCK_ALIGNMENT)));
+ char buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
+ ((aligned(STACK_ALIGN)));
+ char *result = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
struct sha256_state state;
unsigned int space;
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 5903a88351bf..b401dadad4a8 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -26,6 +26,8 @@ config INTEL_IOATDMA
select DMA_ENGINE
select DCA
select ASYNC_TX_DISABLE_CHANNEL_SWITCH
+ select ASYNC_TX_DISABLE_PQ_VAL_DMA
+ select ASYNC_TX_DISABLE_XOR_VAL_DMA
help
Enable support for the Intel(R) I/OAT DMA engine present
in recent Intel Xeon chipsets.
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index bd0b248de2cf..8f99354082ce 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -632,11 +632,21 @@ static bool device_has_all_tx_types(struct dma_device *device)
#if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE)
if (!dma_has_cap(DMA_XOR, device->cap_mask))
return false;
+
+ #ifndef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
+ if (!dma_has_cap(DMA_XOR_VAL, device->cap_mask))
+ return false;
+ #endif
#endif
#if defined(CONFIG_ASYNC_PQ) || defined(CONFIG_ASYNC_PQ_MODULE)
if (!dma_has_cap(DMA_PQ, device->cap_mask))
return false;
+
+ #ifndef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
+ if (!dma_has_cap(DMA_PQ_VAL, device->cap_mask))
+ return false;
+ #endif
#endif
return true;
diff --git a/drivers/dma/ioat/dca.c b/drivers/dma/ioat/dca.c
index 69d02615c4d6..abd9038e06b1 100644
--- a/drivers/dma/ioat/dca.c
+++ b/drivers/dma/ioat/dca.c
@@ -98,17 +98,17 @@ static int dca_enabled_in_bios(struct pci_dev *pdev)
cpuid_level_9 = cpuid_eax(9);
res = test_bit(0, &cpuid_level_9);
if (!res)
- dev_err(&pdev->dev, "DCA is disabled in BIOS\n");
+ dev_dbg(&pdev->dev, "DCA is disabled in BIOS\n");
return res;
}
-static int system_has_dca_enabled(struct pci_dev *pdev)
+int system_has_dca_enabled(struct pci_dev *pdev)
{
if (boot_cpu_has(X86_FEATURE_DCA))
return dca_enabled_in_bios(pdev);
- dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n");
+ dev_dbg(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n");
return 0;
}
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
index c14fdfeb7f33..45edde996480 100644
--- a/drivers/dma/ioat/dma.h
+++ b/drivers/dma/ioat/dma.h
@@ -297,9 +297,7 @@ static inline bool is_ioat_suspended(unsigned long status)
/* channel was fatally programmed */
static inline bool is_ioat_bug(unsigned long err)
{
- return !!(err & (IOAT_CHANERR_SRC_ADDR_ERR|IOAT_CHANERR_DEST_ADDR_ERR|
- IOAT_CHANERR_NEXT_ADDR_ERR|IOAT_CHANERR_CONTROL_ERR|
- IOAT_CHANERR_LENGTH_ERR));
+ return !!err;
}
static inline void ioat_unmap(struct pci_dev *pdev, dma_addr_t addr, size_t len,
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 96ffab7d37a7..8f1f7f05deaa 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -279,6 +279,8 @@ void ioat2_timer_event(unsigned long data)
u32 chanerr;
chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+ dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
+ __func__, chanerr);
BUG_ON(is_ioat_bug(chanerr));
}
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index 35d1e33afd5b..42f6f10fb0cc 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -378,6 +378,8 @@ static void ioat3_timer_event(unsigned long data)
u32 chanerr;
chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+ dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
+ __func__, chanerr);
BUG_ON(is_ioat_bug(chanerr));
}
@@ -569,7 +571,7 @@ __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result,
dump_desc_dbg(ioat, compl_desc);
/* we leave the channel locked to ensure in order submission */
- return &desc->txd;
+ return &compl_desc->txd;
}
static struct dma_async_tx_descriptor *
@@ -728,7 +730,7 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result,
dump_desc_dbg(ioat, compl_desc);
/* we leave the channel locked to ensure in order submission */
- return &desc->txd;
+ return &compl_desc->txd;
}
static struct dma_async_tx_descriptor *
@@ -736,10 +738,16 @@ ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
unsigned int src_cnt, const unsigned char *scf, size_t len,
unsigned long flags)
{
+ /* specify valid address for disabled result */
+ if (flags & DMA_PREP_PQ_DISABLE_P)
+ dst[0] = dst[1];
+ if (flags & DMA_PREP_PQ_DISABLE_Q)
+ dst[1] = dst[0];
+
/* handle the single source multiply case from the raid6
* recovery path
*/
- if (unlikely((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1)) {
+ if ((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1) {
dma_addr_t single_source[2];
unsigned char single_source_coef[2];
@@ -761,6 +769,12 @@ ioat3_prep_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src,
unsigned int src_cnt, const unsigned char *scf, size_t len,
enum sum_check_flags *pqres, unsigned long flags)
{
+ /* specify valid address for disabled result */
+ if (flags & DMA_PREP_PQ_DISABLE_P)
+ pq[0] = pq[1];
+ if (flags & DMA_PREP_PQ_DISABLE_Q)
+ pq[1] = pq[0];
+
/* the cleanup routine only sets bits on validate failure, it
* does not clear bits on validate success... so clear it here
*/
@@ -778,9 +792,9 @@ ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src,
dma_addr_t pq[2];
memset(scf, 0, src_cnt);
- flags |= DMA_PREP_PQ_DISABLE_Q;
pq[0] = dst;
- pq[1] = ~0;
+ flags |= DMA_PREP_PQ_DISABLE_Q;
+ pq[1] = dst; /* specify valid address for disabled result */
return __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len,
flags);
@@ -800,9 +814,9 @@ ioat3_prep_pqxor_val(struct dma_chan *chan, dma_addr_t *src,
*result = 0;
memset(scf, 0, src_cnt);
- flags |= DMA_PREP_PQ_DISABLE_Q;
pq[0] = src[0];
- pq[1] = ~0;
+ flags |= DMA_PREP_PQ_DISABLE_Q;
+ pq[1] = pq[0]; /* specify valid address for disabled result */
return __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1, scf,
len, flags);
@@ -1117,6 +1131,7 @@ static int __devinit ioat3_dma_self_test(struct ioatdma_device *device)
int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
{
struct pci_dev *pdev = device->pdev;
+ int dca_en = system_has_dca_enabled(pdev);
struct dma_device *dma;
struct dma_chan *c;
struct ioat_chan_common *chan;
@@ -1137,6 +1152,11 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock;
cap = readl(device->reg_base + IOAT_DMA_CAP_OFFSET);
+
+ /* dca is incompatible with raid operations */
+ if (dca_en && (cap & (IOAT_CAP_XOR|IOAT_CAP_PQ)))
+ cap &= ~(IOAT_CAP_XOR|IOAT_CAP_PQ);
+
if (cap & IOAT_CAP_XOR) {
is_raid_device = true;
dma->max_xor = 8;
@@ -1186,6 +1206,16 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
device->timer_fn = ioat2_timer_event;
}
+ #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
+ dma_cap_clear(DMA_PQ_VAL, dma->cap_mask);
+ dma->device_prep_dma_pq_val = NULL;
+ #endif
+
+ #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
+ dma_cap_clear(DMA_XOR_VAL, dma->cap_mask);
+ dma->device_prep_dma_xor_val = NULL;
+ #endif
+
/* -= IOAT ver.3 workarounds =- */
/* Write CHANERRMSK_INT with 3E07h to mask out the errors
* that can cause stability issues for IOAT ver.3
diff --git a/drivers/dma/ioat/hw.h b/drivers/dma/ioat/hw.h
index 99afb12bd409..60e675455b6a 100644
--- a/drivers/dma/ioat/hw.h
+++ b/drivers/dma/ioat/hw.h
@@ -39,6 +39,8 @@
#define IOAT_VER_3_0 0x30 /* Version 3.0 */
#define IOAT_VER_3_2 0x32 /* Version 3.2 */
+int system_has_dca_enabled(struct pci_dev *pdev);
+
struct ioat_dma_descriptor {
uint32_t size;
union {
diff --git a/drivers/dma/ioat/registers.h b/drivers/dma/ioat/registers.h
index 63038e18ab03..f015ec196700 100644
--- a/drivers/dma/ioat/registers.h
+++ b/drivers/dma/ioat/registers.h
@@ -92,9 +92,7 @@
#define IOAT_CHANCTRL_ERR_COMPLETION_EN 0x0004
#define IOAT_CHANCTRL_INT_REARM 0x0001
#define IOAT_CHANCTRL_RUN (IOAT_CHANCTRL_INT_REARM |\
- IOAT_CHANCTRL_ERR_COMPLETION_EN |\
- IOAT_CHANCTRL_ANY_ERR_ABORT_EN |\
- IOAT_CHANCTRL_ERR_INT_EN)
+ IOAT_CHANCTRL_ANY_ERR_ABORT_EN)
#define IOAT_DMA_COMP_OFFSET 0x02 /* 16-bit DMA channel compatibility */
#define IOAT_DMA_COMP_V1 0x0001 /* Compatibility with DMA version 1 */
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index b3b065c4e5c1..034ecf0ace03 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -640,17 +640,16 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
#endif
struct sh_dmae_device *shdev;
+ /* get platform data */
+ if (!pdev->dev.platform_data)
+ return -ENODEV;
+
shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL);
if (!shdev) {
dev_err(&pdev->dev, "No enough memory\n");
- err = -ENOMEM;
- goto shdev_err;
+ return -ENOMEM;
}
- /* get platform data */
- if (!pdev->dev.platform_data)
- goto shdev_err;
-
/* platform data */
memcpy(&shdev->pdata, pdev->dev.platform_data,
sizeof(struct sh_dmae_pdata));
@@ -722,7 +721,6 @@ eirq_err:
rst_err:
kfree(shdev);
-shdev_err:
return err;
}
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 4f4ac82382f7..a38831c82649 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1122,7 +1122,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
debugf0("Reading K8_DRAM_BASE_LOW failed\n");
/* Extract parts into separate data entries */
- pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 24;
+ pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8;
pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
pvt->dram_rw_en[dram] = (low & 0x3);
@@ -1135,7 +1135,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
* Extract parts into separate data entries. Limit is the HIGHEST memory
* location of the region, so lower 24 bits need to be all ones
*/
- pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 24) | 0x00FFFFFF;
+ pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 8) | 0x00FFFFFF;
pvt->dram_IntlvSel[dram] = (low >> 8) & 0x7;
pvt->dram_DstNode[dram] = (low & 0x7);
}
@@ -1369,7 +1369,7 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
pvt->dram_IntlvEn[dram] = (low_base >> 8) & 0x7;
pvt->dram_base[dram] = (((u64)high_base & 0x000000FF) << 40) |
- (((u64)low_base & 0xFFFF0000) << 24);
+ (((u64)low_base & 0xFFFF0000) << 8);
low_offset = K8_DRAM_LIMIT_LOW + (dram << 3);
high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
@@ -1391,7 +1391,7 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
* memory location of the region, so low 24 bits need to be all ones.
*/
pvt->dram_limit[dram] = (((u64)high_limit & 0x000000FF) << 40) |
- (((u64) low_limit & 0xFFFF0000) << 24) |
+ (((u64) low_limit & 0xFFFF0000) << 8) |
0x00FFFFFF;
}
@@ -2254,7 +2254,7 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
{
u32 ec = ERROR_CODE(info->nbsl);
u32 xec = EXT_ERROR_CODE(info->nbsl);
- int ecc_type = info->nbsh & (0x3 << 13);
+ int ecc_type = (info->nbsh >> 13) & 0x3;
/* Bail early out if this was an 'observed' error */
if (PP(ec) == K8_NBSL_PP_OBS)
@@ -3163,7 +3163,7 @@ static int __init amd64_edac_init(void)
opstate_init();
if (cache_k8_northbridges() < 0)
- goto err_exit;
+ return err;
err = pci_register_driver(&amd64_pci_driver);
if (err)
@@ -3189,8 +3189,6 @@ static int __init amd64_edac_init(void)
err_2nd_stage:
debugf0("2nd stage failed\n");
-
-err_exit:
pci_unregister_driver(&amd64_pci_driver);
return err;
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 713ed7d37247..689cc6a6214d 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -3,7 +3,6 @@
static bool report_gart_errors;
static void (*nb_bus_decoder)(int node_id, struct err_regs *regs);
-static void (*orig_mce_callback)(struct mce *m);
void amd_report_gart_errors(bool v)
{
@@ -363,8 +362,10 @@ static inline void amd_decode_err_code(unsigned int ec)
pr_warning("Huh? Unknown MCE error 0x%x\n", ec);
}
-static void amd_decode_mce(struct mce *m)
+static int amd_decode_mce(struct notifier_block *nb, unsigned long val,
+ void *data)
{
+ struct mce *m = (struct mce *)data;
struct err_regs regs;
int node, ecc;
@@ -420,20 +421,22 @@ static void amd_decode_mce(struct mce *m)
}
amd_decode_err_code(m->status & 0xffff);
+
+ return NOTIFY_STOP;
}
+static struct notifier_block amd_mce_dec_nb = {
+ .notifier_call = amd_decode_mce,
+};
+
static int __init mce_amd_init(void)
{
/*
* We can decode MCEs for Opteron and later CPUs:
*/
if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
- (boot_cpu_data.x86 >= 0xf)) {
- /* safe the default decode mce callback */
- orig_mce_callback = x86_mce_decode_callback;
-
- x86_mce_decode_callback = amd_decode_mce;
- }
+ (boot_cpu_data.x86 >= 0xf))
+ atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb);
return 0;
}
@@ -442,7 +445,7 @@ early_initcall(mce_amd_init);
#ifdef MODULE
static void __exit mce_amd_exit(void)
{
- x86_mce_decode_callback = orig_mce_callback;
+ atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &amd_mce_dec_nb);
}
MODULE_DESCRIPTION("AMD MCE decoder");
diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c
index d335086f4a26..77a9579d7167 100644
--- a/drivers/edac/i5000_edac.c
+++ b/drivers/edac/i5000_edac.c
@@ -1173,7 +1173,7 @@ static void i5000_get_mc_regs(struct mem_ctl_info *mci)
pci_read_config_word(pvt->branch_1, where,
&pvt->b1_mtr[slot_row]);
debugf2("MTR%d where=0x%x B1 value=0x%x\n", slot_row,
- where, pvt->b0_mtr[slot_row]);
+ where, pvt->b1_mtr[slot_row]);
} else {
pvt->b1_mtr[slot_row] = 0;
}
@@ -1232,7 +1232,7 @@ static int i5000_init_csrows(struct mem_ctl_info *mci)
struct csrow_info *p_csrow;
int empty, channel_count;
int max_csrows;
- int mtr;
+ int mtr, mtr1;
int csrow_megs;
int channel;
int csrow;
@@ -1251,9 +1251,10 @@ static int i5000_init_csrows(struct mem_ctl_info *mci)
/* use branch 0 for the basis */
mtr = pvt->b0_mtr[csrow >> 1];
+ mtr1 = pvt->b1_mtr[csrow >> 1];
/* if no DIMMS on this row, continue */
- if (!MTR_DIMMS_PRESENT(mtr))
+ if (!MTR_DIMMS_PRESENT(mtr) && !MTR_DIMMS_PRESENT(mtr1))
continue;
/* FAKE OUT VALUES, FIXME */
diff --git a/drivers/edac/i5400_edac.c b/drivers/edac/i5400_edac.c
index b08b6d8e2dc7..f99d10655ed4 100644
--- a/drivers/edac/i5400_edac.c
+++ b/drivers/edac/i5400_edac.c
@@ -46,9 +46,10 @@
/* Limits for i5400 */
#define NUM_MTRS_PER_BRANCH 4
#define CHANNELS_PER_BRANCH 2
+#define MAX_DIMMS_PER_CHANNEL NUM_MTRS_PER_BRANCH
#define MAX_CHANNELS 4
-#define MAX_DIMMS (MAX_CHANNELS * 4) /* Up to 4 DIMM's per channel */
-#define MAX_CSROWS (MAX_DIMMS * 2) /* max possible csrows per channel */
+/* max possible csrows per channel */
+#define MAX_CSROWS (MAX_DIMMS_PER_CHANNEL)
/* Device 16,
* Function 0: System Address
@@ -331,7 +332,6 @@ static const struct i5400_dev_info i5400_devs[] = {
struct i5400_dimm_info {
int megabytes; /* size, 0 means not present */
- int dual_rank;
};
/* driver private data structure */
@@ -849,11 +849,9 @@ static int determine_mtr(struct i5400_pvt *pvt, int csrow, int channel)
int n;
/* There is one MTR for each slot pair of FB-DIMMs,
- Each slot may have one or two ranks (2 csrows),
Each slot pair may be at branch 0 or branch 1.
- So, csrow should be divided by eight
*/
- n = csrow >> 3;
+ n = csrow;
if (n >= NUM_MTRS_PER_BRANCH) {
debugf0("ERROR: trying to access an invalid csrow: %d\n",
@@ -905,25 +903,22 @@ static void handle_channel(struct i5400_pvt *pvt, int csrow, int channel,
amb_present_reg = determine_amb_present_reg(pvt, channel);
/* Determine if there is a DIMM present in this DIMM slot */
- if (amb_present_reg & (1 << (csrow >> 1))) {
- dinfo->dual_rank = MTR_DIMM_RANK(mtr);
-
- if (!((dinfo->dual_rank == 0) &&
- ((csrow & 0x1) == 0x1))) {
- /* Start with the number of bits for a Bank
- * on the DRAM */
- addrBits = MTR_DRAM_BANKS_ADDR_BITS(mtr);
- /* Add thenumber of ROW bits */
- addrBits += MTR_DIMM_ROWS_ADDR_BITS(mtr);
- /* add the number of COLUMN bits */
- addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
-
- addrBits += 6; /* add 64 bits per DIMM */
- addrBits -= 20; /* divide by 2^^20 */
- addrBits -= 3; /* 8 bits per bytes */
-
- dinfo->megabytes = 1 << addrBits;
- }
+ if (amb_present_reg & (1 << csrow)) {
+ /* Start with the number of bits for a Bank
+ * on the DRAM */
+ addrBits = MTR_DRAM_BANKS_ADDR_BITS(mtr);
+ /* Add thenumber of ROW bits */
+ addrBits += MTR_DIMM_ROWS_ADDR_BITS(mtr);
+ /* add the number of COLUMN bits */
+ addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
+ /* add the number of RANK bits */
+ addrBits += MTR_DIMM_RANK(mtr);
+
+ addrBits += 6; /* add 64 bits per DIMM */
+ addrBits -= 20; /* divide by 2^^20 */
+ addrBits -= 3; /* 8 bits per bytes */
+
+ dinfo->megabytes = 1 << addrBits;
}
}
}
@@ -951,12 +946,12 @@ static void calculate_dimm_size(struct i5400_pvt *pvt)
return;
}
- /* Scan all the actual CSROWS (which is # of DIMMS * 2)
+ /* Scan all the actual CSROWS
* and calculate the information for each DIMM
* Start with the highest csrow first, to display it first
* and work toward the 0th csrow
*/
- max_csrows = pvt->maxdimmperch * 2;
+ max_csrows = pvt->maxdimmperch;
for (csrow = max_csrows - 1; csrow >= 0; csrow--) {
/* on an odd csrow, first output a 'boundary' marker,
@@ -1064,7 +1059,7 @@ static void i5400_get_mc_regs(struct mem_ctl_info *mci)
/* Get the set of MTR[0-3] regs by each branch */
for (slot_row = 0; slot_row < NUM_MTRS_PER_BRANCH; slot_row++) {
- int where = MTR0 + (slot_row * sizeof(u32));
+ int where = MTR0 + (slot_row * sizeof(u16));
/* Branch 0 set of MTR registers */
pci_read_config_word(pvt->branch_0, where,
@@ -1146,7 +1141,7 @@ static int i5400_init_csrows(struct mem_ctl_info *mci)
pvt = mci->pvt_info;
channel_count = pvt->maxch;
- max_csrows = pvt->maxdimmperch * 2;
+ max_csrows = pvt->maxdimmperch;
empty = 1; /* Assume NO memory */
@@ -1215,28 +1210,6 @@ static void i5400_enable_error_reporting(struct mem_ctl_info *mci)
}
/*
- * i5400_get_dimm_and_channel_counts(pdev, &num_csrows, &num_channels)
- *
- * ask the device how many channels are present and how many CSROWS
- * as well
- */
-static void i5400_get_dimm_and_channel_counts(struct pci_dev *pdev,
- int *num_dimms_per_channel,
- int *num_channels)
-{
- u8 value;
-
- /* Need to retrieve just how many channels and dimms per channel are
- * supported on this memory controller
- */
- pci_read_config_byte(pdev, MAXDIMMPERCH, &value);
- *num_dimms_per_channel = (int)value * 2;
-
- pci_read_config_byte(pdev, MAXCH, &value);
- *num_channels = (int)value;
-}
-
-/*
* i5400_probe1 Probe for ONE instance of device to see if it is
* present.
* return:
@@ -1263,22 +1236,16 @@ static int i5400_probe1(struct pci_dev *pdev, int dev_idx)
if (PCI_FUNC(pdev->devfn) != 0)
return -ENODEV;
- /* Ask the devices for the number of CSROWS and CHANNELS so
- * that we can calculate the memory resources, etc
- *
- * The Chipset will report what it can handle which will be greater
- * or equal to what the motherboard manufacturer will implement.
- *
- * As we don't have a motherboard identification routine to determine
+ /* As we don't have a motherboard identification routine to determine
* actual number of slots/dimms per channel, we thus utilize the
* resource as specified by the chipset. Thus, we might have
* have more DIMMs per channel than actually on the mobo, but this
* allows the driver to support upto the chipset max, without
* some fancy mobo determination.
*/
- i5400_get_dimm_and_channel_counts(pdev, &num_dimms_per_channel,
- &num_channels);
- num_csrows = num_dimms_per_channel * 2;
+ num_dimms_per_channel = MAX_DIMMS_PER_CHANNEL;
+ num_channels = MAX_CHANNELS;
+ num_csrows = num_dimms_per_channel;
debugf0("MC: %s(): Number of - Channels= %d DIMMS= %d CSROWS= %d\n",
__func__, num_channels, num_dimms_per_channel, num_csrows);
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 157f6504f25e..cf27402af97b 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -26,7 +26,9 @@
#include "mpc85xx_edac.h"
static int edac_dev_idx;
+#ifdef CONFIG_PCI
static int edac_pci_idx;
+#endif
static int edac_mc_idx;
static u32 orig_ddr_err_disable;
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 5d524254499e..94260aa76aa3 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -275,7 +275,7 @@ static void log_irqs(u32 evt)
!(evt & OHCI1394_busReset))
return;
- fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
+ fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
evt & OHCI1394_selfIDComplete ? " selfID" : "",
evt & OHCI1394_RQPkt ? " AR_req" : "",
evt & OHCI1394_RSPkt ? " AR_resp" : "",
@@ -286,6 +286,7 @@ static void log_irqs(u32 evt)
evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "",
evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "",
evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "",
+ evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "",
evt & OHCI1394_regAccessFail ? " regAccessFail" : "",
evt & OHCI1394_busReset ? " busReset" : "",
evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
@@ -293,6 +294,7 @@ static void log_irqs(u32 evt)
OHCI1394_respTxComplete | OHCI1394_isochRx |
OHCI1394_isochTx | OHCI1394_postedWriteErr |
OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
+ OHCI1394_cycleInconsistent |
OHCI1394_regAccessFail | OHCI1394_busReset)
? " ?" : "");
}
@@ -1439,6 +1441,17 @@ static irqreturn_t irq_handler(int irq, void *data)
OHCI1394_LinkControl_cycleMaster);
}
+ if (unlikely(event & OHCI1394_cycleInconsistent)) {
+ /*
+ * We need to clear this event bit in order to make
+ * cycleMatch isochronous I/O work. In theory we should
+ * stop active cycleMatch iso contexts now and restart
+ * them at least two cycles later. (FIXME?)
+ */
+ if (printk_ratelimit())
+ fw_notify("isochronous cycle inconsistent\n");
+ }
+
if (event & OHCI1394_cycle64Seconds) {
cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
if ((cycle_time & 0x80000000) == 0)
@@ -1528,6 +1541,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
OHCI1394_isochRx | OHCI1394_isochTx |
OHCI1394_postedWriteErr | OHCI1394_cycleTooLong |
+ OHCI1394_cycleInconsistent |
OHCI1394_cycle64Seconds | OHCI1394_regAccessFail |
OHCI1394_masterIntEnable);
if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
@@ -1890,15 +1904,30 @@ static int handle_it_packet(struct context *context,
{
struct iso_context *ctx =
container_of(context, struct iso_context, context);
+ int i;
+ struct descriptor *pd;
- if (last->transfer_status == 0)
- /* This descriptor isn't done yet, stop iteration. */
+ for (pd = d; pd <= last; pd++)
+ if (pd->transfer_status)
+ break;
+ if (pd > last)
+ /* Descriptor(s) not done yet, stop iteration */
return 0;
- if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS)
+ i = ctx->header_length;
+ if (i + 4 < PAGE_SIZE) {
+ /* Present this value as big-endian to match the receive code */
+ *(__be32 *)(ctx->header + i) = cpu_to_be32(
+ ((u32)le16_to_cpu(pd->transfer_status) << 16) |
+ le16_to_cpu(pd->res_count));
+ ctx->header_length += 4;
+ }
+ if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) {
ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count),
- 0, NULL, ctx->base.callback_data);
-
+ ctx->header_length, ctx->header,
+ ctx->base.callback_data);
+ ctx->header_length = 0;
+ }
return 1;
}
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 50f0176de615..98dbbda3ad41 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -188,14 +188,7 @@ static struct fw_device *target_device(struct sbp2_target *tgt)
/* Impossible login_id, to detect logout attempt before successful login */
#define INVALID_LOGIN_ID 0x10000
-/*
- * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
- * provided in the config rom. Most devices do provide a value, which
- * we'll use for login management orbs, but with some sane limits.
- */
-#define SBP2_MIN_LOGIN_ORB_TIMEOUT 5000U /* Timeout in ms */
-#define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */
-#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
+#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
#define SBP2_ORB_NULL 0x80000000
#define SBP2_RETRY_LIMIT 0xf /* 15 retries */
#define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */
@@ -1034,7 +1027,6 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
{
struct fw_csr_iterator ci;
int key, value;
- unsigned int timeout;
fw_csr_iterator_init(&ci, directory);
while (fw_csr_iterator_next(&ci, &key, &value)) {
@@ -1059,17 +1051,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
case SBP2_CSR_UNIT_CHARACTERISTICS:
/* the timeout value is stored in 500ms units */
- timeout = ((unsigned int) value >> 8 & 0xff) * 500;
- timeout = max(timeout, SBP2_MIN_LOGIN_ORB_TIMEOUT);
- tgt->mgt_orb_timeout =
- min(timeout, SBP2_MAX_LOGIN_ORB_TIMEOUT);
-
- if (timeout > tgt->mgt_orb_timeout)
- fw_notify("%s: config rom contains %ds "
- "management ORB timeout, limiting "
- "to %ds\n", tgt->bus_id,
- timeout / 1000,
- tgt->mgt_orb_timeout / 1000);
+ tgt->mgt_orb_timeout = (value >> 8 & 0xff) * 500;
break;
case SBP2_CSR_LOGICAL_UNIT_NUMBER:
@@ -1087,6 +1069,22 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
return 0;
}
+/*
+ * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
+ * provided in the config rom. Most devices do provide a value, which
+ * we'll use for login management orbs, but with some sane limits.
+ */
+static void sbp2_clamp_management_orb_timeout(struct sbp2_target *tgt)
+{
+ unsigned int timeout = tgt->mgt_orb_timeout;
+
+ if (timeout > 40000)
+ fw_notify("%s: %ds mgt_ORB_timeout limited to 40s\n",
+ tgt->bus_id, timeout / 1000);
+
+ tgt->mgt_orb_timeout = clamp_val(timeout, 5000, 40000);
+}
+
static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
u32 firmware_revision)
{
@@ -1171,6 +1169,7 @@ static int sbp2_probe(struct device *dev)
&firmware_revision) < 0)
goto fail_tgt_put;
+ sbp2_clamp_management_orb_timeout(tgt);
sbp2_init_workarounds(tgt, model, firmware_revision);
/*
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 662ed923d9eb..50de0f5750d8 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -661,7 +661,7 @@ int gpio_export(unsigned gpio, bool direction_may_change)
dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
desc, ioname ? ioname : "gpio%d", gpio);
- if (dev) {
+ if (!IS_ERR(dev)) {
if (direction_may_change)
status = sysfs_create_group(&dev->kobj,
&gpio_attr_group);
@@ -679,7 +679,7 @@ int gpio_export(unsigned gpio, bool direction_may_change)
if (status != 0)
device_unregister(dev);
} else
- status = -ENODEV;
+ status = PTR_ERR(dev);
if (status == 0)
set_bit(FLAG_EXPORT, &desc->flags);
}
@@ -800,11 +800,11 @@ static int gpiochip_export(struct gpio_chip *chip)
mutex_lock(&sysfs_lock);
dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip,
"gpiochip%d", chip->base);
- if (dev) {
+ if (!IS_ERR(dev)) {
status = sysfs_create_group(&dev->kobj,
&gpiochip_attr_group);
} else
- status = -ENODEV;
+ status = PTR_ERR(dev);
chip->exported = (status == 0);
mutex_unlock(&sysfs_lock);
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 5711ce5353c6..4baf3d7d0f8e 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -144,13 +144,6 @@ static int lnw_irq_type(unsigned irq, unsigned type)
static void lnw_irq_unmask(unsigned irq)
{
- struct lnw_gpio *lnw = get_irq_chip_data(irq);
- u32 gpio = irq - lnw->irq_base;
- u8 reg = gpio / 32;
- void __iomem *gedr;
-
- gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]);
- writel(BIT(gpio % 32), gedr);
};
static void lnw_irq_mask(unsigned irq)
@@ -183,13 +176,11 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
gedr_v = readl(gedr);
if (!gedr_v)
continue;
- for (gpio = reg*32; gpio < reg*32+32; gpio++) {
- gedr_v = readl(gedr);
+ for (gpio = reg*32; gpio < reg*32+32; gpio++)
if (gedr_v & BIT(gpio % 32)) {
pr_debug("pin %d triggered\n", gpio);
generic_handle_irq(lnw->irq_base + gpio);
}
- }
/* clear the edge detect status bit */
writel(gedr_v, gedr);
}
diff --git a/drivers/gpio/twl4030-gpio.c b/drivers/gpio/twl4030-gpio.c
index afad14792141..49384a7c5492 100644
--- a/drivers/gpio/twl4030-gpio.c
+++ b/drivers/gpio/twl4030-gpio.c
@@ -460,7 +460,8 @@ no_irqs:
return ret;
}
-static int __devexit gpio_twl4030_remove(struct platform_device *pdev)
+/* Cannot use __devexit as gpio_twl4030_probe() calls us */
+static int gpio_twl4030_remove(struct platform_device *pdev)
{
struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
int status;
@@ -493,7 +494,7 @@ static struct platform_driver gpio_twl4030_driver = {
.driver.name = "twl4030_gpio",
.driver.owner = THIS_MODULE,
.probe = gpio_twl4030_probe,
- .remove = __devexit_p(gpio_twl4030_remove),
+ .remove = gpio_twl4030_remove,
};
static int __init gpio_twl4030_init(void)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f831ea159291..96eddd17e050 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -92,6 +92,7 @@ config DRM_I830
config DRM_I915
tristate "i915 driver"
depends on AGP_INTEL
+ select SHMEM
select DRM_KMS_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 1fe4e1d344fd..bbfd110a7168 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -331,6 +331,7 @@ create_mode:
cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60,
cmdline_mode->rb, cmdline_mode->interlace,
cmdline_mode->margins);
+ drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
list_add(&mode->head, &connector->modes);
return mode;
}
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 3c0d2b3aed76..b54ba63d506e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -626,6 +626,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
return NULL;
}
+ /* it is incorrect if hsync/vsync width is zero */
+ if (!hsync_pulse_width || !vsync_pulse_width) {
+ DRM_DEBUG_KMS("Incorrect Detailed timing. "
+ "Wrong Hsync/Vsync pulse width\n");
+ return NULL;
+ }
mode = drm_mode_create(dev);
if (!mode)
return NULL;
@@ -647,6 +653,21 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
mode->vsync_end = mode->vsync_start + vsync_pulse_width;
mode->vtotal = mode->vdisplay + vblank;
+ /* perform the basic check for the detailed timing */
+ if (mode->hsync_end > mode->htotal ||
+ mode->vsync_end > mode->vtotal) {
+ drm_mode_destroy(dev, mode);
+ DRM_DEBUG_KMS("Incorrect detailed timing. "
+ "Sync is beyond the blank.\n");
+ return NULL;
+ }
+
+ /* Some EDIDs have bogus h/vtotal values */
+ if (mode->hsync_end > mode->htotal)
+ mode->htotal = mode->hsync_end + 1;
+ if (mode->vsync_end > mode->vtotal)
+ mode->vtotal = mode->vsync_end + 1;
+
drm_mode_set_name(mode);
if (pt->misc & DRM_EDID_PT_INTERLACED)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 23dc9c115fd9..65ef011fa8ba 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -454,22 +454,39 @@ out_free:
}
EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
-static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
+static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, u16 regno, struct fb_info *info)
{
struct drm_fb_helper *fb_helper = info->par;
struct drm_framebuffer *fb = fb_helper->fb;
int pindex;
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+ u32 *palette;
+ u32 value;
+ /* place color in psuedopalette */
+ if (regno > 16)
+ return -EINVAL;
+ palette = (u32 *)info->pseudo_palette;
+ red >>= (16 - info->var.red.length);
+ green >>= (16 - info->var.green.length);
+ blue >>= (16 - info->var.blue.length);
+ value = (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset);
+ palette[regno] = value;
+ return 0;
+ }
+
pindex = regno;
if (fb->bits_per_pixel == 16) {
pindex = regno << 3;
if (fb->depth == 16 && regno > 63)
- return;
+ return -EINVAL;
if (fb->depth == 15 && regno > 31)
- return;
+ return -EINVAL;
if (fb->depth == 16) {
u16 r, g, b;
@@ -493,13 +510,7 @@ static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
if (fb->depth != 16)
fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
-
- if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
- ((u32 *) fb->pseudo_palette)[regno] =
- (regno << info->var.red.offset) |
- (regno << info->var.green.offset) |
- (regno << info->var.blue.offset);
- }
+ return 0;
}
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
@@ -536,7 +547,9 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
if (transp)
htransp = *transp++;
- setcolreg(crtc, hred, hgreen, hblue, start++, info);
+ rc = setcolreg(crtc, hred, hgreen, hblue, start++, info);
+ if (rc)
+ return rc;
}
crtc_funcs->load_lut(crtc);
}
@@ -555,6 +568,7 @@ int drm_fb_helper_setcolreg(unsigned regno,
struct drm_device *dev = fb_helper->dev;
struct drm_crtc *crtc;
int i;
+ int ret;
if (regno > 255)
return 1;
@@ -568,8 +582,10 @@ int drm_fb_helper_setcolreg(unsigned regno,
if (i == fb_helper->crtc_count)
continue;
+ ret = setcolreg(crtc, red, green, blue, regno, info);
+ if (ret)
+ return ret;
- setcolreg(crtc, red, green, blue, regno, info);
crtc_funcs->load_lut(crtc);
}
return 0;
@@ -583,7 +599,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
struct drm_framebuffer *fb = fb_helper->fb;
int depth;
- if (var->pixclock == -1 || !var->pixclock)
+ if (var->pixclock != 0)
return -EINVAL;
/* Need to resize the fb object !!! */
@@ -675,7 +691,7 @@ int drm_fb_helper_set_par(struct fb_info *info)
int ret;
int i;
- if (var->pixclock != -1) {
+ if (var->pixclock != 0) {
DRM_ERROR("PIXEL CLCOK SET\n");
return -EINVAL;
}
@@ -691,7 +707,7 @@ int drm_fb_helper_set_par(struct fb_info *info)
if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) {
mutex_lock(&dev->mode_config.mutex);
- ret = crtc->funcs->set_config(&fb_helper->crtc_info->mode_set);
+ ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set);
mutex_unlock(&dev->mode_config.mutex);
if (ret)
return ret;
@@ -888,7 +904,7 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
fb_helper->fb = fb;
if (new_fb) {
- info->var.pixclock = -1;
+ info->var.pixclock = 0;
if (register_framebuffer(info) < 0)
return -EINVAL;
} else {
@@ -928,7 +944,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
{
info->fix.type = FB_TYPE_PACKED_PIXELS;
info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
- FB_VISUAL_DIRECTCOLOR;
+ FB_VISUAL_TRUECOLOR;
info->fix.type_aux = 0;
info->fix.xpanstep = 1; /* doing it in hw */
info->fix.ypanstep = 1; /* doing it in hw */
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 80391995bdec..e9dbb481c469 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -552,7 +552,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
vma->vm_ops = obj->dev->driver->gem_vm_ops;
vma->vm_private_data = map->handle;
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
/* Take a ref for this mapping of the object, so that the fault
* handler can dereference the mmap offset's pointer to the object.
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index c861d80fd779..97dc5a4f0de4 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -103,6 +103,11 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
return child;
}
+/* drm_mm_pre_get() - pre allocate drm_mm_node structure
+ * drm_mm: memory manager struct we are pre-allocating for
+ *
+ * Returns 0 on success or -ENOMEM if allocation fails.
+ */
int drm_mm_pre_get(struct drm_mm *mm)
{
struct drm_mm_node *node;
@@ -253,12 +258,14 @@ void drm_mm_put_block(struct drm_mm_node *cur)
prev_node->size += next_node->size;
list_del(&next_node->ml_entry);
list_del(&next_node->fl_entry);
+ spin_lock(&mm->unused_lock);
if (mm->num_unused < MM_UNUSED_TARGET) {
list_add(&next_node->fl_entry,
&mm->unused_nodes);
++mm->num_unused;
} else
kfree(next_node);
+ spin_unlock(&mm->unused_lock);
} else {
next_node->size += cur->size;
next_node->start = cur->start;
@@ -271,11 +278,13 @@ void drm_mm_put_block(struct drm_mm_node *cur)
list_add(&cur->fl_entry, &mm->fl_entry);
} else {
list_del(&cur->ml_entry);
+ spin_lock(&mm->unused_lock);
if (mm->num_unused < MM_UNUSED_TARGET) {
list_add(&cur->fl_entry, &mm->unused_nodes);
++mm->num_unused;
} else
kfree(cur);
+ spin_unlock(&mm->unused_lock);
}
}
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index f8ce9a3a420d..26bf0552b3cb 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -267,10 +267,10 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co
uint32_t *mem;
for (page = 0; page < page_count; page++) {
- mem = kmap(pages[page]);
+ mem = kmap_atomic(pages[page], KM_USER0);
for (i = 0; i < PAGE_SIZE; i += 4)
seq_printf(m, "%08x : %08x\n", i, mem[i / 4]);
- kunmap(pages[page]);
+ kunmap_atomic(pages[page], KM_USER0);
}
}
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 92aeb918e0c0..e5b138be45fa 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1227,8 +1227,7 @@ static int i915_load_modeset_init(struct drm_device *dev,
goto out;
/* Try to set up FBC with a reasonable compressed buffer size */
- if (IS_MOBILE(dev) && (IS_I9XX(dev) || IS_I965G(dev) || IS_GM45(dev)) &&
- i915_powersave) {
+ if (I915_HAS_FBC(dev) && i915_powersave) {
int cfb_size;
/* Try to get an 8M buffer... */
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b93814c0d3e2..7f436ec075f6 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -89,7 +89,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
pci_set_power_state(dev->pdev, PCI_D3hot);
}
- dev_priv->suspended = 1;
+ /* Modeset on resume, not lid events */
+ dev_priv->modeset_on_lid = 0;
return 0;
}
@@ -124,7 +125,7 @@ static int i915_resume(struct drm_device *dev)
drm_helper_resume_force_mode(dev);
}
- dev_priv->suspended = 0;
+ dev_priv->modeset_on_lid = 0;
return ret;
}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6035d3dae851..a725f6591192 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -274,7 +274,7 @@ typedef struct drm_i915_private {
struct drm_i915_display_funcs display;
/* Register state */
- bool suspended;
+ bool modeset_on_lid;
u8 saveLBB;
u32 saveDSPACNTR;
u32 saveDSPBCNTR;
@@ -296,6 +296,13 @@ typedef struct drm_i915_private {
u32 saveVBLANK_A;
u32 saveVSYNC_A;
u32 saveBCLRPAT_A;
+ u32 saveTRANSACONF;
+ u32 saveTRANS_HTOTAL_A;
+ u32 saveTRANS_HBLANK_A;
+ u32 saveTRANS_HSYNC_A;
+ u32 saveTRANS_VTOTAL_A;
+ u32 saveTRANS_VBLANK_A;
+ u32 saveTRANS_VSYNC_A;
u32 savePIPEASTAT;
u32 saveDSPASTRIDE;
u32 saveDSPASIZE;
@@ -304,8 +311,11 @@ typedef struct drm_i915_private {
u32 saveDSPASURF;
u32 saveDSPATILEOFF;
u32 savePFIT_PGM_RATIOS;
+ u32 saveBLC_HIST_CTL;
u32 saveBLC_PWM_CTL;
u32 saveBLC_PWM_CTL2;
+ u32 saveBLC_CPU_PWM_CTL;
+ u32 saveBLC_CPU_PWM_CTL2;
u32 saveFPB0;
u32 saveFPB1;
u32 saveDPLL_B;
@@ -317,6 +327,13 @@ typedef struct drm_i915_private {
u32 saveVBLANK_B;
u32 saveVSYNC_B;
u32 saveBCLRPAT_B;
+ u32 saveTRANSBCONF;
+ u32 saveTRANS_HTOTAL_B;
+ u32 saveTRANS_HBLANK_B;
+ u32 saveTRANS_HSYNC_B;
+ u32 saveTRANS_VTOTAL_B;
+ u32 saveTRANS_VBLANK_B;
+ u32 saveTRANS_VSYNC_B;
u32 savePIPEBSTAT;
u32 saveDSPBSTRIDE;
u32 saveDSPBSIZE;
@@ -342,6 +359,7 @@ typedef struct drm_i915_private {
u32 savePFIT_CONTROL;
u32 save_palette_a[256];
u32 save_palette_b[256];
+ u32 saveDPFC_CB_BASE;
u32 saveFBC_CFB_BASE;
u32 saveFBC_LL_BASE;
u32 saveFBC_CONTROL;
@@ -349,6 +367,12 @@ typedef struct drm_i915_private {
u32 saveIER;
u32 saveIIR;
u32 saveIMR;
+ u32 saveDEIER;
+ u32 saveDEIMR;
+ u32 saveGTIER;
+ u32 saveGTIMR;
+ u32 saveFDI_RXA_IMR;
+ u32 saveFDI_RXB_IMR;
u32 saveCACHE_MODE_0;
u32 saveD_STATE;
u32 saveDSPCLK_GATE_D;
@@ -382,6 +406,26 @@ typedef struct drm_i915_private {
u32 savePIPEB_DP_LINK_M;
u32 savePIPEA_DP_LINK_N;
u32 savePIPEB_DP_LINK_N;
+ u32 saveFDI_RXA_CTL;
+ u32 saveFDI_TXA_CTL;
+ u32 saveFDI_RXB_CTL;
+ u32 saveFDI_TXB_CTL;
+ u32 savePFA_CTL_1;
+ u32 savePFB_CTL_1;
+ u32 savePFA_WIN_SZ;
+ u32 savePFB_WIN_SZ;
+ u32 savePFA_WIN_POS;
+ u32 savePFB_WIN_POS;
+ u32 savePCH_DREF_CONTROL;
+ u32 saveDISP_ARB_CTL;
+ u32 savePIPEA_DATA_M1;
+ u32 savePIPEA_DATA_N1;
+ u32 savePIPEA_LINK_M1;
+ u32 savePIPEA_LINK_N1;
+ u32 savePIPEB_DATA_M1;
+ u32 savePIPEB_DATA_N1;
+ u32 savePIPEB_LINK_M1;
+ u32 savePIPEB_LINK_N1;
struct {
struct drm_mm gtt_space;
@@ -492,6 +536,8 @@ typedef struct drm_i915_private {
struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
} mm;
struct sdvo_device_mapping sdvo_mappings[2];
+ /* indicate whether the LVDS_BORDER should be enabled or not */
+ unsigned int lvds_border_bits;
/* Reclocking support */
bool render_reclock_avail;
@@ -981,7 +1027,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))
#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev))
-#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && (IS_I9XX(dev) || IS_I965G(dev)))
+#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \
+ (IS_I9XX(dev) || IS_GM45(dev)) && \
+ !IS_IGD(dev) && \
+ !IS_IGDNG(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index c3ceffa46ea0..aa7fd82aa6eb 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -254,10 +254,15 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE;
- u32 de_iir, gt_iir;
+ u32 de_iir, gt_iir, de_ier;
u32 new_de_iir, new_gt_iir;
struct drm_i915_master_private *master_priv;
+ /* disable master interrupt before clearing iir */
+ de_ier = I915_READ(DEIER);
+ I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
+ (void)I915_READ(DEIER);
+
de_iir = I915_READ(DEIIR);
gt_iir = I915_READ(GTIIR);
@@ -290,6 +295,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
gt_iir = new_gt_iir;
}
+ I915_WRITE(DEIER, de_ier);
+ (void)I915_READ(DEIER);
+
return ret;
}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0466ddbeba32..1687edf68795 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -968,6 +968,8 @@
#define LVDS_PORT_EN (1 << 31)
/* Selects pipe B for LVDS data. Must be set on pre-965. */
#define LVDS_PIPEB_SELECT (1 << 30)
+/* Enable border for unscaled (or aspect-scaled) display */
+#define LVDS_BORDER_ENABLE (1 << 15)
/*
* Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
* pixel.
@@ -1078,6 +1080,8 @@
#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
+#define BLC_HIST_CTL 0x61260
+
/* TV port control */
#define TV_CTL 0x68000
/** Enables the TV encoder */
@@ -1780,6 +1784,11 @@
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
+#define PIPE_BPC_MASK (7 << 5) /* Ironlake */
+#define PIPE_8BPC (0 << 5)
+#define PIPE_10BPC (1 << 5)
+#define PIPE_6BPC (2 << 5)
+#define PIPE_12BPC (3 << 5)
#define DSPARB 0x70030
#define DSPARB_CSTART_MASK (0x7f << 7)
@@ -1790,17 +1799,29 @@
#define DSPARB_AEND_SHIFT 0
#define DSPFW1 0x70034
+#define DSPFW_SR_SHIFT 23
+#define DSPFW_CURSORB_SHIFT 16
+#define DSPFW_PLANEB_SHIFT 8
#define DSPFW2 0x70038
+#define DSPFW_CURSORA_MASK 0x00003f00
+#define DSPFW_CURSORA_SHIFT 16
#define DSPFW3 0x7003c
+#define DSPFW_HPLL_SR_EN (1<<31)
+#define DSPFW_CURSOR_SR_SHIFT 24
#define IGD_SELF_REFRESH_EN (1<<30)
/* FIFO watermark sizes etc */
+#define G4X_FIFO_LINE_SIZE 64
#define I915_FIFO_LINE_SIZE 64
#define I830_FIFO_LINE_SIZE 32
+
+#define G4X_FIFO_SIZE 127
#define I945_FIFO_SIZE 127 /* 945 & 965 */
#define I915_FIFO_SIZE 95
#define I855GM_FIFO_SIZE 127 /* In cachelines */
#define I830_FIFO_SIZE 95
+
+#define G4X_MAX_WM 0x3f
#define I915_MAX_WM 0x3f
#define IGD_DISPLAY_FIFO 512 /* in 64byte unit */
@@ -2030,6 +2051,11 @@
#define PFA_CTL_1 0x68080
#define PFB_CTL_1 0x68880
#define PF_ENABLE (1<<31)
+#define PF_FILTER_MASK (3<<23)
+#define PF_FILTER_PROGRAMMED (0<<23)
+#define PF_FILTER_MED_3x3 (1<<23)
+#define PF_FILTER_EDGE_ENHANCE (2<<23)
+#define PF_FILTER_EDGE_SOFTEN (3<<23)
#define PFA_WIN_SZ 0x68074
#define PFB_WIN_SZ 0x68874
#define PFA_WIN_POS 0x68070
@@ -2149,11 +2175,11 @@
#define DREF_CPU_SOURCE_OUTPUT_MASK (3<<13)
#define DREF_SSC_SOURCE_DISABLE (0<<11)
#define DREF_SSC_SOURCE_ENABLE (2<<11)
-#define DREF_SSC_SOURCE_MASK (2<<11)
+#define DREF_SSC_SOURCE_MASK (3<<11)
#define DREF_NONSPREAD_SOURCE_DISABLE (0<<9)
#define DREF_NONSPREAD_CK505_ENABLE (1<<9)
#define DREF_NONSPREAD_SOURCE_ENABLE (2<<9)
-#define DREF_NONSPREAD_SOURCE_MASK (2<<9)
+#define DREF_NONSPREAD_SOURCE_MASK (3<<9)
#define DREF_SUPERSPREAD_SOURCE_DISABLE (0<<7)
#define DREF_SUPERSPREAD_SOURCE_ENABLE (2<<7)
#define DREF_SSC4_DOWNSPREAD (0<<6)
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index bd6d8d91ca9f..6eec8171a44e 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -32,11 +32,15 @@
static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 dpll_reg;
- if (pipe == PIPE_A)
- return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
- else
- return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
+ if (IS_IGDNG(dev)) {
+ dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B;
+ } else {
+ dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B;
+ }
+
+ return (I915_READ(dpll_reg) & DPLL_VCO_ENABLE);
}
static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
@@ -49,6 +53,9 @@ static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
if (!i915_pipe_enabled(dev, pipe))
return;
+ if (IS_IGDNG(dev))
+ reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
+
if (pipe == PIPE_A)
array = dev_priv->save_palette_a;
else
@@ -68,6 +75,9 @@ static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
if (!i915_pipe_enabled(dev, pipe))
return;
+ if (IS_IGDNG(dev))
+ reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
+
if (pipe == PIPE_A)
array = dev_priv->save_palette_a;
else
@@ -229,13 +239,24 @@ static void i915_save_modeset_reg(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
+ if (IS_IGDNG(dev)) {
+ dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
+ dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
+ }
+
/* Pipe & plane A info */
dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
- dev_priv->saveFPA0 = I915_READ(FPA0);
- dev_priv->saveFPA1 = I915_READ(FPA1);
- dev_priv->saveDPLL_A = I915_READ(DPLL_A);
- if (IS_I965G(dev))
+ if (IS_IGDNG(dev)) {
+ dev_priv->saveFPA0 = I915_READ(PCH_FPA0);
+ dev_priv->saveFPA1 = I915_READ(PCH_FPA1);
+ dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A);
+ } else {
+ dev_priv->saveFPA0 = I915_READ(FPA0);
+ dev_priv->saveFPA1 = I915_READ(FPA1);
+ dev_priv->saveDPLL_A = I915_READ(DPLL_A);
+ }
+ if (IS_I965G(dev) && !IS_IGDNG(dev))
dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
@@ -243,7 +264,30 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
+ if (!IS_IGDNG(dev))
+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
+
+ if (IS_IGDNG(dev)) {
+ dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
+ dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
+ dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
+ dev_priv->savePIPEA_LINK_N1 = I915_READ(PIPEA_LINK_N1);
+
+ dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL);
+ dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL);
+
+ dev_priv->savePFA_CTL_1 = I915_READ(PFA_CTL_1);
+ dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ);
+ dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS);
+
+ dev_priv->saveTRANSACONF = I915_READ(TRANSACONF);
+ dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A);
+ dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A);
+ dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A);
+ dev_priv->saveTRANS_VTOTAL_A = I915_READ(TRANS_VTOTAL_A);
+ dev_priv->saveTRANS_VBLANK_A = I915_READ(TRANS_VBLANK_A);
+ dev_priv->saveTRANS_VSYNC_A = I915_READ(TRANS_VSYNC_A);
+ }
dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
@@ -260,10 +304,16 @@ static void i915_save_modeset_reg(struct drm_device *dev)
/* Pipe & plane B info */
dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
- dev_priv->saveFPB0 = I915_READ(FPB0);
- dev_priv->saveFPB1 = I915_READ(FPB1);
- dev_priv->saveDPLL_B = I915_READ(DPLL_B);
- if (IS_I965G(dev))
+ if (IS_IGDNG(dev)) {
+ dev_priv->saveFPB0 = I915_READ(PCH_FPB0);
+ dev_priv->saveFPB1 = I915_READ(PCH_FPB1);
+ dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B);
+ } else {
+ dev_priv->saveFPB0 = I915_READ(FPB0);
+ dev_priv->saveFPB1 = I915_READ(FPB1);
+ dev_priv->saveDPLL_B = I915_READ(DPLL_B);
+ }
+ if (IS_I965G(dev) && !IS_IGDNG(dev))
dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
@@ -271,7 +321,30 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
+ if (!IS_IGDNG(dev))
+ dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
+
+ if (IS_IGDNG(dev)) {
+ dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
+ dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
+ dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
+ dev_priv->savePIPEB_LINK_N1 = I915_READ(PIPEB_LINK_N1);
+
+ dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL);
+ dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL);
+
+ dev_priv->savePFB_CTL_1 = I915_READ(PFB_CTL_1);
+ dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ);
+ dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS);
+
+ dev_priv->saveTRANSBCONF = I915_READ(TRANSBCONF);
+ dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B);
+ dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B);
+ dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B);
+ dev_priv->saveTRANS_VTOTAL_B = I915_READ(TRANS_VTOTAL_B);
+ dev_priv->saveTRANS_VBLANK_B = I915_READ(TRANS_VBLANK_B);
+ dev_priv->saveTRANS_VSYNC_B = I915_READ(TRANS_VSYNC_B);
+ }
dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
@@ -290,23 +363,46 @@ static void i915_save_modeset_reg(struct drm_device *dev)
static void i915_restore_modeset_reg(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ int dpll_a_reg, fpa0_reg, fpa1_reg;
+ int dpll_b_reg, fpb0_reg, fpb1_reg;
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
+ if (IS_IGDNG(dev)) {
+ dpll_a_reg = PCH_DPLL_A;
+ dpll_b_reg = PCH_DPLL_B;
+ fpa0_reg = PCH_FPA0;
+ fpb0_reg = PCH_FPB0;
+ fpa1_reg = PCH_FPA1;
+ fpb1_reg = PCH_FPB1;
+ } else {
+ dpll_a_reg = DPLL_A;
+ dpll_b_reg = DPLL_B;
+ fpa0_reg = FPA0;
+ fpb0_reg = FPB0;
+ fpa1_reg = FPA1;
+ fpb1_reg = FPB1;
+ }
+
+ if (IS_IGDNG(dev)) {
+ I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
+ I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
+ }
+
/* Pipe & plane A info */
/* Prime the clock */
if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
+ I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A &
~DPLL_VCO_ENABLE);
DRM_UDELAY(150);
}
- I915_WRITE(FPA0, dev_priv->saveFPA0);
- I915_WRITE(FPA1, dev_priv->saveFPA1);
+ I915_WRITE(fpa0_reg, dev_priv->saveFPA0);
+ I915_WRITE(fpa1_reg, dev_priv->saveFPA1);
/* Actually enable it */
- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
+ I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);
DRM_UDELAY(150);
- if (IS_I965G(dev))
+ if (IS_I965G(dev) && !IS_IGDNG(dev))
I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
DRM_UDELAY(150);
@@ -317,7 +413,30 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
- I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
+ if (!IS_IGDNG(dev))
+ I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
+
+ if (IS_IGDNG(dev)) {
+ I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
+ I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
+ I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
+ I915_WRITE(PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1);
+
+ I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL);
+ I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL);
+
+ I915_WRITE(PFA_CTL_1, dev_priv->savePFA_CTL_1);
+ I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ);
+ I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS);
+
+ I915_WRITE(TRANSACONF, dev_priv->saveTRANSACONF);
+ I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A);
+ I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A);
+ I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A);
+ I915_WRITE(TRANS_VTOTAL_A, dev_priv->saveTRANS_VTOTAL_A);
+ I915_WRITE(TRANS_VBLANK_A, dev_priv->saveTRANS_VBLANK_A);
+ I915_WRITE(TRANS_VSYNC_A, dev_priv->saveTRANS_VSYNC_A);
+ }
/* Restore plane info */
I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
@@ -339,16 +458,16 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
/* Pipe & plane B info */
if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
+ I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B &
~DPLL_VCO_ENABLE);
DRM_UDELAY(150);
}
- I915_WRITE(FPB0, dev_priv->saveFPB0);
- I915_WRITE(FPB1, dev_priv->saveFPB1);
+ I915_WRITE(fpb0_reg, dev_priv->saveFPB0);
+ I915_WRITE(fpb1_reg, dev_priv->saveFPB1);
/* Actually enable it */
- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
+ I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
DRM_UDELAY(150);
- if (IS_I965G(dev))
+ if (IS_I965G(dev) && !IS_IGDNG(dev))
I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
DRM_UDELAY(150);
@@ -359,7 +478,30 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
- I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
+ if (!IS_IGDNG(dev))
+ I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
+
+ if (IS_IGDNG(dev)) {
+ I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
+ I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
+ I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
+ I915_WRITE(PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1);
+
+ I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL);
+ I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL);
+
+ I915_WRITE(PFB_CTL_1, dev_priv->savePFB_CTL_1);
+ I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ);
+ I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS);
+
+ I915_WRITE(TRANSBCONF, dev_priv->saveTRANSBCONF);
+ I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B);
+ I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B);
+ I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B);
+ I915_WRITE(TRANS_VTOTAL_B, dev_priv->saveTRANS_VTOTAL_B);
+ I915_WRITE(TRANS_VBLANK_B, dev_priv->saveTRANS_VBLANK_B);
+ I915_WRITE(TRANS_VSYNC_B, dev_priv->saveTRANS_VSYNC_B);
+ }
/* Restore plane info */
I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
@@ -404,21 +546,43 @@ void i915_save_display(struct drm_device *dev)
dev_priv->saveCURSIZE = I915_READ(CURSIZE);
/* CRT state */
- dev_priv->saveADPA = I915_READ(ADPA);
+ if (IS_IGDNG(dev)) {
+ dev_priv->saveADPA = I915_READ(PCH_ADPA);
+ } else {
+ dev_priv->saveADPA = I915_READ(ADPA);
+ }
/* LVDS state */
- dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
- dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
- dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
- if (IS_I965G(dev))
- dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
- if (IS_MOBILE(dev) && !IS_I830(dev))
- dev_priv->saveLVDS = I915_READ(LVDS);
- if (!IS_I830(dev) && !IS_845G(dev))
+ if (IS_IGDNG(dev)) {
+ dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
+ dev_priv->saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
+ dev_priv->saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
+ dev_priv->saveLVDS = I915_READ(PCH_LVDS);
+ } else {
+ dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
+ dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
+ dev_priv->saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL);
+ if (IS_I965G(dev))
+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
+ if (IS_MOBILE(dev) && !IS_I830(dev))
+ dev_priv->saveLVDS = I915_READ(LVDS);
+ }
+
+ if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))
dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
- dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
- dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
- dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
+
+ if (IS_IGDNG(dev)) {
+ dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
+ dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
+ dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
+ } else {
+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
+ }
/* Display Port state */
if (SUPPORTS_INTEGRATED_DP(dev)) {
@@ -437,16 +601,23 @@ void i915_save_display(struct drm_device *dev)
/* FIXME: save TV & SDVO state */
/* FBC state */
- dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
- dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
- dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
- dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+ if (IS_GM45(dev)) {
+ dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE);
+ } else {
+ dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
+ dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
+ dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
+ dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+ }
/* VGA state */
dev_priv->saveVGA0 = I915_READ(VGA0);
dev_priv->saveVGA1 = I915_READ(VGA1);
dev_priv->saveVGA_PD = I915_READ(VGA_PD);
- dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
+ if (IS_IGDNG(dev))
+ dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL);
+ else
+ dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
i915_save_vga(dev);
}
@@ -485,22 +656,41 @@ void i915_restore_display(struct drm_device *dev)
I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
/* CRT state */
- I915_WRITE(ADPA, dev_priv->saveADPA);
+ if (IS_IGDNG(dev))
+ I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
+ else
+ I915_WRITE(ADPA, dev_priv->saveADPA);
/* LVDS state */
- if (IS_I965G(dev))
+ if (IS_I965G(dev) && !IS_IGDNG(dev))
I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
- if (IS_MOBILE(dev) && !IS_I830(dev))
+
+ if (IS_IGDNG(dev)) {
+ I915_WRITE(PCH_LVDS, dev_priv->saveLVDS);
+ } else if (IS_MOBILE(dev) && !IS_I830(dev))
I915_WRITE(LVDS, dev_priv->saveLVDS);
- if (!IS_I830(dev) && !IS_845G(dev))
+
+ if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))
I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
- I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
- I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
- I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
- I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
- I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
- I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
+ if (IS_IGDNG(dev)) {
+ I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
+ I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
+ I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
+ I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2);
+ I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
+ I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
+ I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR);
+ I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL);
+ } else {
+ I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
+ I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
+ I915_WRITE(BLC_HIST_CTL, dev_priv->saveBLC_HIST_CTL);
+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
+ I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
+ }
/* Display Port state */
if (SUPPORTS_INTEGRATED_DP(dev)) {
@@ -511,13 +701,22 @@ void i915_restore_display(struct drm_device *dev)
/* FIXME: restore TV & SDVO state */
/* FBC info */
- I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
- I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
- I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
- I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
+ if (IS_GM45(dev)) {
+ g4x_disable_fbc(dev);
+ I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
+ } else {
+ i8xx_disable_fbc(dev);
+ I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
+ I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
+ I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
+ I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
+ }
/* VGA state */
- I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
+ if (IS_IGDNG(dev))
+ I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
+ else
+ I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
I915_WRITE(VGA0, dev_priv->saveVGA0);
I915_WRITE(VGA1, dev_priv->saveVGA1);
I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
@@ -543,8 +742,17 @@ int i915_save_state(struct drm_device *dev)
i915_save_display(dev);
/* Interrupt state */
- dev_priv->saveIER = I915_READ(IER);
- dev_priv->saveIMR = I915_READ(IMR);
+ if (IS_IGDNG(dev)) {
+ dev_priv->saveDEIER = I915_READ(DEIER);
+ dev_priv->saveDEIMR = I915_READ(DEIMR);
+ dev_priv->saveGTIER = I915_READ(GTIER);
+ dev_priv->saveGTIMR = I915_READ(GTIMR);
+ dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR);
+ dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR);
+ } else {
+ dev_priv->saveIER = I915_READ(IER);
+ dev_priv->saveIMR = I915_READ(IMR);
+ }
/* Clock gating state */
dev_priv->saveD_STATE = I915_READ(D_STATE);
@@ -609,8 +817,17 @@ int i915_restore_state(struct drm_device *dev)
i915_restore_display(dev);
/* Interrupt state */
- I915_WRITE (IER, dev_priv->saveIER);
- I915_WRITE (IMR, dev_priv->saveIMR);
+ if (IS_IGDNG(dev)) {
+ I915_WRITE(DEIER, dev_priv->saveDEIER);
+ I915_WRITE(DEIMR, dev_priv->saveDEIMR);
+ I915_WRITE(GTIER, dev_priv->saveGTIER);
+ I915_WRITE(GTIMR, dev_priv->saveGTIMR);
+ I915_WRITE(FDI_RXA_IMR, dev_priv->saveFDI_RXA_IMR);
+ I915_WRITE(FDI_RXB_IMR, dev_priv->saveFDI_RXB_IMR);
+ } else {
+ I915_WRITE (IER, dev_priv->saveIER);
+ I915_WRITE (IMR, dev_priv->saveIMR);
+ }
/* Clock gating state */
I915_WRITE (D_STATE, dev_priv->saveD_STATE);
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4337414846b6..96cd256e60e6 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -351,20 +351,18 @@ parse_driver_features(struct drm_i915_private *dev_priv,
struct drm_device *dev = dev_priv->dev;
struct bdb_driver_features *driver;
- /* set default for chips without eDP */
- if (!SUPPORTS_EDP(dev)) {
- dev_priv->edp_support = 0;
- return;
- }
-
driver = find_section(bdb, BDB_DRIVER_FEATURES);
if (!driver)
return;
- if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
+ if (driver && SUPPORTS_EDP(dev) &&
+ driver->lvds_config == BDB_DRIVER_FEATURE_EDP) {
dev_priv->edp_support = 1;
+ } else {
+ dev_priv->edp_support = 0;
+ }
- if (driver->dual_frequency)
+ if (driver && driver->dual_frequency)
dev_priv->render_reclock_avail = true;
}
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 212e22740fc1..e5051446c48e 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -262,8 +262,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
} while (time_after(timeout, jiffies));
}
- if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
- CRT_HOTPLUG_MONITOR_COLOR)
+ if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
+ CRT_HOTPLUG_MONITOR_NONE)
return true;
return false;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3c14240cc002..099f420de57a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -863,10 +863,8 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
intel_clock_t clock;
- int max_n;
- bool found;
int err_most = 47;
- found = false;
+ int err_min = 10000;
/* eDP has only 2 clock choice, no n/m/p setting */
if (HAS_eDP)
@@ -890,10 +888,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
}
memset(best_clock, 0, sizeof(*best_clock));
- max_n = limit->n.max;
for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
/* based on hardware requriment prefer smaller n to precision */
- for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+ for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
/* based on hardware requirment prefere larger m1,m2 */
for (clock.m1 = limit->m1.max;
clock.m1 >= limit->m1.min; clock.m1--) {
@@ -907,18 +904,18 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
this_err = abs((10000 - (target*10000/clock.dot)));
if (this_err < err_most) {
*best_clock = clock;
- err_most = this_err;
- max_n = clock.n;
- found = true;
/* found on first matching */
goto out;
+ } else if (this_err < err_min) {
+ *best_clock = clock;
+ err_min = this_err;
}
}
}
}
}
out:
- return found;
+ return true;
}
/* DisplayPort has only two frequencies, 162MHz and 270MHz */
@@ -943,6 +940,7 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2);
clock.p = (clock.p1 * clock.p2);
clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p;
+ clock.vco = 0;
memcpy(best_clock, &clock, sizeof(intel_clock_t));
return true;
}
@@ -1260,9 +1258,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
return ret;
}
- /* Pre-i965 needs to install a fence for tiled scan-out */
- if (!IS_I965G(dev) &&
- obj_priv->fence_reg == I915_FENCE_REG_NONE &&
+ /* Install a fence for tiled scan-out. Pre-i965 always needs a fence,
+ * whereas 965+ only requires a fence if using framebuffer compression.
+ * For simplicity, we always install a fence as the cost is not that onerous.
+ */
+ if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
obj_priv->tiling_mode != I915_TILING_NONE) {
ret = i915_gem_object_get_fence_reg(obj);
if (ret != 0) {
@@ -1513,7 +1513,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
/* Enable panel fitting for LVDS */
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
temp = I915_READ(pf_ctl_reg);
- I915_WRITE(pf_ctl_reg, temp | PF_ENABLE);
+ I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3);
/* currently full aspect */
I915_WRITE(pf_win_pos, 0);
@@ -1801,6 +1801,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_ON:
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
+ intel_update_watermarks(dev);
+
/* Enable the DPLL */
temp = I915_READ(dpll_reg);
if ((temp & DPLL_VCO_ENABLE) == 0) {
@@ -1838,7 +1840,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
/* Give the overlay scaler a chance to enable if it's on this pipe */
//intel_crtc_dpms_video(crtc, true); TODO
- intel_update_watermarks(dev);
break;
case DRM_MODE_DPMS_OFF:
intel_update_watermarks(dev);
@@ -2082,7 +2083,7 @@ fdi_reduce_ratio(u32 *num, u32 *den)
#define LINK_N 0x80000
static void
-igdng_compute_m_n(int bytes_per_pixel, int nlanes,
+igdng_compute_m_n(int bits_per_pixel, int nlanes,
int pixel_clock, int link_clock,
struct fdi_m_n *m_n)
{
@@ -2092,7 +2093,8 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes,
temp = (u64) DATA_N * pixel_clock;
temp = div_u64(temp, link_clock);
- m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes);
+ m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes);
+ m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */
m_n->gmch_n = DATA_N;
fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
@@ -2140,6 +2142,13 @@ static struct intel_watermark_params igd_cursor_hplloff_wm = {
IGD_CURSOR_GUARD_WM,
IGD_FIFO_LINE_SIZE
};
+static struct intel_watermark_params g4x_wm_info = {
+ G4X_FIFO_SIZE,
+ G4X_MAX_WM,
+ G4X_MAX_WM,
+ 2,
+ G4X_FIFO_LINE_SIZE,
+};
static struct intel_watermark_params i945_wm_info = {
I945_FIFO_SIZE,
I915_MAX_WM,
@@ -2430,17 +2439,74 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane)
return size;
}
-static void g4x_update_wm(struct drm_device *dev, int unused, int unused2,
- int unused3, int unused4)
+static void g4x_update_wm(struct drm_device *dev, int planea_clock,
+ int planeb_clock, int sr_hdisplay, int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 fw_blc_self = I915_READ(FW_BLC_SELF);
+ int total_size, cacheline_size;
+ int planea_wm, planeb_wm, cursora_wm, cursorb_wm, cursor_sr;
+ struct intel_watermark_params planea_params, planeb_params;
+ unsigned long line_time_us;
+ int sr_clock, sr_entries = 0, entries_required;
- if (i915_powersave)
- fw_blc_self |= FW_BLC_SELF_EN;
- else
- fw_blc_self &= ~FW_BLC_SELF_EN;
- I915_WRITE(FW_BLC_SELF, fw_blc_self);
+ /* Create copies of the base settings for each pipe */
+ planea_params = planeb_params = g4x_wm_info;
+
+ /* Grab a couple of global values before we overwrite them */
+ total_size = planea_params.fifo_size;
+ cacheline_size = planea_params.cacheline_size;
+
+ /*
+ * Note: we need to make sure we don't overflow for various clock &
+ * latency values.
+ * clocks go from a few thousand to several hundred thousand.
+ * latency is usually a few thousand
+ */
+ entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) /
+ 1000;
+ entries_required /= G4X_FIFO_LINE_SIZE;
+ planea_wm = entries_required + planea_params.guard_size;
+
+ entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) /
+ 1000;
+ entries_required /= G4X_FIFO_LINE_SIZE;
+ planeb_wm = entries_required + planeb_params.guard_size;
+
+ cursora_wm = cursorb_wm = 16;
+ cursor_sr = 32;
+
+ DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
+
+ /* Calc sr entries for one plane configs */
+ if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+ /* self-refresh has much higher latency */
+ const static int sr_latency_ns = 12000;
+
+ sr_clock = planea_clock ? planea_clock : planeb_clock;
+ line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+
+ /* Use ns/us then divide to preserve precision */
+ sr_entries = (((sr_latency_ns / line_time_us) + 1) *
+ pixel_size * sr_hdisplay) / 1000;
+ sr_entries = roundup(sr_entries / cacheline_size, 1);
+ DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+ I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+ }
+
+ DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n",
+ planea_wm, planeb_wm, sr_entries);
+
+ planea_wm &= 0x3f;
+ planeb_wm &= 0x3f;
+
+ I915_WRITE(DSPFW1, (sr_entries << DSPFW_SR_SHIFT) |
+ (cursorb_wm << DSPFW_CURSORB_SHIFT) |
+ (planeb_wm << DSPFW_PLANEB_SHIFT) | planea_wm);
+ I915_WRITE(DSPFW2, (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) |
+ (cursora_wm << DSPFW_CURSORA_SHIFT));
+ /* HPLL off in SR has some issues on G4x... disable it */
+ I915_WRITE(DSPFW3, (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) |
+ (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
}
static void i965_update_wm(struct drm_device *dev, int unused, int unused2,
@@ -2586,6 +2652,9 @@ static void intel_update_watermarks(struct drm_device *dev)
unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
int enabled = 0, pixel_size = 0;
+ if (!dev_priv->display.update_wm)
+ return;
+
/* Get the clock config from both planes */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
intel_crtc = to_intel_crtc(crtc);
@@ -2763,7 +2832,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
/* FDI link */
if (IS_IGDNG(dev)) {
- int lane, link_bw;
+ int lane, link_bw, bpp;
/* eDP doesn't require FDI link, so just set DP M/N
according to current link config */
if (is_edp) {
@@ -2782,10 +2851,72 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
lane = 4;
link_bw = 270000;
}
- igdng_compute_m_n(3, lane, target_clock,
+
+ /* determine panel color depth */
+ temp = I915_READ(pipeconf_reg);
+
+ switch (temp & PIPE_BPC_MASK) {
+ case PIPE_8BPC:
+ bpp = 24;
+ break;
+ case PIPE_10BPC:
+ bpp = 30;
+ break;
+ case PIPE_6BPC:
+ bpp = 18;
+ break;
+ case PIPE_12BPC:
+ bpp = 36;
+ break;
+ default:
+ DRM_ERROR("unknown pipe bpc value\n");
+ bpp = 24;
+ }
+
+ igdng_compute_m_n(bpp, lane, target_clock,
link_bw, &m_n);
}
+ /* Ironlake: try to setup display ref clock before DPLL
+ * enabling. This is only under driver's control after
+ * PCH B stepping, previous chipset stepping should be
+ * ignoring this setting.
+ */
+ if (IS_IGDNG(dev)) {
+ temp = I915_READ(PCH_DREF_CONTROL);
+ /* Always enable nonspread source */
+ temp &= ~DREF_NONSPREAD_SOURCE_MASK;
+ temp |= DREF_NONSPREAD_SOURCE_ENABLE;
+ I915_WRITE(PCH_DREF_CONTROL, temp);
+ POSTING_READ(PCH_DREF_CONTROL);
+
+ temp &= ~DREF_SSC_SOURCE_MASK;
+ temp |= DREF_SSC_SOURCE_ENABLE;
+ I915_WRITE(PCH_DREF_CONTROL, temp);
+ POSTING_READ(PCH_DREF_CONTROL);
+
+ udelay(200);
+
+ if (is_edp) {
+ if (dev_priv->lvds_use_ssc) {
+ temp |= DREF_SSC1_ENABLE;
+ I915_WRITE(PCH_DREF_CONTROL, temp);
+ POSTING_READ(PCH_DREF_CONTROL);
+
+ udelay(200);
+
+ temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+ temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
+ I915_WRITE(PCH_DREF_CONTROL, temp);
+ POSTING_READ(PCH_DREF_CONTROL);
+ } else {
+ temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
+ I915_WRITE(PCH_DREF_CONTROL, temp);
+ POSTING_READ(PCH_DREF_CONTROL);
+ }
+ }
+ }
+
if (IS_IGD(dev)) {
fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
if (has_reduced_clock)
@@ -2936,6 +3067,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
lvds = I915_READ(lvds_reg);
lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
+ /* set the corresponsding LVDS_BORDER bit */
+ lvds |= dev_priv->lvds_border_bits;
/* Set the B0-B3 data pairs corresponding to whether we're going to
* set the DPLLs for dual-channel mode or not.
*/
@@ -4124,7 +4257,9 @@ void intel_init_clock_gating(struct drm_device *dev)
* Disable clock gating reported to work incorrectly according to the
* specs, but enable as much else as we can.
*/
- if (IS_G4X(dev)) {
+ if (IS_IGDNG(dev)) {
+ return;
+ } else if (IS_G4X(dev)) {
uint32_t dspclk_gate;
I915_WRITE(RENCLK_GATE_D1, 0);
I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
@@ -4212,7 +4347,9 @@ static void intel_init_display(struct drm_device *dev)
i830_get_display_clock_speed;
/* For FIFO watermark updates */
- if (IS_G4X(dev))
+ if (IS_IGDNG(dev))
+ dev_priv->display.update_wm = NULL;
+ else if (IS_G4X(dev))
dev_priv->display.update_wm = g4x_update_wm;
else if (IS_I965G(dev))
dev_priv->display.update_wm = i965_update_wm;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f4856a510476..d83447557f9b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -400,7 +400,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
{
struct intel_dp_priv *dp_priv = intel_output->dev_priv;
- DRM_ERROR("i2c_init %s\n", name);
+ DRM_DEBUG_KMS("i2c_init %s\n", name);
dp_priv->algo.running = false;
dp_priv->algo.address = 0;
dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 663ab6de0b58..c33451aec1bd 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -77,14 +77,32 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
u32 temp;
- if (mode != DRM_MODE_DPMS_ON) {
- temp = I915_READ(hdmi_priv->sdvox_reg);
+ temp = I915_READ(hdmi_priv->sdvox_reg);
+
+ /* HW workaround, need to toggle enable bit off and on for 12bpc, but
+ * we do this anyway which shows more stable in testing.
+ */
+ if (IS_IGDNG(dev)) {
I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
+ POSTING_READ(hdmi_priv->sdvox_reg);
+ }
+
+ if (mode != DRM_MODE_DPMS_ON) {
+ temp &= ~SDVO_ENABLE;
} else {
- temp = I915_READ(hdmi_priv->sdvox_reg);
- I915_WRITE(hdmi_priv->sdvox_reg, temp | SDVO_ENABLE);
+ temp |= SDVO_ENABLE;
}
+
+ I915_WRITE(hdmi_priv->sdvox_reg, temp);
POSTING_READ(hdmi_priv->sdvox_reg);
+
+ /* HW workaround, need to write this twice for issue that may result
+ * in first write getting masked.
+ */
+ if (IS_IGDNG(dev)) {
+ I915_WRITE(hdmi_priv->sdvox_reg, temp);
+ POSTING_READ(hdmi_priv->sdvox_reg);
+ }
}
static void intel_hdmi_save(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 98ae3d73577e..05598ae10c4b 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -380,7 +380,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
adjusted_mode->crtc_vblank_start + vsync_pos;
/* keep the vsync width constant */
adjusted_mode->crtc_vsync_end =
- adjusted_mode->crtc_vblank_start + vsync_width;
+ adjusted_mode->crtc_vsync_start + vsync_width;
border = 1;
break;
case DRM_MODE_SCALE_ASPECT:
@@ -526,6 +526,14 @@ out:
lvds_priv->pfit_control = pfit_control;
lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios;
/*
+ * When there exists the border, it means that the LVDS_BORDR
+ * should be enabled.
+ */
+ if (border)
+ dev_priv->lvds_border_bits |= LVDS_BORDER_ENABLE;
+ else
+ dev_priv->lvds_border_bits &= ~(LVDS_BORDER_ENABLE);
+ /*
* XXX: It would be nice to support lower refresh rates on the
* panels to reduce power consumption, and perhaps match the
* user's requested refresh rate.
@@ -656,6 +664,15 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
return 0;
}
+/*
+ * Lid events. Note the use of 'modeset_on_lid':
+ * - we set it on lid close, and reset it on open
+ * - we use it as a "only once" bit (ie we ignore
+ * duplicate events where it was already properly
+ * set/reset)
+ * - the suspend/resume paths will also set it to
+ * zero, since they restore the mode ("lid open").
+ */
static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
void *unused)
{
@@ -663,13 +680,19 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
container_of(nb, struct drm_i915_private, lid_notifier);
struct drm_device *dev = dev_priv->dev;
- if (acpi_lid_open() && !dev_priv->suspended) {
- mutex_lock(&dev->mode_config.mutex);
- drm_helper_resume_force_mode(dev);
- mutex_unlock(&dev->mode_config.mutex);
+ if (!acpi_lid_open()) {
+ dev_priv->modeset_on_lid = 1;
+ return NOTIFY_OK;
}
- drm_sysfs_hotplug_event(dev_priv->dev);
+ if (!dev_priv->modeset_on_lid)
+ return NOTIFY_OK;
+
+ dev_priv->modeset_on_lid = 0;
+
+ mutex_lock(&dev->mode_config.mutex);
+ drm_helper_resume_force_mode(dev);
+ mutex_unlock(&dev->mode_config.mutex);
return NOTIFY_OK;
}
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 09a28923f46e..b5713eedd6e1 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \
radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
- r600_blit_kms.o
+ r600_blit_kms.o radeon_pm.o
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index 901befe03da2..d67c42555ab9 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -107,6 +107,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
base += 3;
break;
case ATOM_IIO_WRITE:
+ (void)ctx->card->reg_read(ctx->card, CU16(base + 1));
ctx->card->reg_write(ctx->card, CU16(base + 1), temp);
base += 3;
break;
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
index 5d402086bc47..c11ddddfb3b6 100644
--- a/drivers/gpu/drm/radeon/atombios.h
+++ b/drivers/gpu/drm/radeon/atombios.h
@@ -2314,7 +2314,7 @@ typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT {
UCHAR ucSS_Step;
UCHAR ucSS_Delay;
UCHAR ucSS_Id;
- UCHAR ucRecommandedRef_Div;
+ UCHAR ucRecommendedRef_Div;
UCHAR ucSS_Range; /* it was reserved for V11 */
} ATOM_SPREAD_SPECTRUM_ASSIGNMENT;
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 14fa9701aeb3..c15287a590ff 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -31,10 +31,6 @@
#include "atom.h"
#include "atom-bits.h"
-/* evil but including atombios.h is much worse */
-bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
- SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
- int32_t *pixel_clock);
static void atombios_overscan_setup(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -248,18 +244,18 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
+ atombios_enable_crtc(crtc, 1);
if (ASIC_IS_DCE3(rdev))
atombios_enable_crtc_memreq(crtc, 1);
- atombios_enable_crtc(crtc, 1);
atombios_blank_crtc(crtc, 0);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
atombios_blank_crtc(crtc, 1);
- atombios_enable_crtc(crtc, 0);
if (ASIC_IS_DCE3(rdev))
atombios_enable_crtc_memreq(crtc, 0);
+ atombios_enable_crtc(crtc, 0);
break;
}
@@ -270,59 +266,147 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
static void
atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
- SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param)
+ struct drm_display_mode *mode)
{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
- SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param;
+ SET_CRTC_USING_DTD_TIMING_PARAMETERS args;
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
+ u16 misc = 0;
- conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size);
- conv_param.usH_Blanking_Time =
- cpu_to_le16(crtc_param->usH_Blanking_Time);
- conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size);
- conv_param.usV_Blanking_Time =
- cpu_to_le16(crtc_param->usV_Blanking_Time);
- conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset);
- conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
- conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset);
- conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
- conv_param.susModeMiscInfo.usAccess =
- cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
- conv_param.ucCRTC = crtc_param->ucCRTC;
+ memset(&args, 0, sizeof(args));
+ args.usH_Size = cpu_to_le16(mode->crtc_hdisplay);
+ args.usH_Blanking_Time =
+ cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay);
+ args.usV_Size = cpu_to_le16(mode->crtc_vdisplay);
+ args.usV_Blanking_Time =
+ cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay);
+ args.usH_SyncOffset =
+ cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay);
+ args.usH_SyncWidth =
+ cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
+ args.usV_SyncOffset =
+ cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay);
+ args.usV_SyncWidth =
+ cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
+ /*args.ucH_Border = mode->hborder;*/
+ /*args.ucV_Border = mode->vborder;*/
+
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ misc |= ATOM_VSYNC_POLARITY;
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ misc |= ATOM_HSYNC_POLARITY;
+ if (mode->flags & DRM_MODE_FLAG_CSYNC)
+ misc |= ATOM_COMPOSITESYNC;
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ misc |= ATOM_INTERLACE;
+ if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+ misc |= ATOM_DOUBLE_CLOCK_MODE;
+
+ args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
+ args.ucCRTC = radeon_crtc->crtc_id;
printk("executing set crtc dtd timing\n");
- atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param);
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
-void atombios_crtc_set_timing(struct drm_crtc *crtc,
- SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *
- crtc_param)
+static void atombios_crtc_set_timing(struct drm_crtc *crtc,
+ struct drm_display_mode *mode)
{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
- SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param;
+ SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args;
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
+ u16 misc = 0;
- conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total);
- conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp);
- conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart);
- conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
- conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total);
- conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp);
- conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart);
- conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
- conv_param.susModeMiscInfo.usAccess =
- cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
- conv_param.ucCRTC = crtc_param->ucCRTC;
- conv_param.ucOverscanRight = crtc_param->ucOverscanRight;
- conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft;
- conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom;
- conv_param.ucOverscanTop = crtc_param->ucOverscanTop;
- conv_param.ucReserved = crtc_param->ucReserved;
+ memset(&args, 0, sizeof(args));
+ args.usH_Total = cpu_to_le16(mode->crtc_htotal);
+ args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay);
+ args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start);
+ args.usH_SyncWidth =
+ cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
+ args.usV_Total = cpu_to_le16(mode->crtc_vtotal);
+ args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay);
+ args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start);
+ args.usV_SyncWidth =
+ cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
+
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ misc |= ATOM_VSYNC_POLARITY;
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ misc |= ATOM_HSYNC_POLARITY;
+ if (mode->flags & DRM_MODE_FLAG_CSYNC)
+ misc |= ATOM_COMPOSITESYNC;
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ misc |= ATOM_INTERLACE;
+ if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+ misc |= ATOM_DOUBLE_CLOCK_MODE;
+
+ args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
+ args.ucCRTC = radeon_crtc->crtc_id;
printk("executing set crtc timing\n");
- atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param);
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+static void atombios_set_ss(struct drm_crtc *crtc, int enable)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_encoder *encoder = NULL;
+ struct radeon_encoder *radeon_encoder = NULL;
+ struct radeon_encoder_atom_dig *dig = NULL;
+ int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
+ ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION args;
+ ENABLE_LVDS_SS_PARAMETERS legacy_args;
+ uint16_t percentage = 0;
+ uint8_t type = 0, step = 0, delay = 0, range = 0;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (encoder->crtc == crtc) {
+ radeon_encoder = to_radeon_encoder(encoder);
+ /* only enable spread spectrum on LVDS */
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+ dig = radeon_encoder->enc_priv;
+ if (dig && dig->ss) {
+ percentage = dig->ss->percentage;
+ type = dig->ss->type;
+ step = dig->ss->step;
+ delay = dig->ss->delay;
+ range = dig->ss->range;
+ } else if (enable)
+ return;
+ } else if (enable)
+ return;
+ break;
+ }
+ }
+
+ if (!radeon_encoder)
+ return;
+
+ if (ASIC_IS_AVIVO(rdev)) {
+ memset(&args, 0, sizeof(args));
+ args.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
+ args.ucSpreadSpectrumType = type;
+ args.ucSpreadSpectrumStep = step;
+ args.ucSpreadSpectrumDelay = delay;
+ args.ucSpreadSpectrumRange = range;
+ args.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+ args.ucEnable = enable;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ } else {
+ memset(&legacy_args, 0, sizeof(legacy_args));
+ legacy_args.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
+ legacy_args.ucSpreadSpectrumType = type;
+ legacy_args.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
+ legacy_args.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
+ legacy_args.ucEnable = enable;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&legacy_args);
+ }
}
void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
@@ -333,12 +417,13 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
struct drm_encoder *encoder = NULL;
struct radeon_encoder *radeon_encoder = NULL;
uint8_t frev, crev;
- int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
+ int index;
SET_PIXEL_CLOCK_PS_ALLOCATION args;
PIXEL_CLOCK_PARAMETERS *spc1_ptr;
PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
- uint32_t sclock = mode->clock;
+ uint32_t pll_clock = mode->clock;
+ uint32_t adjusted_clock;
uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
struct radeon_pll *pll;
int pll_flags = 0;
@@ -346,8 +431,6 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
memset(&args, 0, sizeof(args));
if (ASIC_IS_AVIVO(rdev)) {
- uint32_t ss_cntl;
-
if ((rdev->family == CHIP_RS600) ||
(rdev->family == CHIP_RS690) ||
(rdev->family == CHIP_RS740))
@@ -358,15 +441,6 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
else
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
-
- /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */
- if (radeon_crtc->crtc_id == 0) {
- ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
- WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1);
- } else {
- ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
- WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1);
- }
} else {
pll_flags |= RADEON_PLL_LEGACY;
@@ -393,14 +467,43 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
}
}
+ /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
+ * accordingly based on the encoder/transmitter to work around
+ * special hw requirements.
+ */
+ if (ASIC_IS_DCE3(rdev)) {
+ ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args;
+
+ if (!encoder)
+ return;
+
+ memset(&adjust_pll_args, 0, sizeof(adjust_pll_args));
+ adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10);
+ adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id;
+ adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder);
+
+ index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
+ atom_execute_table(rdev->mode_info.atom_context,
+ index, (uint32_t *)&adjust_pll_args);
+ adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10;
+ } else {
+ /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
+ if (ASIC_IS_AVIVO(rdev) &&
+ (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1))
+ adjusted_clock = mode->clock * 2;
+ else
+ adjusted_clock = mode->clock;
+ }
+
if (radeon_crtc->crtc_id == 0)
pll = &rdev->clock.p1pll;
else
pll = &rdev->clock.p2pll;
- radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div,
+ radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags);
+ index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
&crev);
@@ -409,7 +512,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
switch (crev) {
case 1:
spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput;
- spc1_ptr->usPixelClock = cpu_to_le16(sclock);
+ spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
spc1_ptr->usRefDiv = cpu_to_le16(ref_div);
spc1_ptr->usFbDiv = cpu_to_le16(fb_div);
spc1_ptr->ucFracFbDiv = frac_fb_div;
@@ -422,7 +525,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
case 2:
spc2_ptr =
(PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput;
- spc2_ptr->usPixelClock = cpu_to_le16(sclock);
+ spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
spc2_ptr->ucFracFbDiv = frac_fb_div;
@@ -437,7 +540,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
return;
spc3_ptr =
(PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput;
- spc3_ptr->usPixelClock = cpu_to_le16(sclock);
+ spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
spc3_ptr->ucFracFbDiv = frac_fb_div;
@@ -527,6 +630,16 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
WREG32(AVIVO_D1VGA_CONTROL, 0);
else
WREG32(AVIVO_D2VGA_CONTROL, 0);
+
+ if (rdev->family >= CHIP_RV770) {
+ if (radeon_crtc->crtc_id) {
+ WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
+ WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
+ } else {
+ WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
+ WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
+ }
+ }
WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
(u32) fb_location);
WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
@@ -563,6 +676,10 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
radeon_fb = to_radeon_framebuffer(old_fb);
radeon_gem_object_unpin(radeon_fb->obj);
}
+
+ /* Bytes per pixel may have changed */
+ radeon_bandwidth_update(rdev);
+
return 0;
}
@@ -574,134 +691,24 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
- struct drm_encoder *encoder;
- SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
- int need_tv_timings = 0;
- bool ret;
/* TODO color tiling */
- memset(&crtc_timing, 0, sizeof(crtc_timing));
-
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- /* find tv std */
- if (encoder->crtc == crtc) {
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-
- if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
- struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
- if (tv_dac) {
- if (tv_dac->tv_std == TV_STD_NTSC ||
- tv_dac->tv_std == TV_STD_NTSC_J ||
- tv_dac->tv_std == TV_STD_PAL_M)
- need_tv_timings = 1;
- else
- need_tv_timings = 2;
- break;
- }
- }
- }
- }
-
- crtc_timing.ucCRTC = radeon_crtc->crtc_id;
- if (need_tv_timings) {
- ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1,
- &crtc_timing, &adjusted_mode->clock);
- if (ret == false)
- need_tv_timings = 0;
- }
-
- if (!need_tv_timings) {
- crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
- crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
- crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
- crtc_timing.usH_SyncWidth =
- adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
-
- crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
- crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
- crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
- crtc_timing.usV_SyncWidth =
- adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
- crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
- crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
- crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
- crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
- crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
- }
+ atombios_set_ss(crtc, 0);
atombios_crtc_set_pll(crtc, adjusted_mode);
- atombios_crtc_set_timing(crtc, &crtc_timing);
+ atombios_set_ss(crtc, 1);
+ atombios_crtc_set_timing(crtc, adjusted_mode);
if (ASIC_IS_AVIVO(rdev))
atombios_crtc_set_base(crtc, x, y, old_fb);
else {
- if (radeon_crtc->crtc_id == 0) {
- SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing;
- memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing));
-
- /* setup FP shadow regs on R4xx */
- crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id;
- crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay;
- crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay;
- crtc_dtd_timing.usH_Blanking_Time =
- adjusted_mode->crtc_hblank_end -
- adjusted_mode->crtc_hdisplay;
- crtc_dtd_timing.usV_Blanking_Time =
- adjusted_mode->crtc_vblank_end -
- adjusted_mode->crtc_vdisplay;
- crtc_dtd_timing.usH_SyncOffset =
- adjusted_mode->crtc_hsync_start -
- adjusted_mode->crtc_hdisplay;
- crtc_dtd_timing.usV_SyncOffset =
- adjusted_mode->crtc_vsync_start -
- adjusted_mode->crtc_vdisplay;
- crtc_dtd_timing.usH_SyncWidth =
- adjusted_mode->crtc_hsync_end -
- adjusted_mode->crtc_hsync_start;
- crtc_dtd_timing.usV_SyncWidth =
- adjusted_mode->crtc_vsync_end -
- adjusted_mode->crtc_vsync_start;
- /* crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; */
- /* crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; */
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
- crtc_dtd_timing.susModeMiscInfo.usAccess |=
- ATOM_VSYNC_POLARITY;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
- crtc_dtd_timing.susModeMiscInfo.usAccess |=
- ATOM_HSYNC_POLARITY;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
- crtc_dtd_timing.susModeMiscInfo.usAccess |=
- ATOM_COMPOSITESYNC;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
- crtc_dtd_timing.susModeMiscInfo.usAccess |=
- ATOM_INTERLACE;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
- crtc_dtd_timing.susModeMiscInfo.usAccess |=
- ATOM_DOUBLE_CLOCK_MODE;
-
- atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing);
- }
+ if (radeon_crtc->crtc_id == 0)
+ atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
radeon_crtc_set_base(crtc, x, y, old_fb);
radeon_legacy_atom_set_surface(crtc);
}
atombios_overscan_setup(crtc, mode, adjusted_mode);
atombios_scaler_setup(crtc);
- radeon_bandwidth_update(rdev);
return 0;
}
diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c
index fb211e585dea..0d79577c1576 100644
--- a/drivers/gpu/drm/radeon/mkregtable.c
+++ b/drivers/gpu/drm/radeon/mkregtable.c
@@ -561,7 +561,7 @@ struct table {
char *gpu_prefix;
};
-struct offset *offset_new(unsigned o)
+static struct offset *offset_new(unsigned o)
{
struct offset *offset;
@@ -573,12 +573,12 @@ struct offset *offset_new(unsigned o)
return offset;
}
-void table_offset_add(struct table *t, struct offset *offset)
+static void table_offset_add(struct table *t, struct offset *offset)
{
list_add_tail(&offset->list, &t->offsets);
}
-void table_init(struct table *t)
+static void table_init(struct table *t)
{
INIT_LIST_HEAD(&t->offsets);
t->offset_max = 0;
@@ -586,7 +586,7 @@ void table_init(struct table *t)
t->table = NULL;
}
-void table_print(struct table *t)
+static void table_print(struct table *t)
{
unsigned nlloop, i, j, n, c, id;
@@ -611,7 +611,7 @@ void table_print(struct table *t)
printf("};\n");
}
-int table_build(struct table *t)
+static int table_build(struct table *t)
{
struct offset *offset;
unsigned i, m;
@@ -631,7 +631,7 @@ int table_build(struct table *t)
}
static char gpu_name[10];
-int parser_auth(struct table *t, const char *filename)
+static int parser_auth(struct table *t, const char *filename)
{
FILE *file;
regex_t mask_rex;
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 161094c07d94..c9e93eabcf16 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -186,7 +186,7 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
int r100_irq_process(struct radeon_device *rdev)
{
- uint32_t status;
+ uint32_t status, msi_rearm;
status = r100_irq_ack(rdev);
if (!status) {
@@ -209,6 +209,21 @@ int r100_irq_process(struct radeon_device *rdev)
}
status = r100_irq_ack(rdev);
}
+ if (rdev->msi_enabled) {
+ switch (rdev->family) {
+ case CHIP_RS400:
+ case CHIP_RS480:
+ msi_rearm = RREG32(RADEON_AIC_CNTL) & ~RS400_MSI_REARM;
+ WREG32(RADEON_AIC_CNTL, msi_rearm);
+ WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM);
+ break;
+ default:
+ msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
+ WREG32(RADEON_MSI_REARM_EN, msi_rearm);
+ WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+ break;
+ }
+ }
return IRQ_HANDLED;
}
@@ -240,7 +255,7 @@ int r100_wb_init(struct radeon_device *rdev)
int r;
if (rdev->wb.wb_obj == NULL) {
- r = radeon_object_create(rdev, NULL, 4096,
+ r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
true,
RADEON_GEM_DOMAIN_GTT,
false, &rdev->wb.wb_obj);
@@ -563,19 +578,19 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
indirect1_start = 16;
/* cp setup */
WREG32(0x718, pre_write_timer | (pre_write_limit << 28));
- WREG32(RADEON_CP_RB_CNTL,
-#ifdef __BIG_ENDIAN
- RADEON_BUF_SWAP_32BIT |
-#endif
- REG_SET(RADEON_RB_BUFSZ, rb_bufsz) |
+ tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) |
REG_SET(RADEON_RB_BLKSZ, rb_blksz) |
REG_SET(RADEON_MAX_FETCH, max_fetch) |
RADEON_RB_NO_UPDATE);
+#ifdef __BIG_ENDIAN
+ tmp |= RADEON_BUF_SWAP_32BIT;
+#endif
+ WREG32(RADEON_CP_RB_CNTL, tmp);
+
/* Set ring address */
DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr);
WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr);
/* Force read & write ptr to 0 */
- tmp = RREG32(RADEON_CP_RB_CNTL);
WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
WREG32(RADEON_CP_RB_RPTR_WR, 0);
WREG32(RADEON_CP_RB_WPTR, 0);
@@ -2364,7 +2379,7 @@ void r100_bandwidth_update(struct radeon_device *rdev)
/*
Find the total latency for the display data.
*/
- disp_latency_overhead.full = rfixed_const(80);
+ disp_latency_overhead.full = rfixed_const(8);
disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff);
mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full;
mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full;
@@ -2562,8 +2577,11 @@ void r100_bandwidth_update(struct radeon_device *rdev)
static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
{
DRM_ERROR("pitch %d\n", t->pitch);
+ DRM_ERROR("use_pitch %d\n", t->use_pitch);
DRM_ERROR("width %d\n", t->width);
+ DRM_ERROR("width_11 %d\n", t->width_11);
DRM_ERROR("height %d\n", t->height);
+ DRM_ERROR("height_11 %d\n", t->height_11);
DRM_ERROR("num levels %d\n", t->num_levels);
DRM_ERROR("depth %d\n", t->txdepth);
DRM_ERROR("bpp %d\n", t->cpp);
@@ -2623,15 +2641,17 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
else
w = track->textures[u].pitch / (1 << i);
} else {
- w = track->textures[u].width / (1 << i);
+ w = track->textures[u].width;
if (rdev->family >= CHIP_RV515)
w |= track->textures[u].width_11;
+ w = w / (1 << i);
if (track->textures[u].roundup_w)
w = roundup_pow_of_two(w);
}
- h = track->textures[u].height / (1 << i);
+ h = track->textures[u].height;
if (rdev->family >= CHIP_RV515)
h |= track->textures[u].height_11;
+ h = h / (1 << i);
if (track->textures[u].roundup_h)
h = roundup_pow_of_two(h);
size += w * h;
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index e08c4a8974ca..2f43ee8e4048 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -113,7 +113,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location);
- tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 4096;
+ tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - RADEON_GPU_PAGE_SIZE;
WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp);
WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0);
WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0);
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 5c7fe52de30e..1cefdbcc0850 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -311,6 +311,8 @@ int r420_init(struct radeon_device *rdev)
}
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
+ /* Initialize power management */
+ radeon_pm_init(rdev);
/* Get vram informations */
r300_vram_info(rdev);
/* Initialize memory controller (also test AGP) */
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h
index 868add6e166d..7baa73955563 100644
--- a/drivers/gpu/drm/radeon/r500_reg.h
+++ b/drivers/gpu/drm/radeon/r500_reg.h
@@ -384,9 +384,16 @@
# define AVIVO_D1GRPH_TILED (1 << 20)
# define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21)
+/* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2
+ * block and vice versa. This applies to GRPH, CUR, etc.
+ */
#define AVIVO_D1GRPH_LUT_SEL 0x6108
#define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110
+#define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914
+#define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114
#define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118
+#define R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c
+#define R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c
#define AVIVO_D1GRPH_PITCH 0x6120
#define AVIVO_D1GRPH_SURFACE_OFFSET_X 0x6124
#define AVIVO_D1GRPH_SURFACE_OFFSET_Y 0x6128
@@ -404,6 +411,8 @@
# define AVIVO_D1CURSOR_MODE_MASK (3 << 8)
# define AVIVO_D1CURSOR_MODE_24BPP 2
#define AVIVO_D1CUR_SURFACE_ADDRESS 0x6408
+#define R700_D1CUR_SURFACE_ADDRESS_HIGH 0x6c0c
+#define R700_D2CUR_SURFACE_ADDRESS_HIGH 0x640c
#define AVIVO_D1CUR_SIZE 0x6410
#define AVIVO_D1CUR_POSITION 0x6414
#define AVIVO_D1CUR_HOT_SPOT 0x6418
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index a555b7b19b48..f7435185c0a6 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -260,6 +260,8 @@ int r520_init(struct radeon_device *rdev)
}
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
+ /* Initialize power management */
+ radeon_pm_init(rdev);
/* Get vram informations */
r520_vram_info(rdev);
/* Initialize memory controller (also test AGP) */
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 609719490ec2..278f646bc18e 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -339,11 +339,10 @@ int r600_mc_init(struct radeon_device *rdev)
{
fixed20_12 a;
u32 tmp;
- int chansize;
+ int chansize, numchan;
int r;
/* Get VRAM informations */
- rdev->mc.vram_width = 128;
rdev->mc.vram_is_ddr = true;
tmp = RREG32(RAMCFG);
if (tmp & CHANSIZE_OVERRIDE) {
@@ -353,17 +352,23 @@ int r600_mc_init(struct radeon_device *rdev)
} else {
chansize = 32;
}
- if (rdev->family == CHIP_R600) {
- rdev->mc.vram_width = 8 * chansize;
- } else if (rdev->family == CHIP_RV670) {
- rdev->mc.vram_width = 4 * chansize;
- } else if ((rdev->family == CHIP_RV610) ||
- (rdev->family == CHIP_RV620)) {
- rdev->mc.vram_width = chansize;
- } else if ((rdev->family == CHIP_RV630) ||
- (rdev->family == CHIP_RV635)) {
- rdev->mc.vram_width = 2 * chansize;
+ tmp = RREG32(CHMAP);
+ switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
+ case 0:
+ default:
+ numchan = 1;
+ break;
+ case 1:
+ numchan = 2;
+ break;
+ case 2:
+ numchan = 4;
+ break;
+ case 3:
+ numchan = 8;
+ break;
}
+ rdev->mc.vram_width = numchan * chansize;
/* Could aper size report 0 ? */
rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
@@ -404,35 +409,29 @@ int r600_mc_init(struct radeon_device *rdev)
rdev->mc.gtt_location = rdev->mc.mc_vram_size;
}
} else {
- if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
- rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
- 0xFFFF) << 24;
- rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
- tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
- if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
- /* Enough place after vram */
- rdev->mc.gtt_location = tmp;
- } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
- /* Enough place before vram */
+ rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+ rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
+ 0xFFFF) << 24;
+ tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+ if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
+ /* Enough place after vram */
+ rdev->mc.gtt_location = tmp;
+ } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
+ /* Enough place before vram */
+ rdev->mc.gtt_location = 0;
+ } else {
+ /* Not enough place after or before shrink
+ * gart size
+ */
+ if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
rdev->mc.gtt_location = 0;
+ rdev->mc.gtt_size = rdev->mc.vram_location;
} else {
- /* Not enough place after or before shrink
- * gart size
- */
- if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
- rdev->mc.gtt_location = 0;
- rdev->mc.gtt_size = rdev->mc.vram_location;
- } else {
- rdev->mc.gtt_location = tmp;
- rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
- }
+ rdev->mc.gtt_location = tmp;
+ rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
}
- rdev->mc.gtt_location = rdev->mc.mc_vram_size;
- } else {
- rdev->mc.vram_location = 0x00000000UL;
- rdev->mc.gtt_location = rdev->mc.mc_vram_size;
- rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
}
+ rdev->mc.gtt_location = rdev->mc.mc_vram_size;
}
rdev->mc.vram_start = rdev->mc.vram_location;
rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
@@ -859,7 +858,8 @@ void r600_gpu_init(struct radeon_device *rdev)
((rdev->family) == CHIP_RV630) ||
((rdev->family) == CHIP_RV610) ||
((rdev->family) == CHIP_RV620) ||
- ((rdev->family) == CHIP_RS780)) {
+ ((rdev->family) == CHIP_RS780) ||
+ ((rdev->family) == CHIP_RS880)) {
WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE);
} else {
WREG32(DB_DEBUG, 0);
@@ -876,7 +876,8 @@ void r600_gpu_init(struct radeon_device *rdev)
tmp = RREG32(SQ_MS_FIFO_SIZES);
if (((rdev->family) == CHIP_RV610) ||
((rdev->family) == CHIP_RV620) ||
- ((rdev->family) == CHIP_RS780)) {
+ ((rdev->family) == CHIP_RS780) ||
+ ((rdev->family) == CHIP_RS880)) {
tmp = (CACHE_FIFO_SIZE(0xa) |
FETCH_FIFO_HIWATER(0xa) |
DONE_FIFO_HIWATER(0xe0) |
@@ -919,7 +920,8 @@ void r600_gpu_init(struct radeon_device *rdev)
NUM_ES_STACK_ENTRIES(0));
} else if (((rdev->family) == CHIP_RV610) ||
((rdev->family) == CHIP_RV620) ||
- ((rdev->family) == CHIP_RS780)) {
+ ((rdev->family) == CHIP_RS780) ||
+ ((rdev->family) == CHIP_RS880)) {
/* no vertex cache */
sq_config &= ~VC_ENABLE;
@@ -976,7 +978,8 @@ void r600_gpu_init(struct radeon_device *rdev)
if (((rdev->family) == CHIP_RV610) ||
((rdev->family) == CHIP_RV620) ||
- ((rdev->family) == CHIP_RS780)) {
+ ((rdev->family) == CHIP_RS780) ||
+ ((rdev->family) == CHIP_RS880)) {
WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY));
} else {
WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC));
@@ -1002,8 +1005,9 @@ void r600_gpu_init(struct radeon_device *rdev)
tmp = rdev->config.r600.max_pipes * 16;
switch (rdev->family) {
case CHIP_RV610:
- case CHIP_RS780:
case CHIP_RV620:
+ case CHIP_RS780:
+ case CHIP_RS880:
tmp += 32;
break;
case CHIP_RV670:
@@ -1044,8 +1048,9 @@ void r600_gpu_init(struct radeon_device *rdev)
switch (rdev->family) {
case CHIP_RV610:
- case CHIP_RS780:
case CHIP_RV620:
+ case CHIP_RS780:
+ case CHIP_RS880:
tmp = TC_L2_SIZE(8);
break;
case CHIP_RV630:
@@ -1267,19 +1272,17 @@ int r600_cp_resume(struct radeon_device *rdev)
/* Set ring buffer size */
rb_bufsz = drm_order(rdev->cp.ring_size / 8);
+ tmp = RB_NO_UPDATE | (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
#ifdef __BIG_ENDIAN
- WREG32(CP_RB_CNTL, BUF_SWAP_32BIT | RB_NO_UPDATE |
- (drm_order(4096/8) << 8) | rb_bufsz);
-#else
- WREG32(CP_RB_CNTL, RB_NO_UPDATE | (drm_order(4096/8) << 8) | rb_bufsz);
+ tmp |= BUF_SWAP_32BIT;
#endif
+ WREG32(CP_RB_CNTL, tmp);
WREG32(CP_SEM_WAIT_TIMER, 0x4);
/* Set the write pointer delay */
WREG32(CP_RB_WPTR_DELAY, 0);
/* Initialize the ring buffer's read and write pointers */
- tmp = RREG32(CP_RB_CNTL);
WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
WREG32(CP_RB_RPTR_WR, 0);
WREG32(CP_RB_WPTR, 0);
@@ -1400,7 +1403,7 @@ int r600_wb_enable(struct radeon_device *rdev)
int r;
if (rdev->wb.wb_obj == NULL) {
- r = radeon_object_create(rdev, NULL, 4096, true,
+ r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
if (r) {
dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
@@ -1450,8 +1453,8 @@ int r600_copy_blit(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_pages, struct radeon_fence *fence)
{
- r600_blit_prepare_copy(rdev, num_pages * 4096);
- r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * 4096);
+ r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
+ r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
r600_blit_done_copy(rdev, fence);
return 0;
}
@@ -1632,10 +1635,13 @@ int r600_init(struct radeon_device *rdev)
r600_scratch_init(rdev);
/* Initialize surface registers */
radeon_surface_init(rdev);
+ /* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
r = radeon_clocks_init(rdev);
if (r)
return r;
+ /* Initialize power management */
+ radeon_pm_init(rdev);
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c
index dec501081608..5ea432347589 100644
--- a/drivers/gpu/drm/radeon/r600_blit.c
+++ b/drivers/gpu/drm/radeon/r600_blit.c
@@ -582,6 +582,8 @@ r600_blit_copy(struct drm_device *dev,
u64 vb_addr;
u32 *vb;
+ vb = r600_nomm_get_vb_ptr(dev);
+
if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
max_bytes = 8192;
@@ -617,8 +619,8 @@ r600_blit_copy(struct drm_device *dev,
if (!dev_priv->blit_vb)
return;
set_shaders(dev);
+ vb = r600_nomm_get_vb_ptr(dev);
}
- vb = r600_nomm_get_vb_ptr(dev);
vb[0] = i2f(dst_x);
vb[1] = 0;
@@ -706,8 +708,8 @@ r600_blit_copy(struct drm_device *dev,
return;
set_shaders(dev);
+ vb = r600_nomm_get_vb_ptr(dev);
}
- vb = r600_nomm_get_vb_ptr(dev);
vb[0] = i2f(dst_x / 4);
vb[1] = 0;
@@ -772,6 +774,7 @@ r600_blit_swap(struct drm_device *dev,
{
drm_radeon_private_t *dev_priv = dev->dev_private;
int cb_format, tex_format;
+ int sx2, sy2, dx2, dy2;
u64 vb_addr;
u32 *vb;
@@ -786,16 +789,10 @@ r600_blit_swap(struct drm_device *dev,
}
vb = r600_nomm_get_vb_ptr(dev);
- if (cpp == 4) {
- cb_format = COLOR_8_8_8_8;
- tex_format = FMT_8_8_8_8;
- } else if (cpp == 2) {
- cb_format = COLOR_5_6_5;
- tex_format = FMT_5_6_5;
- } else {
- cb_format = COLOR_8;
- tex_format = FMT_8;
- }
+ sx2 = sx + w;
+ sy2 = sy + h;
+ dx2 = dx + w;
+ dy2 = dy + h;
vb[0] = i2f(dx);
vb[1] = i2f(dy);
@@ -803,31 +800,46 @@ r600_blit_swap(struct drm_device *dev,
vb[3] = i2f(sy);
vb[4] = i2f(dx);
- vb[5] = i2f(dy + h);
+ vb[5] = i2f(dy2);
vb[6] = i2f(sx);
- vb[7] = i2f(sy + h);
+ vb[7] = i2f(sy2);
+
+ vb[8] = i2f(dx2);
+ vb[9] = i2f(dy2);
+ vb[10] = i2f(sx2);
+ vb[11] = i2f(sy2);
- vb[8] = i2f(dx + w);
- vb[9] = i2f(dy + h);
- vb[10] = i2f(sx + w);
- vb[11] = i2f(sy + h);
+ switch(cpp) {
+ case 4:
+ cb_format = COLOR_8_8_8_8;
+ tex_format = FMT_8_8_8_8;
+ break;
+ case 2:
+ cb_format = COLOR_5_6_5;
+ tex_format = FMT_5_6_5;
+ break;
+ default:
+ cb_format = COLOR_8;
+ tex_format = FMT_8;
+ break;
+ }
/* src */
set_tex_resource(dev_priv, tex_format,
src_pitch / cpp,
- sy + h, src_pitch / cpp,
+ sy2, src_pitch / cpp,
src_gpu_addr);
cp_set_surface_sync(dev_priv,
- R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr);
+ R600_TC_ACTION_ENA, src_pitch * sy2, src_gpu_addr);
/* dst */
set_render_target(dev_priv, cb_format,
- dst_pitch / cpp, dy + h,
+ dst_pitch / cpp, dy2,
dst_gpu_addr);
/* scissors */
- set_scissors(dev_priv, dx, dy, dx + w, dy + h);
+ set_scissors(dev_priv, dx, dy, dx2, dy2);
/* Vertex buffer setup */
vb_addr = dev_priv->gart_buffers_offset +
@@ -840,7 +852,7 @@ r600_blit_swap(struct drm_device *dev,
cp_set_surface_sync(dev_priv,
R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
- dst_pitch * (dy + h), dst_gpu_addr);
+ dst_pitch * dy2, dst_gpu_addr);
dev_priv->blit_vb->used += 12 * 4;
}
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index 93108bb31d1d..dbf716e1fbf3 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -368,7 +368,7 @@ set_default_state(struct radeon_device *rdev)
if ((rdev->family == CHIP_RV610) ||
(rdev->family == CHIP_RV620) ||
(rdev->family == CHIP_RS780) ||
- (rdev->family == CHIP_RS780) ||
+ (rdev->family == CHIP_RS880) ||
(rdev->family == CHIP_RV710))
sq_config = 0;
else
@@ -610,6 +610,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
size_bytes, rdev->r600_blit.vb_used);
+ vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
max_bytes = 8192;
@@ -652,7 +653,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
vb = r600_nomm_get_vb_ptr(dev);
#endif
}
- vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
vb[0] = i2f(dst_x);
vb[1] = 0;
@@ -747,7 +747,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
vb = r600_nomm_get_vb_ptr(dev);
}
#endif
- vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
vb[0] = i2f(dst_x / 4);
vb[1] = 0;
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 17e42195c632..0d820764f340 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -466,6 +466,23 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
for (i = 0; i < pkt->count; i++) {
reg = start_reg + (4 * i);
switch (reg) {
+ case SQ_ESGS_RING_BASE:
+ case SQ_GSVS_RING_BASE:
+ case SQ_ESTMP_RING_BASE:
+ case SQ_GSTMP_RING_BASE:
+ case SQ_VSTMP_RING_BASE:
+ case SQ_PSTMP_RING_BASE:
+ case SQ_FBUF_RING_BASE:
+ case SQ_REDUC_RING_BASE:
+ case SX_MEMORY_EXPORT_BASE:
+ r = r600_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad SET_CONFIG_REG "
+ "0x%04X\n", reg);
+ return -EINVAL;
+ }
+ ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+ break;
case CP_COHER_BASE:
/* use PACKET3_SURFACE_SYNC */
return -EINVAL;
@@ -487,6 +504,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
reg = start_reg + (4 * i);
switch (reg) {
case DB_DEPTH_BASE:
+ case DB_HTILE_DATA_BASE:
case CB_COLOR0_BASE:
case CB_COLOR1_BASE:
case CB_COLOR2_BASE:
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 9b64d47f1f82..27ab428b149b 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -119,6 +119,7 @@
#define DB_DEBUG 0x9830
#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31)
#define DB_DEPTH_BASE 0x2800C
+#define DB_HTILE_DATA_BASE 0x28014
#define DB_WATERMARKS 0x9838
#define DEPTH_FREE(x) ((x) << 0)
#define DEPTH_FLUSH(x) ((x) << 5)
@@ -171,6 +172,14 @@
#define SQ_STACK_RESOURCE_MGMT_2 0x8c14
# define NUM_GS_STACK_ENTRIES(x) ((x) << 0)
# define NUM_ES_STACK_ENTRIES(x) ((x) << 16)
+#define SQ_ESGS_RING_BASE 0x8c40
+#define SQ_GSVS_RING_BASE 0x8c48
+#define SQ_ESTMP_RING_BASE 0x8c50
+#define SQ_GSTMP_RING_BASE 0x8c58
+#define SQ_VSTMP_RING_BASE 0x8c60
+#define SQ_PSTMP_RING_BASE 0x8c68
+#define SQ_FBUF_RING_BASE 0x8c70
+#define SQ_REDUC_RING_BASE 0x8c78
#define GRBM_CNTL 0x8000
# define GRBM_READ_TIMEOUT(x) ((x) << 0)
@@ -271,6 +280,10 @@
#define PCIE_PORT_INDEX 0x0038
#define PCIE_PORT_DATA 0x003C
+#define CHMAP 0x2004
+#define NOOFCHAN_SHIFT 12
+#define NOOFCHAN_MASK 0x00003000
+
#define RAMCFG 0x2408
#define NOOFBANK_SHIFT 0
#define NOOFBANK_MASK 0x00000001
@@ -352,6 +365,7 @@
#define SX_MISC 0x28350
+#define SX_MEMORY_EXPORT_BASE 0x9010
#define SX_DEBUG_1 0x9054
#define SMX_EVENT_RELEASE (1 << 0)
#define ENABLE_NEW_SMX_ADDRESS (1 << 16)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 5ab35b81c86b..224506a2f7b1 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -139,6 +139,10 @@ struct radeon_clock {
uint32_t default_sclk;
};
+/*
+ * Power management
+ */
+int radeon_pm_init(struct radeon_device *rdev);
/*
* Fences.
@@ -276,6 +280,8 @@ union radeon_gart_table {
struct radeon_gart_table_vram vram;
};
+#define RADEON_GPU_PAGE_SIZE 4096
+
struct radeon_gart {
dma_addr_t table_addr;
unsigned num_gpu_pages;
@@ -513,6 +519,7 @@ typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p,
* AGP
*/
int radeon_agp_init(struct radeon_device *rdev);
+void radeon_agp_resume(struct radeon_device *rdev);
void radeon_agp_fini(struct radeon_device *rdev);
@@ -621,7 +628,9 @@ struct radeon_asic {
uint64_t dst_offset,
unsigned num_pages,
struct radeon_fence *fence);
+ uint32_t (*get_engine_clock)(struct radeon_device *rdev);
void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock);
+ uint32_t (*get_memory_clock)(struct radeon_device *rdev);
void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock);
void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes);
void (*set_clock_gating)(struct radeon_device *rdev, int enable);
@@ -783,6 +792,7 @@ struct radeon_device {
const struct firmware *me_fw; /* all family ME firmware */
const struct firmware *pfp_fw; /* r6/700 PFP firmware */
struct r600_blit r600_blit;
+ int msi_enabled; /* msi enabled */
};
int radeon_device_init(struct radeon_device *rdev,
@@ -952,7 +962,9 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
#define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f))
#define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f))
#define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f))
+#define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev))
#define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
+#define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev))
#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
#define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l))
#define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e))
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c
index 23ea9955ac59..54bf49a6d676 100644
--- a/drivers/gpu/drm/radeon/radeon_agp.c
+++ b/drivers/gpu/drm/radeon/radeon_agp.c
@@ -237,6 +237,18 @@ int radeon_agp_init(struct radeon_device *rdev)
#endif
}
+void radeon_agp_resume(struct radeon_device *rdev)
+{
+#if __OS_HAS_AGP
+ int r;
+ if (rdev->flags & RADEON_IS_AGP) {
+ r = radeon_agp_init(rdev);
+ if (r)
+ dev_warn(rdev->dev, "radeon AGP reinit failed\n");
+ }
+#endif
+}
+
void radeon_agp_fini(struct radeon_device *rdev)
{
#if __OS_HAS_AGP
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index c3532c7a6f3f..c18fbee387d7 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -31,10 +31,13 @@
/*
* common functions
*/
+uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev);
void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock);
void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
+uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev);
void radeon_atom_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock);
+uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev);
void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock);
void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
@@ -95,7 +98,9 @@ static struct radeon_asic r100_asic = {
.copy_blit = &r100_copy_blit,
.copy_dma = NULL,
.copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_legacy_get_engine_clock,
.set_engine_clock = &radeon_legacy_set_engine_clock,
+ .get_memory_clock = NULL,
.set_memory_clock = NULL,
.set_pcie_lanes = NULL,
.set_clock_gating = &radeon_legacy_set_clock_gating,
@@ -148,7 +153,9 @@ static struct radeon_asic r300_asic = {
.copy_blit = &r100_copy_blit,
.copy_dma = &r300_copy_dma,
.copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_legacy_get_engine_clock,
.set_engine_clock = &radeon_legacy_set_engine_clock,
+ .get_memory_clock = NULL,
.set_memory_clock = NULL,
.set_pcie_lanes = &rv370_set_pcie_lanes,
.set_clock_gating = &radeon_legacy_set_clock_gating,
@@ -185,7 +192,9 @@ static struct radeon_asic r420_asic = {
.copy_blit = &r100_copy_blit,
.copy_dma = &r300_copy_dma,
.copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
.set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock,
.set_pcie_lanes = &rv370_set_pcie_lanes,
.set_clock_gating = &radeon_atom_set_clock_gating,
@@ -227,7 +236,9 @@ static struct radeon_asic rs400_asic = {
.copy_blit = &r100_copy_blit,
.copy_dma = &r300_copy_dma,
.copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_legacy_get_engine_clock,
.set_engine_clock = &radeon_legacy_set_engine_clock,
+ .get_memory_clock = NULL,
.set_memory_clock = NULL,
.set_pcie_lanes = NULL,
.set_clock_gating = &radeon_legacy_set_clock_gating,
@@ -273,7 +284,9 @@ static struct radeon_asic rs600_asic = {
.copy_blit = &r100_copy_blit,
.copy_dma = &r300_copy_dma,
.copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
.set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock,
.set_pcie_lanes = NULL,
.set_clock_gating = &radeon_atom_set_clock_gating,
@@ -312,7 +325,9 @@ static struct radeon_asic rs690_asic = {
.copy_blit = &r100_copy_blit,
.copy_dma = &r300_copy_dma,
.copy = &r300_copy_dma,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
.set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock,
.set_pcie_lanes = NULL,
.set_clock_gating = &radeon_atom_set_clock_gating,
@@ -357,7 +372,9 @@ static struct radeon_asic rv515_asic = {
.copy_blit = &r100_copy_blit,
.copy_dma = &r300_copy_dma,
.copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
.set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock,
.set_pcie_lanes = &rv370_set_pcie_lanes,
.set_clock_gating = &radeon_atom_set_clock_gating,
@@ -393,7 +410,9 @@ static struct radeon_asic r520_asic = {
.copy_blit = &r100_copy_blit,
.copy_dma = &r300_copy_dma,
.copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
.set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock,
.set_pcie_lanes = &rv370_set_pcie_lanes,
.set_clock_gating = &radeon_atom_set_clock_gating,
@@ -456,7 +475,9 @@ static struct radeon_asic r600_asic = {
.copy_blit = &r600_copy_blit,
.copy_dma = &r600_copy_blit,
.copy = &r600_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
.set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock,
.set_pcie_lanes = NULL,
.set_clock_gating = &radeon_atom_set_clock_gating,
@@ -493,7 +514,9 @@ static struct radeon_asic rv770_asic = {
.copy_blit = &r600_copy_blit,
.copy_dma = &r600_copy_blit,
.copy = &r600_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
.set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock,
.set_pcie_lanes = NULL,
.set_clock_gating = &radeon_atom_set_clock_gating,
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 5b6c08cee40e..2ed88a820935 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -46,7 +46,8 @@ radeon_add_atom_connector(struct drm_device *dev,
uint32_t supported_device,
int connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
- bool linkb, uint32_t igp_lane_info);
+ bool linkb, uint32_t igp_lane_info,
+ uint16_t connector_object_id);
/* from radeon_legacy_encoder.c */
extern void
@@ -193,6 +194,23 @@ const int supported_devices_connector_convert[] = {
DRM_MODE_CONNECTOR_DisplayPort
};
+const uint16_t supported_devices_connector_object_id_convert[] = {
+ CONNECTOR_OBJECT_ID_NONE,
+ CONNECTOR_OBJECT_ID_VGA,
+ CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */
+ CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D, /* not all boards support DL */
+ CONNECTOR_OBJECT_ID_VGA, /* technically DVI-A */
+ CONNECTOR_OBJECT_ID_COMPOSITE,
+ CONNECTOR_OBJECT_ID_SVIDEO,
+ CONNECTOR_OBJECT_ID_LVDS,
+ CONNECTOR_OBJECT_ID_9PIN_DIN,
+ CONNECTOR_OBJECT_ID_9PIN_DIN,
+ CONNECTOR_OBJECT_ID_DISPLAYPORT,
+ CONNECTOR_OBJECT_ID_HDMI_TYPE_A,
+ CONNECTOR_OBJECT_ID_HDMI_TYPE_B,
+ CONNECTOR_OBJECT_ID_SVIDEO
+};
+
const int object_connector_convert[] = {
DRM_MODE_CONNECTOR_Unknown,
DRM_MODE_CONNECTOR_DVII,
@@ -229,7 +247,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
ATOM_OBJECT_HEADER *obj_header;
int i, j, path_size, device_support;
int connector_type;
- uint16_t igp_lane_info, conn_id;
+ uint16_t igp_lane_info, conn_id, connector_object_id;
bool linkb;
struct radeon_i2c_bus_rec ddc_bus;
@@ -277,7 +295,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
ATOM_DEVICE_CV_SUPPORT)
continue;
- if ((rdev->family == CHIP_RS780) &&
+ /* IGP chips */
+ if ((rdev->flags & RADEON_IS_IGP) &&
(con_obj_id ==
CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) {
uint16_t igp_offset = 0;
@@ -311,6 +330,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
connector_type =
object_connector_convert
[ct];
+ connector_object_id = ct;
igp_lane_info =
slot_config & 0xffff;
} else
@@ -321,6 +341,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
igp_lane_info = 0;
connector_type =
object_connector_convert[con_obj_id];
+ connector_object_id = con_obj_id;
}
if (connector_type == DRM_MODE_CONNECTOR_Unknown)
@@ -425,7 +446,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
le16_to_cpu(path->
usDeviceTag),
connector_type, &ddc_bus,
- linkb, igp_lane_info);
+ linkb, igp_lane_info,
+ connector_object_id);
}
}
@@ -435,6 +457,45 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
return true;
}
+static uint16_t atombios_get_connector_object_id(struct drm_device *dev,
+ int connector_type,
+ uint16_t devices)
+{
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (rdev->flags & RADEON_IS_IGP) {
+ return supported_devices_connector_object_id_convert
+ [connector_type];
+ } else if (((connector_type == DRM_MODE_CONNECTOR_DVII) ||
+ (connector_type == DRM_MODE_CONNECTOR_DVID)) &&
+ (devices & ATOM_DEVICE_DFP2_SUPPORT)) {
+ struct radeon_mode_info *mode_info = &rdev->mode_info;
+ struct atom_context *ctx = mode_info->atom_context;
+ int index = GetIndexIntoMasterTable(DATA, XTMDS_Info);
+ uint16_t size, data_offset;
+ uint8_t frev, crev;
+ ATOM_XTMDS_INFO *xtmds;
+
+ atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
+ xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
+
+ if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
+ if (connector_type == DRM_MODE_CONNECTOR_DVII)
+ return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
+ else
+ return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
+ } else {
+ if (connector_type == DRM_MODE_CONNECTOR_DVII)
+ return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+ else
+ return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
+ }
+ } else {
+ return supported_devices_connector_object_id_convert
+ [connector_type];
+ }
+}
+
struct bios_connector {
bool valid;
uint16_t line_mux;
@@ -593,14 +654,20 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
/* add the connectors */
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
- if (bios_connectors[i].valid)
+ if (bios_connectors[i].valid) {
+ uint16_t connector_object_id =
+ atombios_get_connector_object_id(dev,
+ bios_connectors[i].connector_type,
+ bios_connectors[i].devices);
radeon_add_atom_connector(dev,
bios_connectors[i].line_mux,
bios_connectors[i].devices,
bios_connectors[i].
connector_type,
&bios_connectors[i].ddc_bus,
- false, 0);
+ false, 0,
+ connector_object_id);
+ }
}
radeon_link_encoder_connector(dev);
@@ -641,8 +708,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
le16_to_cpu(firmware_info->info.usReferenceClock);
p1pll->reference_div = 0;
- p1pll->pll_out_min =
- le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
+ if (crev < 2)
+ p1pll->pll_out_min =
+ le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
+ else
+ p1pll->pll_out_min =
+ le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output);
p1pll->pll_out_max =
le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
@@ -651,6 +722,16 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
p1pll->pll_out_min = 64800;
else
p1pll->pll_out_min = 20000;
+ } else if (p1pll->pll_out_min > 64800) {
+ /* Limiting the pll output range is a good thing generally as
+ * it limits the number of possible pll combinations for a given
+ * frequency presumably to the ones that work best on each card.
+ * However, certain duallink DVI monitors seem to like
+ * pll combinations that would be limited by this at least on
+ * pre-DCE 3.0 r6xx hardware. This might need to be adjusted per
+ * family.
+ */
+ p1pll->pll_out_min = 64800;
}
p1pll->pll_in_min =
@@ -767,6 +848,46 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
return false;
}
+static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct
+ radeon_encoder
+ *encoder,
+ int id)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_mode_info *mode_info = &rdev->mode_info;
+ int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info);
+ uint16_t data_offset;
+ struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info;
+ uint8_t frev, crev;
+ struct radeon_atom_ss *ss = NULL;
+
+ if (id > ATOM_MAX_SS_ENTRY)
+ return NULL;
+
+ atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
+ &crev, &data_offset);
+
+ ss_info =
+ (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
+
+ if (ss_info) {
+ ss =
+ kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL);
+
+ if (!ss)
+ return NULL;
+
+ ss->percentage = le16_to_cpu(ss_info->asSS_Info[id].usSpreadSpectrumPercentage);
+ ss->type = ss_info->asSS_Info[id].ucSpreadSpectrumType;
+ ss->step = ss_info->asSS_Info[id].ucSS_Step;
+ ss->delay = ss_info->asSS_Info[id].ucSS_Delay;
+ ss->range = ss_info->asSS_Info[id].ucSS_Range;
+ ss->refdiv = ss_info->asSS_Info[id].ucRecommendedRef_Div;
+ }
+ return ss;
+}
+
union lvds_info {
struct _ATOM_LVDS_INFO info;
struct _ATOM_LVDS_INFO_V12 info_12;
@@ -798,27 +919,31 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
if (!lvds)
return NULL;
- lvds->native_mode.dotclock =
+ lvds->native_mode.clock =
le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;
- lvds->native_mode.panel_xres =
+ lvds->native_mode.hdisplay =
le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);
- lvds->native_mode.panel_yres =
+ lvds->native_mode.vdisplay =
le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);
- lvds->native_mode.hblank =
- le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
- lvds->native_mode.hoverplus =
- le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
- lvds->native_mode.hsync_width =
- le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
- lvds->native_mode.vblank =
- le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
- lvds->native_mode.voverplus =
- le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
- lvds->native_mode.vsync_width =
- le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
+ lvds->native_mode.htotal = lvds->native_mode.hdisplay +
+ le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
+ lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
+ le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
+ lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
+ le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
+ lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
+ le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
+ lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +
+ le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
+ lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +
+ le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
lvds->panel_pwr_delay =
le16_to_cpu(lvds_info->info.usOffDelayInMs);
lvds->lvds_misc = lvds_info->info.ucLVDS_Misc;
+ /* set crtc values */
+ drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
+
+ lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id);
encoder->native_mode = lvds->native_mode;
}
@@ -857,8 +982,7 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
}
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
- SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
- int32_t *pixel_clock)
+ struct drm_display_mode *mode)
{
struct radeon_mode_info *mode_info = &rdev->mode_info;
ATOM_ANALOG_TV_INFO *tv_info;
@@ -866,7 +990,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
ATOM_DTD_FORMAT *dtd_timings;
int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
u8 frev, crev;
- uint16_t data_offset;
+ u16 data_offset, misc;
atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset);
@@ -876,28 +1000,37 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
if (index > MAX_SUPPORTED_TV_TIMING)
return false;
- crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
- crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
- crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
- crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
-
- crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
- crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
- crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
- crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
-
- crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo;
-
- crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight);
- crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft);
- crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom);
- crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop);
- *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
+ mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
+ mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
+ mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
+ mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) +
+ le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
+
+ mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
+ mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
+ mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
+ mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) +
+ le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
+
+ mode->flags = 0;
+ misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess);
+ if (misc & ATOM_VSYNC_POLARITY)
+ mode->flags |= DRM_MODE_FLAG_NVSYNC;
+ if (misc & ATOM_HSYNC_POLARITY)
+ mode->flags |= DRM_MODE_FLAG_NHSYNC;
+ if (misc & ATOM_COMPOSITESYNC)
+ mode->flags |= DRM_MODE_FLAG_CSYNC;
+ if (misc & ATOM_INTERLACE)
+ mode->flags |= DRM_MODE_FLAG_INTERLACE;
+ if (misc & ATOM_DOUBLE_CLOCK_MODE)
+ mode->flags |= DRM_MODE_FLAG_DBLSCAN;
+
+ mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
if (index == 1) {
/* PAL timings appear to have wrong values for totals */
- crtc_timing->usH_Total -= 1;
- crtc_timing->usV_Total -= 1;
+ mode->crtc_htotal -= 1;
+ mode->crtc_vtotal -= 1;
}
break;
case 2:
@@ -906,17 +1039,36 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
return false;
dtd_timings = &tv_info_v1_2->aModeTimings[index];
- crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time);
- crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive);
- crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset);
- crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth);
- crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time);
- crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive);
- crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset);
- crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth);
-
- crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
- *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
+ mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) +
+ le16_to_cpu(dtd_timings->usHBlanking_Time);
+ mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive);
+ mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) +
+ le16_to_cpu(dtd_timings->usHSyncOffset);
+ mode->crtc_hsync_end = mode->crtc_hsync_start +
+ le16_to_cpu(dtd_timings->usHSyncWidth);
+
+ mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) +
+ le16_to_cpu(dtd_timings->usVBlanking_Time);
+ mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive);
+ mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) +
+ le16_to_cpu(dtd_timings->usVSyncOffset);
+ mode->crtc_vsync_end = mode->crtc_vsync_start +
+ le16_to_cpu(dtd_timings->usVSyncWidth);
+
+ mode->flags = 0;
+ misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
+ if (misc & ATOM_VSYNC_POLARITY)
+ mode->flags |= DRM_MODE_FLAG_NVSYNC;
+ if (misc & ATOM_HSYNC_POLARITY)
+ mode->flags |= DRM_MODE_FLAG_NHSYNC;
+ if (misc & ATOM_COMPOSITESYNC)
+ mode->flags |= DRM_MODE_FLAG_CSYNC;
+ if (misc & ATOM_INTERLACE)
+ mode->flags |= DRM_MODE_FLAG_INTERLACE;
+ if (misc & ATOM_DOUBLE_CLOCK_MODE)
+ mode->flags |= DRM_MODE_FLAG_DBLSCAN;
+
+ mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
break;
}
return true;
@@ -981,6 +1133,24 @@ void radeon_atom_static_pwrmgt_setup(struct radeon_device *rdev, int enable)
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
+uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev)
+{
+ GET_ENGINE_CLOCK_PS_ALLOCATION args;
+ int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock);
+
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ return args.ulReturnEngineClock;
+}
+
+uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev)
+{
+ GET_MEMORY_CLOCK_PS_ALLOCATION args;
+ int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock);
+
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ return args.ulReturnMemoryClock;
+}
+
void radeon_atom_set_engine_clock(struct radeon_device *rdev,
uint32_t eng_clock)
{
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
index 2e938f7496fb..10bd50a7db87 100644
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -63,7 +63,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
if (r) {
goto out_cleanup;
}
- r = radeon_copy_dma(rdev, saddr, daddr, size / 4096, fence);
+ r = radeon_copy_dma(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence);
if (r) {
goto out_cleanup;
}
@@ -88,7 +88,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
if (r) {
goto out_cleanup;
}
- r = radeon_copy_blit(rdev, saddr, daddr, size / 4096, fence);
+ r = radeon_copy_blit(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence);
if (r) {
goto out_cleanup;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 34a9b9119518..906921740c60 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -50,19 +50,16 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev)
vram_base = drm_get_resource_start(rdev->ddev, 0);
bios = ioremap(vram_base, size);
if (!bios) {
- DRM_ERROR("Unable to mmap vram\n");
return false;
}
if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
iounmap(bios);
- DRM_ERROR("bad rom signature\n");
return false;
}
rdev->bios = kmalloc(size, GFP_KERNEL);
if (rdev->bios == NULL) {
iounmap(bios);
- DRM_ERROR("kmalloc failed\n");
return false;
}
memcpy(rdev->bios, bios, size);
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
index f5c32a766b10..a81354167621 100644
--- a/drivers/gpu/drm/radeon/radeon_clocks.c
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -32,7 +32,7 @@
#include "atom.h"
/* 10 khz */
-static uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
+uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
{
struct radeon_pll *spll = &rdev->clock.spll;
uint32_t fb_div, ref_div, post_div, sclk;
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 748265a105b3..5253cbf6db1f 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -49,7 +49,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
uint32_t connector_id,
uint32_t supported_device,
int connector_type,
- struct radeon_i2c_bus_rec *i2c_bus);
+ struct radeon_i2c_bus_rec *i2c_bus,
+ uint16_t connector_object_id);
/* from radeon_legacy_encoder.c */
extern void
@@ -808,25 +809,25 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf;
if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE)
- lvds->native_mode.panel_yres =
+ lvds->native_mode.vdisplay =
((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
RADEON_VERT_PANEL_SHIFT) + 1;
else
- lvds->native_mode.panel_yres =
+ lvds->native_mode.vdisplay =
(RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1;
if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE)
- lvds->native_mode.panel_xres =
+ lvds->native_mode.hdisplay =
(((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
else
- lvds->native_mode.panel_xres =
+ lvds->native_mode.hdisplay =
((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8;
- if ((lvds->native_mode.panel_xres < 640) ||
- (lvds->native_mode.panel_yres < 480)) {
- lvds->native_mode.panel_xres = 640;
- lvds->native_mode.panel_yres = 480;
+ if ((lvds->native_mode.hdisplay < 640) ||
+ (lvds->native_mode.vdisplay < 480)) {
+ lvds->native_mode.hdisplay = 640;
+ lvds->native_mode.vdisplay = 480;
}
ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
@@ -846,8 +847,8 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
lvds->panel_vcc_delay = 200;
DRM_INFO("Panel info derived from registers\n");
- DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres,
- lvds->native_mode.panel_yres);
+ DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
+ lvds->native_mode.vdisplay);
return lvds;
}
@@ -882,11 +883,11 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
DRM_INFO("Panel ID String: %s\n", stmp);
- lvds->native_mode.panel_xres = RBIOS16(lcd_info + 0x19);
- lvds->native_mode.panel_yres = RBIOS16(lcd_info + 0x1b);
+ lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19);
+ lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b);
- DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres,
- lvds->native_mode.panel_yres);
+ DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
+ lvds->native_mode.vdisplay);
lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c);
if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0)
@@ -944,27 +945,25 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
if (tmp == 0)
break;
- if ((RBIOS16(tmp) == lvds->native_mode.panel_xres) &&
+ if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) &&
(RBIOS16(tmp + 2) ==
- lvds->native_mode.panel_yres)) {
- lvds->native_mode.hblank =
- (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8;
- lvds->native_mode.hoverplus =
- (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) -
- 1) * 8;
- lvds->native_mode.hsync_width =
- RBIOS8(tmp + 23) * 8;
-
- lvds->native_mode.vblank = (RBIOS16(tmp + 24) -
- RBIOS16(tmp + 26));
- lvds->native_mode.voverplus =
- ((RBIOS16(tmp + 28) & 0x7ff) -
- RBIOS16(tmp + 26));
- lvds->native_mode.vsync_width =
- ((RBIOS16(tmp + 28) & 0xf800) >> 11);
- lvds->native_mode.dotclock =
- RBIOS16(tmp + 9) * 10;
+ lvds->native_mode.vdisplay)) {
+ lvds->native_mode.htotal = RBIOS16(tmp + 17) * 8;
+ lvds->native_mode.hsync_start = RBIOS16(tmp + 21) * 8;
+ lvds->native_mode.hsync_end = (RBIOS8(tmp + 23) +
+ RBIOS16(tmp + 21)) * 8;
+
+ lvds->native_mode.vtotal = RBIOS16(tmp + 24);
+ lvds->native_mode.vsync_start = RBIOS16(tmp + 28) & 0x7ff;
+ lvds->native_mode.vsync_end =
+ ((RBIOS16(tmp + 28) & 0xf800) >> 11) +
+ (RBIOS16(tmp + 28) & 0x7ff);
+
+ lvds->native_mode.clock = RBIOS16(tmp + 9) * 10;
lvds->native_mode.flags = 0;
+ /* set crtc values */
+ drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
+
}
}
} else {
@@ -1178,7 +1177,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
radeon_add_legacy_connector(dev, 0,
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_VGA,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
} else if (rdev->flags & RADEON_IS_MOBILITY) {
/* LVDS */
ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
@@ -1190,7 +1190,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
radeon_add_legacy_connector(dev, 0,
ATOM_DEVICE_LCD1_SUPPORT,
DRM_MODE_CONNECTOR_LVDS,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_LVDS);
/* VGA - primary dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
@@ -1202,7 +1203,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
radeon_add_legacy_connector(dev, 1,
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_VGA,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
} else {
/* DVI-I - tv dac, int tmds */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
@@ -1220,7 +1222,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_DFP1_SUPPORT |
ATOM_DEVICE_CRT2_SUPPORT,
DRM_MODE_CONNECTOR_DVII,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
/* VGA - primary dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
@@ -1232,7 +1235,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
radeon_add_legacy_connector(dev, 1,
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_VGA,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
}
if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
@@ -1245,7 +1249,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
radeon_add_legacy_connector(dev, 2,
ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
}
break;
case CT_IBOOK:
@@ -1259,7 +1264,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
0),
ATOM_DEVICE_LCD1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
- DRM_MODE_CONNECTOR_LVDS, &ddc_i2c);
+ DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_LVDS);
/* VGA - TV DAC */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
radeon_add_legacy_encoder(dev,
@@ -1268,7 +1274,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
2),
ATOM_DEVICE_CRT2_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
- DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+ DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
/* TV - TV DAC */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
@@ -1277,7 +1284,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_TV1_SUPPORT);
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
break;
case CT_POWERBOOK_EXTERNAL:
DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
@@ -1290,7 +1298,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
0),
ATOM_DEVICE_LCD1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
- DRM_MODE_CONNECTOR_LVDS, &ddc_i2c);
+ DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_LVDS);
/* DVI-I - primary dac, ext tmds */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
radeon_add_legacy_encoder(dev,
@@ -1303,10 +1312,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
+ /* XXX some are SL */
radeon_add_legacy_connector(dev, 1,
ATOM_DEVICE_DFP2_SUPPORT |
ATOM_DEVICE_CRT1_SUPPORT,
- DRM_MODE_CONNECTOR_DVII, &ddc_i2c);
+ DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I);
/* TV - TV DAC */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
@@ -1315,7 +1326,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_TV1_SUPPORT);
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
break;
case CT_POWERBOOK_INTERNAL:
DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
@@ -1328,7 +1340,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
0),
ATOM_DEVICE_LCD1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
- DRM_MODE_CONNECTOR_LVDS, &ddc_i2c);
+ DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_LVDS);
/* DVI-I - primary dac, int tmds */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
radeon_add_legacy_encoder(dev,
@@ -1344,7 +1357,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
radeon_add_legacy_connector(dev, 1,
ATOM_DEVICE_DFP1_SUPPORT |
ATOM_DEVICE_CRT1_SUPPORT,
- DRM_MODE_CONNECTOR_DVII, &ddc_i2c);
+ DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
/* TV - TV DAC */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
@@ -1353,7 +1367,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_TV1_SUPPORT);
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
break;
case CT_POWERBOOK_VGA:
DRM_INFO("Connector Table: %d (powerbook vga)\n",
@@ -1366,7 +1381,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
0),
ATOM_DEVICE_LCD1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
- DRM_MODE_CONNECTOR_LVDS, &ddc_i2c);
+ DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_LVDS);
/* VGA - primary dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
radeon_add_legacy_encoder(dev,
@@ -1375,7 +1391,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
1),
ATOM_DEVICE_CRT1_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
- DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+ DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
/* TV - TV DAC */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
@@ -1384,7 +1401,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_TV1_SUPPORT);
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
break;
case CT_MINI_EXTERNAL:
DRM_INFO("Connector Table: %d (mini external tmds)\n",
@@ -1401,10 +1419,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_CRT2_SUPPORT,
2),
ATOM_DEVICE_CRT2_SUPPORT);
+ /* XXX are any DL? */
radeon_add_legacy_connector(dev, 0,
ATOM_DEVICE_DFP2_SUPPORT |
ATOM_DEVICE_CRT2_SUPPORT,
- DRM_MODE_CONNECTOR_DVII, &ddc_i2c);
+ DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
/* TV - TV DAC */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
@@ -1413,7 +1433,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_TV1_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
break;
case CT_MINI_INTERNAL:
DRM_INFO("Connector Table: %d (mini internal tmds)\n",
@@ -1433,7 +1454,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
radeon_add_legacy_connector(dev, 0,
ATOM_DEVICE_DFP1_SUPPORT |
ATOM_DEVICE_CRT2_SUPPORT,
- DRM_MODE_CONNECTOR_DVII, &ddc_i2c);
+ DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
/* TV - TV DAC */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
@@ -1442,7 +1464,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_TV1_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
break;
case CT_IMAC_G5_ISIGHT:
DRM_INFO("Connector Table: %d (imac g5 isight)\n",
@@ -1455,7 +1478,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
0),
ATOM_DEVICE_DFP1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
- DRM_MODE_CONNECTOR_DVID, &ddc_i2c);
+ DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
/* VGA - tv dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
radeon_add_legacy_encoder(dev,
@@ -1464,7 +1488,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
2),
ATOM_DEVICE_CRT2_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
- DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+ DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
/* TV - TV DAC */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
@@ -1473,7 +1498,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_TV1_SUPPORT);
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
break;
case CT_EMAC:
DRM_INFO("Connector Table: %d (emac)\n",
@@ -1486,7 +1512,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
1),
ATOM_DEVICE_CRT1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
- DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+ DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
/* VGA - tv dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
radeon_add_legacy_encoder(dev,
@@ -1495,7 +1522,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
2),
ATOM_DEVICE_CRT2_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
- DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+ DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
/* TV - TV DAC */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
@@ -1504,7 +1532,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ATOM_DEVICE_TV1_SUPPORT);
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
break;
default:
DRM_INFO("Connector table: %d (invalid)\n",
@@ -1581,11 +1610,63 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev,
return true;
}
+static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev)
+{
+ /* Acer 5102 has non-existent TV port */
+ if (dev->pdev->device == 0x5975 &&
+ dev->pdev->subsystem_vendor == 0x1025 &&
+ dev->pdev->subsystem_device == 0x009f)
+ return false;
+
+ /* HP dc5750 has non-existent TV port */
+ if (dev->pdev->device == 0x5974 &&
+ dev->pdev->subsystem_vendor == 0x103c &&
+ dev->pdev->subsystem_device == 0x280a)
+ return false;
+
+ return true;
+}
+
+static uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d)
+{
+ struct radeon_device *rdev = dev->dev_private;
+ uint32_t ext_tmds_info;
+
+ if (rdev->flags & RADEON_IS_IGP) {
+ if (is_dvi_d)
+ return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
+ else
+ return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+ }
+ ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
+ if (ext_tmds_info) {
+ uint8_t rev = RBIOS8(ext_tmds_info);
+ uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5);
+ if (rev >= 3) {
+ if (is_dvi_d)
+ return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
+ else
+ return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
+ } else {
+ if (flags & 1) {
+ if (is_dvi_d)
+ return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
+ else
+ return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
+ }
+ }
+ }
+ if (is_dvi_d)
+ return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
+ else
+ return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+}
+
bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
{
struct radeon_device *rdev = dev->dev_private;
uint32_t conn_info, entry, devices;
- uint16_t tmp;
+ uint16_t tmp, connector_object_id;
enum radeon_combios_ddc ddc_type;
enum radeon_combios_connector connector;
int i = 0;
@@ -1628,8 +1709,9 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
break;
}
- radeon_apply_legacy_quirks(dev, i, &connector,
- &ddc_i2c);
+ if (!radeon_apply_legacy_quirks(dev, i, &connector,
+ &ddc_i2c))
+ continue;
switch (connector) {
case CONNECTOR_PROPRIETARY_LEGACY:
@@ -1644,7 +1726,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
radeon_add_legacy_connector(dev, i, devices,
legacy_connector_convert
[connector],
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
break;
case CONNECTOR_CRT_LEGACY:
if (tmp & 0x1) {
@@ -1669,7 +1752,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
devices,
legacy_connector_convert
[connector],
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
break;
case CONNECTOR_DVI_I_LEGACY:
devices = 0;
@@ -1698,6 +1782,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
ATOM_DEVICE_DFP2_SUPPORT,
0),
ATOM_DEVICE_DFP2_SUPPORT);
+ connector_object_id = combios_check_dl_dvi(dev, 0);
} else {
devices |= ATOM_DEVICE_DFP1_SUPPORT;
radeon_add_legacy_encoder(dev,
@@ -1706,19 +1791,24 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
ATOM_DEVICE_DFP1_SUPPORT,
0),
ATOM_DEVICE_DFP1_SUPPORT);
+ connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
}
radeon_add_legacy_connector(dev,
i,
devices,
legacy_connector_convert
[connector],
- &ddc_i2c);
+ &ddc_i2c,
+ connector_object_id);
break;
case CONNECTOR_DVI_D_LEGACY:
- if ((tmp >> 4) & 0x1)
+ if ((tmp >> 4) & 0x1) {
devices = ATOM_DEVICE_DFP2_SUPPORT;
- else
+ connector_object_id = combios_check_dl_dvi(dev, 1);
+ } else {
devices = ATOM_DEVICE_DFP1_SUPPORT;
+ connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+ }
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id
(dev, devices, 0),
@@ -1726,7 +1816,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
radeon_add_legacy_connector(dev, i, devices,
legacy_connector_convert
[connector],
- &ddc_i2c);
+ &ddc_i2c,
+ connector_object_id);
break;
case CONNECTOR_CTV_LEGACY:
case CONNECTOR_STV_LEGACY:
@@ -1740,7 +1831,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
ATOM_DEVICE_TV1_SUPPORT,
legacy_connector_convert
[connector],
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
break;
default:
DRM_ERROR("Unknown connector type: %d\n",
@@ -1772,10 +1864,29 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
ATOM_DEVICE_CRT1_SUPPORT |
ATOM_DEVICE_DFP1_SUPPORT,
DRM_MODE_CONNECTOR_DVII,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
} else {
- DRM_DEBUG("No connector info found\n");
- return false;
+ uint16_t crt_info =
+ combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
+ DRM_DEBUG("Found CRT table, assuming VGA connector\n");
+ if (crt_info) {
+ radeon_add_legacy_encoder(dev,
+ radeon_get_encoder_id(dev,
+ ATOM_DEVICE_CRT1_SUPPORT,
+ 1),
+ ATOM_DEVICE_CRT1_SUPPORT);
+ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+ radeon_add_legacy_connector(dev,
+ 0,
+ ATOM_DEVICE_CRT1_SUPPORT,
+ DRM_MODE_CONNECTOR_VGA,
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_VGA);
+ } else {
+ DRM_DEBUG("No connector info found\n");
+ return false;
+ }
}
}
@@ -1870,7 +1981,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
5,
ATOM_DEVICE_LCD1_SUPPORT,
DRM_MODE_CONNECTOR_LVDS,
- &ddc_i2c);
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_LVDS);
}
}
@@ -1880,16 +1992,19 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
if (tv_info) {
if (RBIOS8(tv_info + 6) == 'T') {
- radeon_add_legacy_encoder(dev,
- radeon_get_encoder_id
- (dev,
- ATOM_DEVICE_TV1_SUPPORT,
- 2),
- ATOM_DEVICE_TV1_SUPPORT);
- radeon_add_legacy_connector(dev, 6,
- ATOM_DEVICE_TV1_SUPPORT,
- DRM_MODE_CONNECTOR_SVIDEO,
- &ddc_i2c);
+ if (radeon_apply_legacy_tv_quirks(dev)) {
+ radeon_add_legacy_encoder(dev,
+ radeon_get_encoder_id
+ (dev,
+ ATOM_DEVICE_TV1_SUPPORT,
+ 2),
+ ATOM_DEVICE_TV1_SUPPORT);
+ radeon_add_legacy_connector(dev, 6,
+ ATOM_DEVICE_TV1_SUPPORT,
+ DRM_MODE_CONNECTOR_SVIDEO,
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO);
+ }
}
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index e376be47a4a0..29763ceae3af 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -178,25 +178,12 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode
struct drm_device *dev = encoder->dev;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_display_mode *mode = NULL;
- struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
-
- if (native_mode->panel_xres != 0 &&
- native_mode->panel_yres != 0 &&
- native_mode->dotclock != 0) {
- mode = drm_mode_create(dev);
-
- mode->hdisplay = native_mode->panel_xres;
- mode->vdisplay = native_mode->panel_yres;
-
- mode->htotal = mode->hdisplay + native_mode->hblank;
- mode->hsync_start = mode->hdisplay + native_mode->hoverplus;
- mode->hsync_end = mode->hsync_start + native_mode->hsync_width;
- mode->vtotal = mode->vdisplay + native_mode->vblank;
- mode->vsync_start = mode->vdisplay + native_mode->voverplus;
- mode->vsync_end = mode->vsync_start + native_mode->vsync_width;
- mode->clock = native_mode->dotclock;
- mode->flags = 0;
+ struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+ if (native_mode->hdisplay != 0 &&
+ native_mode->vdisplay != 0 &&
+ native_mode->clock != 0) {
+ mode = drm_mode_duplicate(dev, native_mode);
mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
drm_mode_set_name(mode);
@@ -210,7 +197,7 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn
struct drm_device *dev = encoder->dev;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_display_mode *mode = NULL;
- struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
+ struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
int i;
struct mode_size {
int w;
@@ -236,11 +223,16 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn
};
for (i = 0; i < 17; i++) {
+ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
+ if (common_modes[i].w > 1024 ||
+ common_modes[i].h > 768)
+ continue;
+ }
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
- if (common_modes[i].w > native_mode->panel_xres ||
- common_modes[i].h > native_mode->panel_yres ||
- (common_modes[i].w == native_mode->panel_xres &&
- common_modes[i].h == native_mode->panel_yres))
+ if (common_modes[i].w > native_mode->hdisplay ||
+ common_modes[i].h > native_mode->vdisplay ||
+ (common_modes[i].w == native_mode->hdisplay &&
+ common_modes[i].h == native_mode->vdisplay))
continue;
}
if (common_modes[i].w < 320 || common_modes[i].h < 200)
@@ -344,28 +336,23 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
struct drm_connector *connector)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
+ struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
/* Try to get native mode details from EDID if necessary */
- if (!native_mode->dotclock) {
+ if (!native_mode->clock) {
struct drm_display_mode *t, *mode;
list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
- if (mode->hdisplay == native_mode->panel_xres &&
- mode->vdisplay == native_mode->panel_yres) {
- native_mode->hblank = mode->htotal - mode->hdisplay;
- native_mode->hoverplus = mode->hsync_start - mode->hdisplay;
- native_mode->hsync_width = mode->hsync_end - mode->hsync_start;
- native_mode->vblank = mode->vtotal - mode->vdisplay;
- native_mode->voverplus = mode->vsync_start - mode->vdisplay;
- native_mode->vsync_width = mode->vsync_end - mode->vsync_start;
- native_mode->dotclock = mode->clock;
+ if (mode->hdisplay == native_mode->hdisplay &&
+ mode->vdisplay == native_mode->vdisplay) {
+ *native_mode = *mode;
+ drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V);
DRM_INFO("Determined LVDS native mode details from EDID\n");
break;
}
}
}
- if (!native_mode->dotclock) {
+ if (!native_mode->clock) {
DRM_INFO("No LVDS native mode details, disabling RMX\n");
radeon_encoder->rmx_type = RMX_OFF;
}
@@ -410,13 +397,64 @@ static int radeon_lvds_get_modes(struct drm_connector *connector)
static int radeon_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
+ struct drm_encoder *encoder = radeon_best_single_encoder(connector);
+
+ if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
+ return MODE_PANEL;
+
+ if (encoder) {
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+
+ /* AVIVO hardware supports downscaling modes larger than the panel
+ * to the panel size, but I'm not sure this is desirable.
+ */
+ if ((mode->hdisplay > native_mode->hdisplay) ||
+ (mode->vdisplay > native_mode->vdisplay))
+ return MODE_PANEL;
+
+ /* if scaling is disabled, block non-native modes */
+ if (radeon_encoder->rmx_type == RMX_OFF) {
+ if ((mode->hdisplay != native_mode->hdisplay) ||
+ (mode->vdisplay != native_mode->vdisplay))
+ return MODE_PANEL;
+ }
+ }
+
return MODE_OK;
}
static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
{
- enum drm_connector_status ret = connector_status_connected;
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ struct drm_encoder *encoder = radeon_best_single_encoder(connector);
+ enum drm_connector_status ret = connector_status_disconnected;
+
+ if (encoder) {
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+
+ /* check if panel is valid */
+ if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
+ ret = connector_status_connected;
+
+ }
+
+ /* check for edid as well */
+ if (radeon_connector->edid)
+ ret = connector_status_connected;
+ else {
+ if (radeon_connector->ddc_bus) {
+ radeon_i2c_do_lock(radeon_connector, 1);
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+ &radeon_connector->ddc_bus->adapter);
+ radeon_i2c_do_lock(radeon_connector, 0);
+ if (radeon_connector->edid)
+ ret = connector_status_connected;
+ }
+ }
/* check acpi lid status ??? */
+
radeon_connector_update_scratch_regs(connector, ret);
return ret;
}
@@ -427,6 +465,8 @@ static void radeon_connector_destroy(struct drm_connector *connector)
if (radeon_connector->ddc_bus)
radeon_i2c_destroy(radeon_connector->ddc_bus);
+ if (radeon_connector->edid)
+ kfree(radeon_connector->edid);
kfree(radeon_connector->con_priv);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
@@ -496,6 +536,8 @@ static int radeon_vga_get_modes(struct drm_connector *connector)
static int radeon_vga_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
+ /* XXX check mode bandwidth */
+ /* XXX verify against max DAC output frequency */
return MODE_OK;
}
@@ -514,9 +556,33 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
radeon_i2c_do_lock(radeon_connector, 1);
dret = radeon_ddc_probe(radeon_connector);
radeon_i2c_do_lock(radeon_connector, 0);
- if (dret)
- ret = connector_status_connected;
- else {
+ if (dret) {
+ if (radeon_connector->edid) {
+ kfree(radeon_connector->edid);
+ radeon_connector->edid = NULL;
+ }
+ radeon_i2c_do_lock(radeon_connector, 1);
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+ radeon_i2c_do_lock(radeon_connector, 0);
+
+ if (!radeon_connector->edid) {
+ DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
+ drm_get_connector_name(connector));
+ ret = connector_status_connected;
+ } else {
+ radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
+
+ /* some oems have boards with separate digital and analog connectors
+ * with a shared ddc line (often vga + hdmi)
+ */
+ if (radeon_connector->use_digital && radeon_connector->shared_ddc) {
+ kfree(radeon_connector->edid);
+ radeon_connector->edid = NULL;
+ ret = connector_status_disconnected;
+ } else
+ ret = connector_status_connected;
+ }
+ } else {
if (radeon_connector->dac_load_detect) {
encoder_funcs = encoder->helper_private;
ret = encoder_funcs->detect(encoder, connector);
@@ -570,6 +636,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector)
static int radeon_tv_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
+ if ((mode->hdisplay > 1024) || (mode->vdisplay > 768))
+ return MODE_CLOCK_RANGE;
return MODE_OK;
}
@@ -644,20 +712,29 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
dret = radeon_ddc_probe(radeon_connector);
radeon_i2c_do_lock(radeon_connector, 0);
if (dret) {
+ if (radeon_connector->edid) {
+ kfree(radeon_connector->edid);
+ radeon_connector->edid = NULL;
+ }
radeon_i2c_do_lock(radeon_connector, 1);
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0);
if (!radeon_connector->edid) {
- DRM_ERROR("DDC responded but not EDID found for %s\n",
- drm_get_connector_name(connector));
+ DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
+ drm_get_connector_name(connector));
} else {
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
- /* if this isn't a digital monitor
- then we need to make sure we don't have any
- TV conflicts */
- ret = connector_status_connected;
+ /* some oems have boards with separate digital and analog connectors
+ * with a shared ddc line (often vga + hdmi)
+ */
+ if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) {
+ kfree(radeon_connector->edid);
+ radeon_connector->edid = NULL;
+ ret = connector_status_disconnected;
+ } else
+ ret = connector_status_connected;
}
}
@@ -753,9 +830,27 @@ static void radeon_dvi_force(struct drm_connector *connector)
radeon_connector->use_digital = true;
}
+static int radeon_dvi_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+ /* XXX check mode bandwidth */
+
+ if (radeon_connector->use_digital && (mode->clock > 165000)) {
+ if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) ||
+ (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
+ (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
+ return MODE_OK;
+ else
+ return MODE_CLOCK_HIGH;
+ }
+ return MODE_OK;
+}
+
struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
.get_modes = radeon_dvi_get_modes,
- .mode_valid = radeon_vga_mode_valid,
+ .mode_valid = radeon_dvi_mode_valid,
.best_encoder = radeon_dvi_encoder,
};
@@ -775,13 +870,15 @@ radeon_add_atom_connector(struct drm_device *dev,
int connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
bool linkb,
- uint32_t igp_lane_info)
+ uint32_t igp_lane_info,
+ uint16_t connector_object_id)
{
struct radeon_device *rdev = dev->dev_private;
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
struct radeon_connector_atom_dig *radeon_dig_connector;
uint32_t subpixel_order = SubPixelNone;
+ bool shared_ddc = false;
int ret;
/* fixme - tv/cv/din */
@@ -795,6 +892,13 @@ radeon_add_atom_connector(struct drm_device *dev,
radeon_connector->devices |= supported_device;
return;
}
+ if (radeon_connector->ddc_bus && i2c_bus->valid) {
+ if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus,
+ sizeof(struct radeon_i2c_bus_rec)) == 0) {
+ radeon_connector->shared_ddc = true;
+ shared_ddc = true;
+ }
+ }
}
radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
@@ -805,6 +909,8 @@ radeon_add_atom_connector(struct drm_device *dev,
radeon_connector->connector_id = connector_id;
radeon_connector->devices = supported_device;
+ radeon_connector->shared_ddc = shared_ddc;
+ radeon_connector->connector_object_id = connector_object_id;
switch (connector_type) {
case DRM_MODE_CONNECTOR_VGA:
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -956,7 +1062,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
uint32_t connector_id,
uint32_t supported_device,
int connector_type,
- struct radeon_i2c_bus_rec *i2c_bus)
+ struct radeon_i2c_bus_rec *i2c_bus,
+ uint16_t connector_object_id)
{
struct radeon_device *rdev = dev->dev_private;
struct drm_connector *connector;
@@ -985,6 +1092,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
radeon_connector->connector_id = connector_id;
radeon_connector->devices = supported_device;
+ radeon_connector->connector_object_id = connector_object_id;
switch (connector_type) {
case DRM_MODE_CONNECTOR_VGA:
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1042,6 +1150,13 @@ radeon_add_legacy_connector(struct drm_device *dev,
if (ret)
goto failed;
radeon_connector->dac_load_detect = true;
+ /* RS400,RC410,RS480 chipset seems to report a lot
+ * of false positive on load detect, we haven't yet
+ * found a way to make load detect reliable on those
+ * chipset, thus just disable it for TV.
+ */
+ if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
+ radeon_connector->dac_load_detect = false;
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property,
1);
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
index b13c79e38bc0..28772a37009c 100644
--- a/drivers/gpu/drm/radeon/radeon_cursor.c
+++ b/drivers/gpu/drm/radeon/radeon_cursor.c
@@ -109,9 +109,15 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj,
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct radeon_device *rdev = crtc->dev->dev_private;
- if (ASIC_IS_AVIVO(rdev))
+ if (ASIC_IS_AVIVO(rdev)) {
+ if (rdev->family >= CHIP_RV770) {
+ if (radeon_crtc->crtc_id)
+ WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, 0);
+ else
+ WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0);
+ }
WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
- else {
+ } else {
radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr;
/* offset is from DISP(2)_BASE_ADDRESS */
WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 3d667031de6e..41bb76fbe734 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -444,20 +444,24 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
return r;
}
-static struct card_info atom_card_info = {
- .dev = NULL,
- .reg_read = cail_reg_read,
- .reg_write = cail_reg_write,
- .mc_read = cail_mc_read,
- .mc_write = cail_mc_write,
- .pll_read = cail_pll_read,
- .pll_write = cail_pll_write,
-};
-
int radeon_atombios_init(struct radeon_device *rdev)
{
- atom_card_info.dev = rdev->ddev;
- rdev->mode_info.atom_context = atom_parse(&atom_card_info, rdev->bios);
+ struct card_info *atom_card_info =
+ kzalloc(sizeof(struct card_info), GFP_KERNEL);
+
+ if (!atom_card_info)
+ return -ENOMEM;
+
+ rdev->mode_info.atom_card_info = atom_card_info;
+ atom_card_info->dev = rdev->ddev;
+ atom_card_info->reg_read = cail_reg_read;
+ atom_card_info->reg_write = cail_reg_write;
+ atom_card_info->mc_read = cail_mc_read;
+ atom_card_info->mc_write = cail_mc_write;
+ atom_card_info->pll_read = cail_pll_read;
+ atom_card_info->pll_write = cail_pll_write;
+
+ rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
return 0;
}
@@ -465,6 +469,7 @@ int radeon_atombios_init(struct radeon_device *rdev)
void radeon_atombios_fini(struct radeon_device *rdev)
{
kfree(rdev->mode_info.atom_context);
+ kfree(rdev->mode_info.atom_card_info);
}
int radeon_combios_init(struct radeon_device *rdev)
@@ -582,10 +587,9 @@ int radeon_device_init(struct radeon_device *rdev,
DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
/* if we have > 1 VGA cards, then disable the radeon VGA resources */
- r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
- if (r) {
- return -EINVAL;
- }
+ /* this will fail for cards that aren't VGA class devices, just
+ * ignore it */
+ vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
r = radeon_init(rdev);
if (r)
@@ -684,6 +688,8 @@ int radeon_resume_kms(struct drm_device *dev)
return -1;
}
pci_set_master(dev->pdev);
+ /* resume AGP if in use */
+ radeon_agp_resume(rdev);
radeon_resume(rdev);
radeon_restore_bios_scratch_regs(rdev);
fb_set_suspend(rdev->fbdev_info, 0);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 3655d91993a6..c85df4afcb7a 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -137,9 +137,6 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
if (size != 256) {
return;
}
- if (crtc->fb == NULL) {
- return;
- }
/* userspace palettes are always correct as is */
for (i = 0; i < 256; i++) {
@@ -147,7 +144,6 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
radeon_crtc->lut_g[i] = green[i] >> 6;
radeon_crtc->lut_b[i] = blue[i] >> 6;
}
-
radeon_crtc_load_lut(crtc);
}
@@ -338,27 +334,19 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
{
- struct edid *edid;
int ret = 0;
if (!radeon_connector->ddc_bus)
return -1;
if (!radeon_connector->edid) {
radeon_i2c_do_lock(radeon_connector, 1);
- edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0);
- } else
- edid = radeon_connector->edid;
+ }
- if (edid) {
- /* update digital bits here */
- if (edid->input & DRM_EDID_INPUT_DIGITAL)
- radeon_connector->use_digital = 1;
- else
- radeon_connector->use_digital = 0;
- drm_mode_connector_update_edid_property(&radeon_connector->base, edid);
- ret = drm_add_edid_modes(&radeon_connector->base, edid);
- kfree(edid);
+ if (radeon_connector->edid) {
+ drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
+ ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
return ret;
}
drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
@@ -765,7 +753,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
radeon_crtc->rmx_type = radeon_encoder->rmx_type;
memcpy(&radeon_crtc->native_mode,
&radeon_encoder->native_mode,
- sizeof(struct radeon_native_mode));
+ sizeof(struct drm_display_mode));
first = false;
} else {
if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) {
@@ -783,10 +771,10 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
if (radeon_crtc->rmx_type != RMX_OFF) {
fixed20_12 a, b;
a.full = rfixed_const(crtc->mode.vdisplay);
- b.full = rfixed_const(radeon_crtc->native_mode.panel_xres);
+ b.full = rfixed_const(radeon_crtc->native_mode.hdisplay);
radeon_crtc->vsc.full = rfixed_div(a, b);
a.full = rfixed_const(crtc->mode.hdisplay);
- b.full = rfixed_const(radeon_crtc->native_mode.panel_yres);
+ b.full = rfixed_const(radeon_crtc->native_mode.vdisplay);
radeon_crtc->hsc.full = rfixed_div(a, b);
} else {
radeon_crtc->vsc.full = rfixed_const(1);
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index a65ab1a0dad2..d42bc512d75a 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -31,6 +31,10 @@
extern int atom_debug;
+/* evil but including atombios.h is much worse */
+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
+ struct drm_display_mode *mode);
+
uint32_t
radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
{
@@ -167,49 +171,17 @@ void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
- struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
-
- if (mode->hdisplay < native_mode->panel_xres ||
- mode->vdisplay < native_mode->panel_yres) {
- if (ASIC_IS_AVIVO(rdev)) {
- adjusted_mode->hdisplay = native_mode->panel_xres;
- adjusted_mode->vdisplay = native_mode->panel_yres;
- adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
- adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
- adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
- adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
- adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
- adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
- /* update crtc values */
- drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
- /* adjust crtc values */
- adjusted_mode->crtc_hdisplay = native_mode->panel_xres;
- adjusted_mode->crtc_vdisplay = native_mode->panel_yres;
- adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
- adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
- adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
- adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
- adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
- adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
- } else {
- adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
- adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
- adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
- adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
- adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
- adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
- /* update crtc values */
- drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
- /* adjust crtc values */
- adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
- adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
- adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
- adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
- adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
- adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
+ struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+
+ if (mode->hdisplay < native_mode->hdisplay ||
+ mode->vdisplay < native_mode->vdisplay) {
+ int mode_id = adjusted_mode->base.id;
+ *adjusted_mode = *native_mode;
+ if (!ASIC_IS_AVIVO(rdev)) {
+ adjusted_mode->hdisplay = mode->hdisplay;
+ adjusted_mode->vdisplay = mode->vdisplay;
}
- adjusted_mode->flags = native_mode->flags;
- adjusted_mode->clock = native_mode->dotclock;
+ adjusted_mode->base.id = mode_id;
}
}
@@ -219,7 +191,11 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ /* set the active encoder to connector routing */
+ radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
if (radeon_encoder->rmx_type != RMX_OFF)
@@ -230,6 +206,18 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
&& (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+ struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
+ if (tv_dac) {
+ if (tv_dac->tv_std == TV_STD_NTSC ||
+ tv_dac->tv_std == TV_STD_NTSC_J ||
+ tv_dac->tv_std == TV_STD_PAL_M)
+ radeon_atom_get_tv_timings(rdev, 0, adjusted_mode);
+ else
+ radeon_atom_get_tv_timings(rdev, 1, adjusted_mode);
+ }
+ }
+
return true;
}
@@ -461,7 +449,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
case 1:
args.v1.ucMisc = 0;
args.v1.ucAction = action;
- if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+ if (drm_detect_hdmi_monitor(radeon_connector->edid))
args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
@@ -486,7 +474,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
if (dig->coherent_mode)
args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
}
- if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+ if (drm_detect_hdmi_monitor(radeon_connector->edid))
args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
args.v2.ucTruncate = 0;
@@ -544,7 +532,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
- if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+ if (drm_detect_hdmi_monitor(radeon_connector->edid))
return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital)
return ATOM_ENCODER_MODE_DVI;
@@ -554,7 +542,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
case DRM_MODE_CONNECTOR_DVID:
case DRM_MODE_CONNECTOR_HDMIA:
default:
- if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+ if (drm_detect_hdmi_monitor(radeon_connector->edid))
return ATOM_ENCODER_MODE_HDMI;
else
return ATOM_ENCODER_MODE_DVI;
@@ -566,7 +554,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
/*if (radeon_output->MonType == MT_DP)
return ATOM_ENCODER_MODE_DP;
else*/
- if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+ if (drm_detect_hdmi_monitor(radeon_connector->edid))
return ATOM_ENCODER_MODE_HDMI;
else
return ATOM_ENCODER_MODE_DVI;
@@ -734,14 +722,17 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
args.v1.ucAction = action;
-
+ if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+ args.v1.usInitInfo = radeon_connector->connector_object_id;
+ } else {
+ if (radeon_encoder->pixel_clock > 165000)
+ args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
+ else
+ args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+ }
if (ASIC_IS_DCE32(rdev)) {
- if (radeon_encoder->pixel_clock > 165000) {
- args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 2) / 100);
- args.v2.acConfig.fDualLinkConnector = 1;
- } else {
- args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 4) / 100);
- }
+ if (radeon_encoder->pixel_clock > 165000)
+ args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
if (dig->dig_block)
args.v2.acConfig.ucEncoderSel = 1;
@@ -766,7 +757,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
}
} else {
args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
- args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock) / 10);
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
@@ -874,16 +864,9 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
int index = 0;
bool is_dig = false;
- int devices;
memset(&args, 0, sizeof(args));
- /* on DPMS off we have no idea if active device is meaningful */
- if (mode != DRM_MODE_DPMS_ON && !radeon_encoder->active_device)
- devices = radeon_encoder->devices;
- else
- devices = radeon_encoder->active_device;
-
DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
radeon_encoder->encoder_id, mode, radeon_encoder->devices,
radeon_encoder->active_device);
@@ -914,18 +897,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
- if (devices & (ATOM_DEVICE_TV_SUPPORT))
+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
- else if (devices & (ATOM_DEVICE_CV_SUPPORT))
+ else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
else
index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
- if (devices & (ATOM_DEVICE_TV_SUPPORT))
+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
- else if (devices & (ATOM_DEVICE_CV_SUPPORT))
+ else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
else
index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
@@ -1104,8 +1087,11 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder,
}
/* set scaler clears this on some chips */
- if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
- WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN);
+ if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) {
+ if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
+ WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
+ AVIVO_D1MODE_INTERLEAVE_EN);
+ }
}
static void
@@ -1153,6 +1139,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
/* setup and enable the encoder and transmitter */
atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
break;
@@ -1268,8 +1255,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
{
radeon_atom_output_lock(encoder, true);
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
-
- radeon_encoder_set_active_device(encoder);
}
static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index a931af065dd4..a68d7566178c 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -140,15 +140,15 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
WARN(1, "trying to unbind memory to unitialized GART !\n");
return;
}
- t = offset / 4096;
- p = t / (PAGE_SIZE / 4096);
+ t = offset / RADEON_GPU_PAGE_SIZE;
+ p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
for (i = 0; i < pages; i++, p++) {
if (rdev->gart.pages[p]) {
pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p],
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
rdev->gart.pages[p] = NULL;
rdev->gart.pages_addr[p] = 0;
- for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) {
+ for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
radeon_gart_set_page(rdev, t, 0);
}
}
@@ -169,8 +169,8 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
DRM_ERROR("trying to bind memory to unitialized GART !\n");
return -EINVAL;
}
- t = offset / 4096;
- p = t / (PAGE_SIZE / 4096);
+ t = offset / RADEON_GPU_PAGE_SIZE;
+ p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
for (i = 0; i < pages; i++, p++) {
/* we need to support large memory configurations */
@@ -185,9 +185,9 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
}
rdev->gart.pages[p] = pagelist[i];
page_base = rdev->gart.pages_addr[p];
- for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) {
+ for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
radeon_gart_set_page(rdev, t, page_base);
- page_base += 4096;
+ page_base += RADEON_GPU_PAGE_SIZE;
}
}
mb();
@@ -200,14 +200,14 @@ int radeon_gart_init(struct radeon_device *rdev)
if (rdev->gart.pages) {
return 0;
}
- /* We need PAGE_SIZE >= 4096 */
- if (PAGE_SIZE < 4096) {
+ /* We need PAGE_SIZE >= RADEON_GPU_PAGE_SIZE */
+ if (PAGE_SIZE < RADEON_GPU_PAGE_SIZE) {
DRM_ERROR("Page size is smaller than GPU page size!\n");
return -EINVAL;
}
/* Compute table size */
rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE;
- rdev->gart.num_gpu_pages = rdev->mc.gtt_size / 4096;
+ rdev->gart.num_gpu_pages = rdev->mc.gtt_size / RADEON_GPU_PAGE_SIZE;
DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n",
rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages);
/* Allocate pages table */
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 8e0a8759e428..a0fe6232dcb6 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -92,6 +92,13 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
if (r) {
return r;
}
+ /* enable msi */
+ rdev->msi_enabled = 0;
+ if (rdev->family >= CHIP_RV380) {
+ int ret = pci_enable_msi(rdev->pdev);
+ if (!ret)
+ rdev->msi_enabled = 1;
+ }
drm_irq_install(rdev->ddev);
rdev->irq.installed = true;
DRM_INFO("radeon: irq initialized.\n");
@@ -103,5 +110,7 @@ void radeon_irq_kms_fini(struct radeon_device *rdev)
if (rdev->irq.installed) {
rdev->irq.installed = false;
drm_irq_uninstall(rdev->ddev);
+ if (rdev->msi_enabled)
+ pci_disable_msi(rdev->pdev);
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 36410f85d705..8d0b7aa87fa4 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -48,7 +48,7 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active;
u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp;
u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp;
- struct radeon_native_mode *native_mode = &radeon_crtc->native_mode;
+ struct drm_display_mode *native_mode = &radeon_crtc->native_mode;
fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) &
(RADEON_VERT_STRETCH_RESERVED |
@@ -95,19 +95,19 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
fp_horz_vert_active = 0;
- if (native_mode->panel_xres == 0 ||
- native_mode->panel_yres == 0) {
+ if (native_mode->hdisplay == 0 ||
+ native_mode->vdisplay == 0) {
hscale = false;
vscale = false;
} else {
- if (xres > native_mode->panel_xres)
- xres = native_mode->panel_xres;
- if (yres > native_mode->panel_yres)
- yres = native_mode->panel_yres;
+ if (xres > native_mode->hdisplay)
+ xres = native_mode->hdisplay;
+ if (yres > native_mode->vdisplay)
+ yres = native_mode->vdisplay;
- if (xres == native_mode->panel_xres)
+ if (xres == native_mode->hdisplay)
hscale = false;
- if (yres == native_mode->panel_yres)
+ if (yres == native_mode->vdisplay)
vscale = false;
}
@@ -119,11 +119,11 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
else {
inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0;
scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX)
- / native_mode->panel_xres + 1;
+ / native_mode->hdisplay + 1;
fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) |
RADEON_HORZ_STRETCH_BLEND |
RADEON_HORZ_STRETCH_ENABLE |
- ((native_mode->panel_xres/8-1) << 16));
+ ((native_mode->hdisplay/8-1) << 16));
}
if (!vscale)
@@ -131,11 +131,11 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
else {
inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0;
scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX)
- / native_mode->panel_yres + 1;
+ / native_mode->vdisplay + 1;
fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) |
RADEON_VERT_STRETCH_ENABLE |
RADEON_VERT_STRETCH_BLEND |
- ((native_mode->panel_yres-1) << 12));
+ ((native_mode->vdisplay-1) << 12));
}
break;
case RMX_CENTER:
@@ -175,8 +175,8 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
? RADEON_CRTC_V_SYNC_POL
: 0)));
- fp_horz_vert_active = (((native_mode->panel_yres) & 0xfff) |
- (((native_mode->panel_xres / 8) & 0x1ff) << 16));
+ fp_horz_vert_active = (((native_mode->vdisplay) & 0xfff) |
+ (((native_mode->hdisplay / 8) & 0x1ff) << 16));
break;
case RMX_OFF:
default:
@@ -532,6 +532,10 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
radeon_fb = to_radeon_framebuffer(old_fb);
radeon_gem_object_unpin(radeon_fb->obj);
}
+
+ /* Bytes per pixel may have changed */
+ radeon_bandwidth_update(rdev);
+
return 0;
}
@@ -664,6 +668,9 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl);
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+
+ WREG32(RADEON_FP_H2_SYNC_STRT_WID, crtc_h_sync_strt_wid);
+ WREG32(RADEON_FP_V2_SYNC_STRT_WID, crtc_v_sync_strt_wid);
} else {
uint32_t crtc_gen_cntl;
uint32_t crtc_ext_cntl;
@@ -1015,14 +1022,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc,
int x, int y, struct drm_framebuffer *old_fb)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- struct radeon_device *rdev = dev->dev_private;
/* TODO TV */
radeon_crtc_set_base(crtc, x, y, old_fb);
radeon_set_crtc_timing(crtc, adjusted_mode);
radeon_set_pll(crtc, adjusted_mode);
- radeon_bandwidth_update(rdev);
if (radeon_crtc->crtc_id == 0) {
radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode);
} else {
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 6ceb958fd194..00382122869b 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -107,8 +107,6 @@ static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder)
else
radeon_combios_output_lock(encoder, true);
radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF);
-
- radeon_encoder_set_active_device(encoder);
}
static void radeon_legacy_lvds_commit(struct drm_encoder *encoder)
@@ -192,6 +190,8 @@ static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ /* set the active encoder to connector routing */
+ radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
if (radeon_encoder->rmx_type != RMX_OFF)
@@ -218,7 +218,8 @@ static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
-
+ /* set the active encoder to connector routing */
+ radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
return true;
@@ -272,7 +273,6 @@ static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder)
else
radeon_combios_output_lock(encoder, true);
radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
- radeon_encoder_set_active_device(encoder);
}
static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder)
@@ -468,7 +468,6 @@ static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder)
else
radeon_combios_output_lock(encoder, true);
radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF);
- radeon_encoder_set_active_device(encoder);
}
static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder)
@@ -543,6 +542,14 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder,
fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+ fp_gen_cntl &= ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN |
+ RADEON_FP_DFP_SYNC_SEL |
+ RADEON_FP_CRT_SYNC_SEL |
+ RADEON_FP_CRTC_LOCK_8DOT |
+ RADEON_FP_USE_SHADOW_EN |
+ RADEON_FP_CRTC_USE_SHADOW_VEND |
+ RADEON_FP_CRT_SYNC_ALT);
+
if (1) /* FIXME rgbBits == 8 */
fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */
else
@@ -556,7 +563,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder,
else
fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
} else
- fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
+ fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2;
} else {
if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) {
fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
@@ -593,7 +600,8 @@ static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
-
+ /* set the active encoder to connector routing */
+ radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
return true;
@@ -636,7 +644,6 @@ static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder)
else
radeon_combios_output_lock(encoder, true);
radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF);
- radeon_encoder_set_active_device(encoder);
}
static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder)
@@ -735,7 +742,8 @@ static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
-
+ /* set the active encoder to connector routing */
+ radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
return true;
@@ -839,7 +847,6 @@ static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder)
else
radeon_combios_output_lock(encoder, true);
radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
- radeon_encoder_set_active_device(encoder);
}
static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index e61226817ccf..ace726aa0d76 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -172,6 +172,7 @@ enum radeon_connector_table {
struct radeon_mode_info {
struct atom_context *atom_context;
+ struct card_info *atom_card_info;
enum radeon_connector_table connector_table;
bool mode_config_initialized;
struct radeon_crtc *crtcs[2];
@@ -186,17 +187,6 @@ struct radeon_mode_info {
};
-struct radeon_native_mode {
- /* preferred mode */
- uint32_t panel_xres, panel_yres;
- uint32_t hoverplus, hsync_width;
- uint32_t hblank;
- uint32_t voverplus, vsync_width;
- uint32_t vblank;
- uint32_t dotclock;
- uint32_t flags;
-};
-
#define MAX_H_CODE_TIMING_LEN 32
#define MAX_V_CODE_TIMING_LEN 32
@@ -228,7 +218,7 @@ struct radeon_crtc {
enum radeon_rmx_type rmx_type;
fixed20_12 vsc;
fixed20_12 hsc;
- struct radeon_native_mode native_mode;
+ struct drm_display_mode native_mode;
};
struct radeon_encoder_primary_dac {
@@ -248,7 +238,7 @@ struct radeon_encoder_lvds {
bool use_bios_dividers;
uint32_t lvds_gen_cntl;
/* panel mode */
- struct radeon_native_mode native_mode;
+ struct drm_display_mode native_mode;
};
struct radeon_encoder_tv_dac {
@@ -271,6 +261,16 @@ struct radeon_encoder_int_tmds {
struct radeon_tmds_pll tmds_pll[4];
};
+/* spread spectrum */
+struct radeon_atom_ss {
+ uint16_t percentage;
+ uint8_t type;
+ uint8_t step;
+ uint8_t delay;
+ uint8_t range;
+ uint8_t refdiv;
+};
+
struct radeon_encoder_atom_dig {
/* atom dig */
bool coherent_mode;
@@ -278,8 +278,9 @@ struct radeon_encoder_atom_dig {
/* atom lvds */
uint32_t lvds_misc;
uint16_t panel_pwr_delay;
+ struct radeon_atom_ss *ss;
/* panel mode */
- struct radeon_native_mode native_mode;
+ struct drm_display_mode native_mode;
};
struct radeon_encoder_atom_dac {
@@ -294,7 +295,7 @@ struct radeon_encoder {
uint32_t flags;
uint32_t pixel_clock;
enum radeon_rmx_type rmx_type;
- struct radeon_native_mode native_mode;
+ struct drm_display_mode native_mode;
void *enc_priv;
};
@@ -308,12 +309,15 @@ struct radeon_connector {
uint32_t connector_id;
uint32_t devices;
struct radeon_i2c_chan *ddc_bus;
+ /* some systems have a an hdmi and vga port with a shared ddc line */
+ bool shared_ddc;
bool use_digital;
/* we need to mind the EDID between detect
and get modes due to analog/digital/tvencoder */
struct edid *edid;
void *con_priv;
bool dac_load_detect;
+ uint16_t connector_object_id;
};
struct radeon_framebuffer {
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
new file mode 100644
index 000000000000..46146c6a2a06
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -0,0 +1,65 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rafał Miłecki <zajec5@gmail.com>
+ */
+#include "drmP.h"
+#include "radeon.h"
+
+int radeon_debugfs_pm_init(struct radeon_device *rdev);
+
+int radeon_pm_init(struct radeon_device *rdev)
+{
+ if (radeon_debugfs_pm_init(rdev)) {
+ DRM_ERROR("Failed to register debugfs file for CP !\n");
+ }
+
+ return 0;
+}
+
+/*
+ * Debugfs info
+ */
+#if defined(CONFIG_DEBUG_FS)
+
+static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct radeon_device *rdev = dev->dev_private;
+
+ seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev));
+ seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev));
+
+ return 0;
+}
+
+static struct drm_info_list radeon_pm_info_list[] = {
+ {"radeon_pm_info", radeon_debugfs_pm_info, 0, NULL},
+};
+#endif
+
+int radeon_debugfs_pm_init(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+ return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list));
+#else
+ return 0;
+#endif
+}
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
index bfa1ab9c93e1..29ab75903ec1 100644
--- a/drivers/gpu/drm/radeon/radeon_reg.h
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
@@ -290,6 +290,8 @@
#define RADEON_BUS_CNTL 0x0030
# define RADEON_BUS_MASTER_DIS (1 << 6)
# define RADEON_BUS_BIOS_DIS_ROM (1 << 12)
+# define RS600_BUS_MASTER_DIS (1 << 14)
+# define RS600_MSI_REARM (1 << 20) /* rs600/rs690/rs740 */
# define RADEON_BUS_RD_DISCARD_EN (1 << 24)
# define RADEON_BUS_RD_ABORT_EN (1 << 25)
# define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28)
@@ -297,6 +299,9 @@
# define RADEON_BUS_READ_BURST (1 << 30)
#define RADEON_BUS_CNTL1 0x0034
# define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4)
+/* rv370/rv380, rv410, r423/r430/r480, r5xx */
+#define RADEON_MSI_REARM_EN 0x0160
+# define RV370_MSI_REARM_EN (1 << 0)
/* #define RADEON_PCIE_INDEX 0x0030 */
/* #define RADEON_PCIE_DATA 0x0034 */
@@ -3311,6 +3316,7 @@
#define RADEON_AIC_CNTL 0x01d0
# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
# define RADEON_DIS_OUT_OF_PCI_GART_ACCESS (1 << 1)
+# define RS400_MSI_REARM (1 << 3) /* rs400/rs480 */
#define RADEON_AIC_LO_ADDR 0x01dc
#define RADEON_AIC_PT_BASE 0x01d8
#define RADEON_AIC_HI_ADDR 0x01e0
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index 03c33cf4e14c..f8a465d9a1cf 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -42,7 +42,7 @@ void radeon_test_moves(struct radeon_device *rdev)
/* Number of tests =
* (Total GTT - IB pool - writeback page - ring buffer) / test size
*/
- n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - 4096 -
+ n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE -
rdev->cp.ring_size) / size;
gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL);
@@ -102,7 +102,7 @@ void radeon_test_moves(struct radeon_device *rdev)
goto out_cleanup;
}
- r = radeon_copy(rdev, gtt_addr, vram_addr, size / 4096, fence);
+ r = radeon_copy(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, fence);
if (r) {
DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
goto out_cleanup;
@@ -145,7 +145,7 @@ void radeon_test_moves(struct radeon_device *rdev)
goto out_cleanup;
}
- r = radeon_copy(rdev, vram_addr, gtt_addr, size / 4096, fence);
+ r = radeon_copy(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, fence);
if (r) {
DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
goto out_cleanup;
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 765bd184b6fc..1381e06d6af3 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -295,6 +295,12 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
if (unlikely(r)) {
return r;
}
+
+ r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement);
+ if (unlikely(r)) {
+ goto out_cleanup;
+ }
+
r = ttm_tt_bind(bo->ttm, &tmp_mem);
if (unlikely(r)) {
goto out_cleanup;
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index a769c296f6a6..ca037160a582 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -418,6 +418,8 @@ int rs400_resume(struct radeon_device *rdev)
rs400_gart_disable(rdev);
/* Resume clock before doing reset */
r300_clock_startup(rdev);
+ /* setup MC before calling post tables */
+ rs400_mc_program(rdev);
/* Reset gpu before posting otherwise ATOM will enter infinite loop */
if (radeon_gpu_reset(rdev)) {
dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 10dfa78762da..5f117cd8736a 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -242,7 +242,7 @@ void rs600_irq_disable(struct radeon_device *rdev)
int rs600_irq_process(struct radeon_device *rdev)
{
- uint32_t status;
+ uint32_t status, msi_rearm;
uint32_t r500_disp_int;
status = rs600_irq_ack(rdev, &r500_disp_int);
@@ -260,6 +260,22 @@ int rs600_irq_process(struct radeon_device *rdev)
drm_handle_vblank(rdev->ddev, 1);
status = rs600_irq_ack(rdev, &r500_disp_int);
}
+ if (rdev->msi_enabled) {
+ switch (rdev->family) {
+ case CHIP_RS600:
+ case CHIP_RS690:
+ case CHIP_RS740:
+ msi_rearm = RREG32(RADEON_BUS_CNTL) & ~RS600_MSI_REARM;
+ WREG32(RADEON_BUS_CNTL, msi_rearm);
+ WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM);
+ break;
+ default:
+ msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
+ WREG32(RADEON_MSI_REARM_EN, msi_rearm);
+ WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+ break;
+ }
+ }
return IRQ_HANDLED;
}
@@ -472,6 +488,8 @@ int rs600_init(struct radeon_device *rdev)
}
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
+ /* Initialize power management */
+ radeon_pm_init(rdev);
/* Get vram informations */
rs600_vram_info(rdev);
/* Initialize memory controller (also test AGP) */
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 025e3225346c..27547175cf93 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -706,6 +706,8 @@ int rs690_init(struct radeon_device *rdev)
}
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
+ /* Initialize power management */
+ radeon_pm_init(rdev);
/* Get vram informations */
rs690_vram_info(rdev);
/* Initialize memory controller (also test AGP) */
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 41a34c23e6d8..ba68c9fe90a1 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -380,7 +380,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL);
/* Stop all video */
- WREG32(R_000330_D1VGA_CONTROL, 0);
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
WREG32(R_000300_VGA_RENDER_CONTROL, 0);
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
@@ -389,6 +388,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
WREG32(R_006880_D2CRTC_CONTROL, 0);
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
+ WREG32(R_000330_D1VGA_CONTROL, 0);
+ WREG32(R_000338_D2VGA_CONTROL, 0);
}
void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
@@ -402,14 +403,14 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control);
mdelay(1);
/* Restore video state */
+ WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
+ WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1);
WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control);
WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control);
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
- WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
- WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
}
@@ -585,6 +586,8 @@ int rv515_init(struct radeon_device *rdev)
}
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
+ /* Initialize power management */
+ radeon_pm_init(rdev);
/* Get vram informations */
rv515_vram_info(rdev);
/* Initialize memory controller (also test AGP) */
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 595ac638039d..b0efd0ddae7a 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -529,11 +529,11 @@ static void rv770_gpu_init(struct radeon_device *rdev)
if (rdev->family == CHIP_RV770)
gb_tiling_config |= BANK_TILING(1);
else
- gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_SHIFT) >> NOOFBANK_MASK);
+ gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
gb_tiling_config |= GROUP_SIZE(0);
- if (((mc_arb_ramcfg & NOOFROWS_MASK) & NOOFROWS_SHIFT) > 3) {
+ if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) {
gb_tiling_config |= ROW_TILING(3);
gb_tiling_config |= SAMPLE_SPLIT(3);
} else {
@@ -579,14 +579,14 @@ static void rv770_gpu_init(struct radeon_device *rdev)
/* set HW defaults for 3D engine */
WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
- ROQ_IB2_START(0x2b)));
+ ROQ_IB2_START(0x2b)));
WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO |
- SYNC_GRADIENT |
- SYNC_WALKER |
- SYNC_ALIGNER));
+ SYNC_GRADIENT |
+ SYNC_WALKER |
+ SYNC_ALIGNER));
sx_debug_1 = RREG32(SX_DEBUG_1);
sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
@@ -598,9 +598,9 @@ static void rv770_gpu_init(struct radeon_device *rdev)
WREG32(SMX_DC_CTL0, smx_dc_ctl0);
WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
- GS_FLUSH_CTL(4) |
- ACK_FLUSH_CTL(3) |
- SYNC_FLUSH_CTL));
+ GS_FLUSH_CTL(4) |
+ ACK_FLUSH_CTL(3) |
+ SYNC_FLUSH_CTL));
if (rdev->family == CHIP_RV770)
WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f));
@@ -611,12 +611,12 @@ static void rv770_gpu_init(struct radeon_device *rdev)
}
WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) |
- POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) |
- SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1)));
+ POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) |
+ SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1)));
WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) |
- SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) |
- SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize)));
+ SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) |
+ SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize)));
WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
@@ -774,14 +774,36 @@ int rv770_mc_init(struct radeon_device *rdev)
{
fixed20_12 a;
u32 tmp;
+ int chansize, numchan;
int r;
/* Get VRAM informations */
- /* FIXME: Don't know how to determine vram width, need to check
- * vram_width usage
- */
- rdev->mc.vram_width = 128;
rdev->mc.vram_is_ddr = true;
+ tmp = RREG32(MC_ARB_RAMCFG);
+ if (tmp & CHANSIZE_OVERRIDE) {
+ chansize = 16;
+ } else if (tmp & CHANSIZE_MASK) {
+ chansize = 64;
+ } else {
+ chansize = 32;
+ }
+ tmp = RREG32(MC_SHARED_CHMAP);
+ switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
+ case 0:
+ default:
+ numchan = 1;
+ break;
+ case 1:
+ numchan = 2;
+ break;
+ case 2:
+ numchan = 4;
+ break;
+ case 3:
+ numchan = 8;
+ break;
+ }
+ rdev->mc.vram_width = numchan * chansize;
/* Could aper size report 0 ? */
rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
@@ -961,10 +983,13 @@ int rv770_init(struct radeon_device *rdev)
r600_scratch_init(rdev);
/* Initialize surface registers */
radeon_surface_init(rdev);
+ /* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
r = radeon_clocks_init(rdev);
if (r)
return r;
+ /* Initialize power management */
+ radeon_pm_init(rdev);
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h
index 4b9c3d6396ff..a1367ab6f261 100644
--- a/drivers/gpu/drm/radeon/rv770d.h
+++ b/drivers/gpu/drm/radeon/rv770d.h
@@ -129,6 +129,10 @@
#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
#define HDP_TILING_CONFIG 0x2F3C
+#define MC_SHARED_CHMAP 0x2004
+#define NOOFCHAN_SHIFT 12
+#define NOOFCHAN_MASK 0x00003000
+
#define MC_ARB_RAMCFG 0x2760
#define NOOFBANK_SHIFT 0
#define NOOFBANK_MASK 0x00000003
@@ -142,6 +146,7 @@
#define CHANSIZE_MASK 0x00000100
#define BURSTLENGTH_SHIFT 9
#define BURSTLENGTH_MASK 0x00000200
+#define CHANSIZE_OVERRIDE (1 << 11)
#define MC_VM_AGP_TOP 0x2028
#define MC_VM_AGP_BOT 0x202C
#define MC_VM_AGP_BASE 0x2030
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index a55ee1a56c16..7bcb89f39ce8 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -279,6 +279,7 @@ int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement)
return ttm_tt_set_caching(ttm, state);
}
+EXPORT_SYMBOL(ttm_tt_set_placement_caching);
static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
{
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index e2e8741fdb53..80792d38d25c 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -39,8 +39,6 @@
* Version Information
*/
-#define DRIVER_VERSION "v2.6"
-#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Jiri Kosina"
#define DRIVER_DESC "HID core driver"
#define DRIVER_LICENSE "GPL"
@@ -1327,6 +1325,8 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
@@ -1621,6 +1621,7 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_KYE, 0x0058) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) },
@@ -1919,5 +1920,8 @@ static void __exit hid_exit(void)
module_init(hid_init);
module_exit(hid_exit);
+MODULE_AUTHOR("Andreas Gal");
+MODULE_AUTHOR("Vojtech Pavlik");
+MODULE_AUTHOR("Jiri Kosina");
MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 0ceabbb8e019..3839340e293a 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -117,6 +117,7 @@
#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2
#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4
#define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff
+#define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK 0x00d3
#define USB_VENDOR_ID_CHERRY 0x046a
#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
@@ -305,6 +306,8 @@
#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
+#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
+#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
#define USB_DEVICE_ID_DINOVO_MINI 0xc71f
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 4a489785647a..9fcd3d017ab3 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -33,6 +33,7 @@
#define LG_NOGET 0x100
#define LG_FF 0x200
#define LG_FF2 0x400
+#define LG_RDESC_REL_ABS 0x800
/*
* Certain Logitech keyboards send in report #3 keys which are far
@@ -51,6 +52,13 @@ static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[84] = rdesc[89] = 0x4d;
rdesc[85] = rdesc[90] = 0x10;
}
+ if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 &&
+ rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
+ rdesc[49] == 0x81 && rdesc[50] == 0x06) {
+ dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
+ "report descriptor\n");
+ rdesc[33] = rdesc[50] = 0x02;
+ }
}
#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
@@ -323,8 +331,13 @@ static const struct hid_device_id lg_devices[] = {
.driver_data = LG_FF },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
.driver_data = LG_FF2 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
+ .driver_data = LG_RDESC_REL_ABS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
+ .driver_data = LG_RDESC_REL_ABS },
{ }
};
+
MODULE_DEVICE_TABLE(hid, lg_devices);
static struct hid_driver lg_driver = {
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 03bd703255a3..0258289f3b3e 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -41,8 +41,6 @@
* Version Information
*/
-#define DRIVER_VERSION "v2.6"
-#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Jiri Kosina"
#define DRIVER_DESC "USB HID core driver"
#define DRIVER_LICENSE "GPL"
@@ -998,7 +996,8 @@ static int usbhid_start(struct hid_device *hid)
usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
- usbhid_init_reports(hid);
+ if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
+ usbhid_init_reports(hid);
set_bit(HID_STARTED, &usbhid->iofl);
@@ -1395,8 +1394,7 @@ static int __init hid_init(void)
retval = usb_register(&hid_driver);
if (retval)
goto usb_register_fail;
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
- DRIVER_DESC "\n");
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
return 0;
usb_register_fail:
@@ -1423,6 +1421,8 @@ static void __exit hid_exit(void)
module_init(hid_init);
module_exit(hid_exit);
-MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_AUTHOR("Andreas Gal");
+MODULE_AUTHOR("Vojtech Pavlik");
+MODULE_AUTHOR("Jiri Kosina");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index e9875625dcf0..38773dc2821b 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -54,6 +54,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
@@ -281,7 +282,7 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
if (idVendor == USB_VENDOR_ID_NCR &&
idProduct >= USB_DEVICE_ID_NCR_FIRST &&
idProduct <= USB_DEVICE_ID_NCR_LAST)
- return HID_QUIRK_NOGET;
+ return HID_QUIRK_NO_INIT_REPORTS;
down_read(&dquirks_rwsem);
bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 8b6ee247bfe4..867e08433e4b 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -450,7 +450,6 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
if (!uref_multi)
return -ENOMEM;
- lock_kernel();
uref = &uref_multi->uref;
if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
if (copy_from_user(uref_multi, user_arg,
@@ -528,7 +527,6 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
case HIDIOCGCOLLECTIONINDEX:
i = field->usage[uref->usage_index].collection_index;
- unlock_kernel();
kfree(uref_multi);
return i;
case HIDIOCGUSAGES:
@@ -547,15 +545,12 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
}
goodreturn:
- unlock_kernel();
kfree(uref_multi);
return 0;
fault:
- unlock_kernel();
kfree(uref_multi);
return -EFAULT;
inval:
- unlock_kernel();
kfree(uref_multi);
return -EINVAL;
}
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index d39877a7da63..b5a95193c694 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -350,8 +350,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
case FAULT:
/* Note - only for remote1 and remote2 */
- out = data->alarms & (sattr->index ? 0x8000 : 0x4000);
- out = out ? 0 : 1;
+ out = !!(data->alarms & (sattr->index ? 0x8000 : 0x4000));
break;
default:
@@ -863,7 +862,7 @@ static SENSOR_DEVICE_ATTR_2(pwm1_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
set_pwmfreq, INPUT, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_enable, S_IRUGO | S_IWUSR, show_pwmctrl,
set_pwmctrl, INPUT, 0);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_channel_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_channels_temp, S_IRUGO | S_IWUSR,
show_pwmchan, set_pwmchan, INPUT, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
set_pwm, MIN, 0);
@@ -875,7 +874,7 @@ static SENSOR_DEVICE_ATTR_2(pwm2_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
set_pwmfreq, INPUT, 1);
static SENSOR_DEVICE_ATTR_2(pwm2_enable, S_IRUGO | S_IWUSR, show_pwmctrl,
set_pwmctrl, INPUT, 1);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_channel_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_channels_temp, S_IRUGO | S_IWUSR,
show_pwmchan, set_pwmchan, INPUT, 1);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
set_pwm, MIN, 1);
@@ -887,7 +886,7 @@ static SENSOR_DEVICE_ATTR_2(pwm3_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
set_pwmfreq, INPUT, 2);
static SENSOR_DEVICE_ATTR_2(pwm3_enable, S_IRUGO | S_IWUSR, show_pwmctrl,
set_pwmctrl, INPUT, 2);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_channel_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_channels_temp, S_IRUGO | S_IWUSR,
show_pwmchan, set_pwmchan, INPUT, 2);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
set_pwm, MIN, 2);
@@ -947,19 +946,19 @@ static struct attribute *adt7475_attrs[] = {
&sensor_dev_attr_pwm1.dev_attr.attr,
&sensor_dev_attr_pwm1_freq.dev_attr.attr,
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
- &sensor_dev_attr_pwm1_auto_channel_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
&sensor_dev_attr_pwm2.dev_attr.attr,
&sensor_dev_attr_pwm2_freq.dev_attr.attr,
&sensor_dev_attr_pwm2_enable.dev_attr.attr,
- &sensor_dev_attr_pwm2_auto_channel_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
&sensor_dev_attr_pwm3.dev_attr.attr,
&sensor_dev_attr_pwm3_freq.dev_attr.attr,
&sensor_dev_attr_pwm3_enable.dev_attr.attr,
- &sensor_dev_attr_pwm3_auto_channel_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
NULL,
@@ -1152,7 +1151,7 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
}
/* Limits and settings, should never change update every 60 seconds */
- if (time_after(jiffies, data->limits_updated + HZ * 2) ||
+ if (time_after(jiffies, data->limits_updated + HZ * 60) ||
!data->valid) {
data->config5 = adt7475_read(REG_CONFIG5);
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index 2c2cb1ec94c5..27d62574284f 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -572,7 +572,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
/* Sample register contents every 1 sec */
if (time_after(jiffies, data->last_update + HZ) || !data->valid) {
- if (data->type != sch5027) {
+ if (data->type == dme1737) {
data->vid = dme1737_read(data, DME1737_REG_VID) &
0x3f;
}
@@ -1621,9 +1621,6 @@ static struct attribute *dme1737_misc_attr[] = {
&sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
&sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
&sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr,
- /* Misc */
- &dev_attr_vrm.attr,
- &dev_attr_cpu0_vid.attr,
NULL
};
@@ -1631,6 +1628,18 @@ static const struct attribute_group dme1737_misc_group = {
.attrs = dme1737_misc_attr,
};
+/* The following struct holds VID-related attributes. Their creation
+ depends on the chip type which is determined during module load. */
+static struct attribute *dme1737_vid_attr[] = {
+ &dev_attr_vrm.attr,
+ &dev_attr_cpu0_vid.attr,
+ NULL
+};
+
+static const struct attribute_group dme1737_vid_group = {
+ .attrs = dme1737_vid_attr,
+};
+
/* The following structs hold the PWM attributes, some of which are optional.
* Their creation depends on the chip configuration which is determined during
* module load. */
@@ -1902,6 +1911,9 @@ static void dme1737_remove_files(struct device *dev)
if (data->type != sch5027) {
sysfs_remove_group(&dev->kobj, &dme1737_misc_group);
}
+ if (data->type == dme1737) {
+ sysfs_remove_group(&dev->kobj, &dme1737_vid_group);
+ }
sysfs_remove_group(&dev->kobj, &dme1737_group);
@@ -1933,6 +1945,13 @@ static int dme1737_create_files(struct device *dev)
goto exit_remove;
}
+ /* Create VID-related sysfs attributes */
+ if ((data->type == dme1737) &&
+ (err = sysfs_create_group(&dev->kobj,
+ &dme1737_vid_group))) {
+ goto exit_remove;
+ }
+
/* Create fan sysfs attributes */
for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
if (data->has_fan & (1 << ix)) {
@@ -2127,7 +2146,7 @@ static int dme1737_init_device(struct device *dev)
data->pwm_acz[2] = 4; /* pwm3 -> zone3 */
/* Set VRM */
- if (data->type != sch5027) {
+ if (data->type == dme1737) {
data->vrm = vid_which_vrm();
}
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index 2a7a85a6dc36..da1b1f9488af 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -819,7 +819,7 @@ static int watchdog_release(struct inode *inode, struct file *filp)
static ssize_t watchdog_write(struct file *filp, const char __user *buf,
size_t count, loff_t *offset)
{
- size_t ret;
+ int ret;
struct fschmd_data *data = filp->private_data;
if (count) {
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 6679854c85b0..be475e844c2a 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -197,11 +197,13 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted),
AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd),
- AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
+ AXIS_DMI_MATCH("NC6730b", "HP Compaq 6730b", xy_rotated_left_usd),
+ AXIS_DMI_MATCH("NC6730s", "HP Compaq 6730s", xy_swap),
AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
AXIS_DMI_MATCH("NC6710x", "HP Compaq 6710", xy_swap_yz_inverted),
AXIS_DMI_MATCH("NC6715x", "HP Compaq 6715", y_inverted),
AXIS_DMI_MATCH("NC693xx", "HP EliteBook 693", xy_rotated_right),
+ AXIS_DMI_MATCH("NC693xx", "HP EliteBook 853", xy_swap),
/* Intel-based HP Pavilion dv5 */
AXIS_DMI_MATCH2("HPDV5_I",
PRODUCT_NAME, "HP Pavilion dv5",
@@ -214,6 +216,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
y_inverted),
AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted),
AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted),
+ AXIS_DMI_MATCH("HDX18", "HP HDX 18", x_inverted),
{ NULL, }
/* Laptop models without axis info (yet):
* "NC6910" "HP Compaq 6910"
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index ffeb2a10e1a7..a3749cb0f181 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1028,12 +1028,11 @@ static int __init it87_find(unsigned short *address,
chip_type, *address, sio_data->revision);
/* Read GPIO config and VID value from LDN 7 (GPIO) */
- if (chip_type != IT8705F_DEVID) {
+ if (sio_data->type != it87) {
int reg;
superio_select(GPIO);
- if ((chip_type == it8718) ||
- (chip_type == it8720))
+ if (sio_data->type == it8718 || sio_data->type == it8720)
sio_data->vid_value = superio_inb(IT87_SIO_VID_REG);
reg = superio_inb(IT87_SIO_PINX2_REG);
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
index 3a524f2fe493..71835412529f 100644
--- a/drivers/hwmon/s3c-hwmon.c
+++ b/drivers/hwmon/s3c-hwmon.c
@@ -323,14 +323,21 @@ static int __devinit s3c_hwmon_probe(struct platform_device *dev)
}
for (i = 0; i < ARRAY_SIZE(pdata->in); i++) {
- if (!pdata->in[i])
+ struct s3c24xx_adc_hwmon_incfg *cfg = pdata->in[i];
+
+ if (!cfg)
continue;
- if (pdata->in[i]->mult >= 0x10000)
+ if (cfg->mult >= 0x10000)
dev_warn(&dev->dev,
"channel %d multiplier too large\n",
i);
+ if (cfg->divider == 0) {
+ dev_err(&dev->dev, "channel %d divider zero\n", i);
+ continue;
+ }
+
ret = s3c_hwmon_create_attr(&dev->dev, pdata->in[i],
&hwmon->attrs[i], i);
if (ret) {
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 737335ff2b21..e8fe7f169e25 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -128,7 +128,7 @@ config I2C_PIIX4
ATI SB600
ATI SB700
ATI SB800
- AMD SB900
+ AMD Hudson-2
Serverworks OSB4
Serverworks CSB5
Serverworks CSB6
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 4afba3ec2a61..e3654d683e15 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -120,19 +120,26 @@ struct imx_i2c_struct {
wait_queue_head_t queue;
unsigned long i2csr;
unsigned int disable_delay;
+ int stopped;
+ unsigned int ifdr; /* IMX_I2C_IFDR */
};
/** Functions for IMX I2C adapter driver ***************************************
*******************************************************************************/
-static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx)
+static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
{
unsigned long orig_jiffies = jiffies;
+ unsigned int temp;
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
- /* wait for bus not busy */
- while (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_IBB) {
+ while (1) {
+ temp = readb(i2c_imx->base + IMX_I2C_I2SR);
+ if (for_busy && (temp & I2SR_IBB))
+ break;
+ if (!for_busy && !(temp & I2SR_IBB))
+ break;
if (signal_pending(current)) {
dev_dbg(&i2c_imx->adapter.dev,
"<%s> I2C Interrupted\n", __func__);
@@ -179,41 +186,62 @@ static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
return 0;
}
-static void i2c_imx_start(struct imx_i2c_struct *i2c_imx)
+static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
{
unsigned int temp = 0;
+ int result;
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+ clk_enable(i2c_imx->clk);
+ writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR);
/* Enable I2C controller */
+ writeb(0, i2c_imx->base + IMX_I2C_I2SR);
writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
+
+ /* Wait controller to be stable */
+ udelay(50);
+
/* Start I2C transaction */
temp = readb(i2c_imx->base + IMX_I2C_I2CR);
temp |= I2CR_MSTA;
writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ result = i2c_imx_bus_busy(i2c_imx, 1);
+ if (result)
+ return result;
+ i2c_imx->stopped = 0;
+
temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ return result;
}
static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
{
unsigned int temp = 0;
- /* Stop I2C transaction */
- dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
- temp = readb(i2c_imx->base + IMX_I2C_I2CR);
- temp &= ~I2CR_MSTA;
- writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
- /* setup chip registers to defaults */
- writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
- writeb(0, i2c_imx->base + IMX_I2C_I2SR);
- /*
- * This delay caused by an i.MXL hardware bug.
- * If no (or too short) delay, no "STOP" bit will be generated.
- */
- udelay(i2c_imx->disable_delay);
+ if (!i2c_imx->stopped) {
+ /* Stop I2C transaction */
+ dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+ temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+ temp &= ~(I2CR_MSTA | I2CR_MTX);
+ writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ i2c_imx->stopped = 1;
+ }
+ if (cpu_is_mx1()) {
+ /*
+ * This delay caused by an i.MXL hardware bug.
+ * If no (or too short) delay, no "STOP" bit will be generated.
+ */
+ udelay(i2c_imx->disable_delay);
+ }
+
+ if (!i2c_imx->stopped)
+ i2c_imx_bus_busy(i2c_imx, 0);
+
/* Disable I2C controller */
writeb(0, i2c_imx->base + IMX_I2C_I2CR);
+ clk_disable(i2c_imx->clk);
}
static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
@@ -233,8 +261,8 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
else
for (i = 0; i2c_clk_div[i][0] < div; i++);
- /* Write divider value to register */
- writeb(i2c_clk_div[i][1], i2c_imx->base + IMX_I2C_IFDR);
+ /* Store divider value */
+ i2c_imx->ifdr = i2c_clk_div[i][1];
/*
* There dummy delay is calculated.
@@ -341,11 +369,15 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
if (result)
return result;
if (i == (msgs->len - 1)) {
+ /* It must generate STOP before read I2DR to prevent
+ controller from generating another clock cycle */
dev_dbg(&i2c_imx->adapter.dev,
"<%s> clear MSTA\n", __func__);
temp = readb(i2c_imx->base + IMX_I2C_I2CR);
- temp &= ~I2CR_MSTA;
+ temp &= ~(I2CR_MSTA | I2CR_MTX);
writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ i2c_imx_bus_busy(i2c_imx, 0);
+ i2c_imx->stopped = 1;
} else if (i == (msgs->len - 2)) {
dev_dbg(&i2c_imx->adapter.dev,
"<%s> set TXAK\n", __func__);
@@ -370,14 +402,11 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
- /* Check if i2c bus is not busy */
- result = i2c_imx_bus_busy(i2c_imx);
+ /* Start I2C transfer */
+ result = i2c_imx_start(i2c_imx);
if (result)
goto fail0;
- /* Start I2C transfer */
- i2c_imx_start(i2c_imx);
-
/* read/write data */
for (i = 0; i < num; i++) {
if (i) {
@@ -386,6 +415,9 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
temp = readb(i2c_imx->base + IMX_I2C_I2CR);
temp |= I2CR_RSTA;
writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ result = i2c_imx_bus_busy(i2c_imx, 1);
+ if (result)
+ goto fail0;
}
dev_dbg(&i2c_imx->adapter.dev,
"<%s> transfer message: %d\n", __func__, i);
@@ -500,7 +532,6 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "can't get I2C clock\n");
goto fail3;
}
- clk_enable(i2c_imx->clk);
/* Request IRQ */
ret = request_irq(i2c_imx->irq, i2c_imx_isr, 0, pdev->name, i2c_imx);
@@ -549,7 +580,6 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
fail5:
free_irq(i2c_imx->irq, i2c_imx);
fail4:
- clk_disable(i2c_imx->clk);
clk_put(i2c_imx->clk);
fail3:
release_mem_region(i2c_imx->res->start, resource_size(res));
@@ -586,8 +616,6 @@ static int __exit i2c_imx_remove(struct platform_device *pdev)
if (pdata && pdata->exit)
pdata->exit(&pdev->dev);
- /* Disable I2C clock */
- clk_disable(i2c_imx->clk);
clk_put(i2c_imx->clk);
release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res));
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index d325e86e3103..f627001108b8 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -365,9 +365,6 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
unsigned timeout = i2c->adap.timeout;
u32 flags = restart ? CCR_RSTA : 0;
- /* Start with MEN */
- if (!restart)
- writeccr(i2c, CCR_MEN);
/* Start as master */
writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);
/* Write target byte */
@@ -396,9 +393,6 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
int i, result;
u32 flags = restart ? CCR_RSTA : 0;
- /* Start with MEN */
- if (!restart)
- writeccr(i2c, CCR_MEN);
/* Switch to read - restart */
writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);
/* Write target address byte - this time with the read flag set */
@@ -425,9 +419,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
/* Generate txack on next to last byte */
if (i == length - 2)
writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);
- /* Generate stop on last byte */
+ /* Do not generate stop on last byte */
if (i == length - 1)
- writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_TXAK);
+ writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX);
data[i] = readb(i2c->base + MPC_I2C_DR);
}
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index d26a972aacaa..1e245e9cad31 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -22,7 +22,7 @@
Intel PIIX4, 440MX
Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
ATI IXP200, IXP300, IXP400, SB600, SB700, SB800
- AMD SB900
+ AMD Hudson-2
SMSC Victory66
Note: we assume there can only be one device, with one SMBus interface.
@@ -233,9 +233,9 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
unsigned short smba_idx = 0xcd6;
u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c;
- /* SB800 SMBus does not support forcing address */
+ /* SB800 and later SMBus does not support forcing address */
if (force || force_addr) {
- dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support "
+ dev_err(&PIIX4_dev->dev, "SMBus does not support "
"forcing address!\n");
return -EINVAL;
}
@@ -480,7 +480,7 @@ static struct pci_device_id piix4_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB900_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_OSB4) },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index 6ff6c20f1e78..fbab6846ae64 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -19,7 +19,9 @@
#include <linux/completion.h>
#include <linux/platform_device.h>
#include <linux/i2c-pnx.h>
+#include <linux/io.h>
#include <mach/hardware.h>
+#include <mach/i2c.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
@@ -54,6 +56,9 @@ static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap)
struct timer_list *timer = &data->mif.timer;
int expires = I2C_PNX_TIMEOUT / (1000 / HZ);
+ if (expires <= 1)
+ expires = 2;
+
del_timer_sync(timer);
dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n",
@@ -645,7 +650,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
return 0;
out_irq:
- free_irq(alg_data->irq, alg_data);
+ free_irq(alg_data->irq, i2c_pnx->adapter);
out_clock:
i2c_pnx->set_clock_stop(pdev);
out_unmap:
@@ -664,7 +669,7 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev)
struct i2c_adapter *adap = i2c_pnx->adapter;
struct i2c_pnx_algo_data *alg_data = adap->algo_data;
- free_irq(alg_data->irq, alg_data);
+ free_irq(alg_data->irq, i2c_pnx->adapter);
i2c_del_adapter(adap);
i2c_pnx->set_clock_stop(pdev);
iounmap((void *)alg_data->ioaddr);
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
index aa96bd2d27ea..a0702f36a72f 100644
--- a/drivers/i2c/chips/tsl2550.c
+++ b/drivers/i2c/chips/tsl2550.c
@@ -257,6 +257,7 @@ static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
{
+ struct tsl2550_data *data = i2c_get_clientdata(client);
u8 ch0, ch1;
int ret;
@@ -274,6 +275,8 @@ static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
ret = tsl2550_calculate_lux(ch0, ch1);
if (ret < 0)
return ret;
+ if (data->operating_mode == 1)
+ ret *= 5;
return sprintf(buf, "%d\n", ret);
}
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 8d80fceca6a4..296504355142 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -762,6 +762,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
{
int res = 0;
struct i2c_adapter *found;
+ struct i2c_client *client, *next;
/* First make sure that this adapter was ever added */
mutex_lock(&core_lock);
@@ -781,6 +782,16 @@ int i2c_del_adapter(struct i2c_adapter *adap)
if (res)
return res;
+ /* Remove devices instantiated from sysfs */
+ list_for_each_entry_safe(client, next, &userspace_devices, detected) {
+ if (client->adapter == adap) {
+ dev_dbg(&adap->dev, "Removing %s at 0x%x\n",
+ client->name, client->addr);
+ list_del(&client->detected);
+ i2c_unregister_device(client);
+ }
+ }
+
/* Detach any active clients. This can't fail, thus we do not
checking the returned value. */
res = device_for_each_child(&adap->dev, NULL, __unregister_client);
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c
index 6396c3ad3252..837322b10a4c 100644
--- a/drivers/ide/atiixp.c
+++ b/drivers/ide/atiixp.c
@@ -177,7 +177,7 @@ static const struct pci_device_id atiixp_pci_tbl[] = {
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), 0 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), 1 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), 0 },
- { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_SB900_IDE), 0 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 680e5975217f..ca0c46f6580a 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -379,7 +379,8 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
.enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
.port_ops = &cmd64x_port_ops,
.host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
- IDE_HFLAG_ABUSE_PREFETCH,
+ IDE_HFLAG_ABUSE_PREFETCH |
+ IDE_HFLAG_SERIALIZE,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = 0x00, /* no udma */
@@ -389,7 +390,8 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
.init_chipset = init_chipset_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
.port_ops = &cmd648_port_ops,
- .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH |
+ IDE_HFLAG_SERIALIZE,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index 063b933d864a..dd6396384c25 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -60,15 +60,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
MODULE_LICENSE("Dual MPL/GPL");
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
-
-#ifdef CONFIG_PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
-
/*====================================================================*/
typedef struct ide_info_t {
@@ -98,7 +89,7 @@ static int ide_probe(struct pcmcia_device *link)
{
ide_info_t *info;
- DEBUG(0, "ide_attach()\n");
+ dev_dbg(&link->dev, "ide_attach()\n");
/* Create new ide device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -112,7 +103,6 @@ static int ide_probe(struct pcmcia_device *link)
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = 3;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -134,7 +124,7 @@ static void ide_detach(struct pcmcia_device *link)
ide_hwif_t *hwif = info->host->ports[0];
unsigned long data_addr, ctl_addr;
- DEBUG(0, "ide_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
data_addr = hwif->io_ports.data_addr;
ctl_addr = hwif->io_ports.ctl_addr;
@@ -217,9 +207,6 @@ out_release:
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
struct pcmcia_config_check {
unsigned long ctl_base;
int skip_vcc;
@@ -282,11 +269,11 @@ static int ide_config(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
struct pcmcia_config_check *stk = NULL;
- int last_ret = 0, last_fn = 0, is_kme = 0;
+ int ret = 0, is_kme = 0;
unsigned long io_base, ctl_base;
struct ide_host *host;
- DEBUG(0, "ide_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "ide_config(0x%p)\n", link);
is_kme = ((link->manf_id == MANFID_KME) &&
((link->card_id == PRODID_KME_KXLC005_A) ||
@@ -306,8 +293,12 @@ static int ide_config(struct pcmcia_device *link)
io_base = link->io.BasePort1;
ctl_base = stk->ctl_base;
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/* disable drive interrupts during IDE probe */
outb(0x02, ctl_base);
@@ -342,8 +333,6 @@ err_mem:
printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
goto failed;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
kfree(stk);
ide_release(link);
@@ -363,7 +352,7 @@ static void ide_release(struct pcmcia_device *link)
ide_info_t *info = link->priv;
struct ide_host *host = info->host;
- DEBUG(0, "ide_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
if (info->ndev)
/* FIXME: if this fails we need to queue the cleanup somehow
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index d3440b5010a5..6e7ae2b6cfc6 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -162,7 +162,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
if (tf->command == ATA_CMD_SET_FEATURES &&
tf->feature == SETFEATURES_XFER &&
tf->nsect >= XFER_SW_DMA_0) {
- xfer_rate = ide_find_dma_mode(drive, XFER_UDMA_6);
+ xfer_rate = ide_find_dma_mode(drive, tf->nsect);
if (xfer_rate != tf->nsect) {
err = -EINVAL;
goto abort;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 63c53d65e875..4d76ba473097 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1046,15 +1046,6 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
if (port_ops && port_ops->init_dev)
port_ops->init_dev(drive);
}
-
- ide_port_for_each_dev(i, drive, hwif) {
- /*
- * default to PIO Mode 0 before we figure out
- * the most suited mode for the attached device
- */
- if (port_ops && port_ops->set_pio_mode)
- port_ops->set_pio_mode(drive, 0);
- }
}
static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 96a2959ce877..7c544f7c74c4 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -260,15 +260,12 @@ static int ieee802154_fake_close(struct net_device *dev)
static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- skb->iif = dev->ifindex;
- skb->dev = dev;
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
- dev->trans_start = jiffies;
-
/* FIXME: do hardware work here ... */
+ dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
index 72c63e5dd630..38df81fcdc3a 100644
--- a/drivers/input/ff-core.c
+++ b/drivers/input/ff-core.c
@@ -337,16 +337,16 @@ int input_ff_create(struct input_dev *dev, int max_effects)
dev->ff = ff;
dev->flush = flush_effects;
dev->event = input_ff_event;
- set_bit(EV_FF, dev->evbit);
+ __set_bit(EV_FF, dev->evbit);
/* Copy "true" bits into ff device bitmap */
for (i = 0; i <= FF_MAX; i++)
if (test_bit(i, dev->ffbit))
- set_bit(i, ff->ffbit);
+ __set_bit(i, ff->ffbit);
/* we can emulate RUMBLE with periodic effects */
if (test_bit(FF_PERIODIC, ff->ffbit))
- set_bit(FF_RUMBLE, dev->ffbit);
+ __set_bit(FF_RUMBLE, dev->ffbit);
return 0;
}
@@ -362,12 +362,14 @@ EXPORT_SYMBOL_GPL(input_ff_create);
*/
void input_ff_destroy(struct input_dev *dev)
{
- clear_bit(EV_FF, dev->evbit);
- if (dev->ff) {
- if (dev->ff->destroy)
- dev->ff->destroy(dev->ff);
- kfree(dev->ff->private);
- kfree(dev->ff);
+ struct ff_device *ff = dev->ff;
+
+ __clear_bit(EV_FF, dev->evbit);
+ if (ff) {
+ if (ff->destroy)
+ ff->destroy(ff);
+ kfree(ff->private);
+ kfree(ff);
dev->ff = NULL;
}
}
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
index 2d1415e16834..b483b2995fa9 100644
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -61,7 +61,6 @@ struct ml_device {
struct ml_effect_state states[FF_MEMLESS_EFFECTS];
int gain;
struct timer_list timer;
- spinlock_t timer_lock;
struct input_dev *dev;
int (*play_effect)(struct input_dev *dev, void *data,
@@ -368,38 +367,38 @@ static void ml_effect_timer(unsigned long timer_data)
{
struct input_dev *dev = (struct input_dev *)timer_data;
struct ml_device *ml = dev->ff->private;
+ unsigned long flags;
debug("timer: updating effects");
- spin_lock(&ml->timer_lock);
+ spin_lock_irqsave(&dev->event_lock, flags);
ml_play_effects(ml);
- spin_unlock(&ml->timer_lock);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
}
+/*
+ * Sets requested gain for FF effects. Called with dev->event_lock held.
+ */
static void ml_ff_set_gain(struct input_dev *dev, u16 gain)
{
struct ml_device *ml = dev->ff->private;
int i;
- spin_lock_bh(&ml->timer_lock);
-
ml->gain = gain;
for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
__clear_bit(FF_EFFECT_PLAYING, &ml->states[i].flags);
ml_play_effects(ml);
-
- spin_unlock_bh(&ml->timer_lock);
}
+/*
+ * Start/stop specified FF effect. Called with dev->event_lock held.
+ */
static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
{
struct ml_device *ml = dev->ff->private;
struct ml_effect_state *state = &ml->states[effect_id];
- unsigned long flags;
-
- spin_lock_irqsave(&ml->timer_lock, flags);
if (value > 0) {
debug("initiated play");
@@ -425,8 +424,6 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
ml_play_effects(ml);
}
- spin_unlock_irqrestore(&ml->timer_lock, flags);
-
return 0;
}
@@ -436,7 +433,7 @@ static int ml_ff_upload(struct input_dev *dev,
struct ml_device *ml = dev->ff->private;
struct ml_effect_state *state = &ml->states[effect->id];
- spin_lock_bh(&ml->timer_lock);
+ spin_lock_irq(&dev->event_lock);
if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
__clear_bit(FF_EFFECT_PLAYING, &state->flags);
@@ -448,7 +445,7 @@ static int ml_ff_upload(struct input_dev *dev,
ml_schedule_timer(ml);
}
- spin_unlock_bh(&ml->timer_lock);
+ spin_unlock_irq(&dev->event_lock);
return 0;
}
@@ -482,7 +479,6 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
ml->private = data;
ml->play_effect = play_effect;
ml->gain = 0xffff;
- spin_lock_init(&ml->timer_lock);
setup_timer(&ml->timer, ml_effect_timer, (unsigned long)dev);
set_bit(FF_GAIN, dev->ffbit);
diff --git a/drivers/input/input.c b/drivers/input/input.c
index c6f88ebb40c7..2266ecbfbc01 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -782,10 +782,29 @@ static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
return 0;
}
+union input_seq_state {
+ struct {
+ unsigned short pos;
+ bool mutex_acquired;
+ };
+ void *p;
+};
+
static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos)
{
- if (mutex_lock_interruptible(&input_mutex))
- return NULL;
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
+ int error;
+
+ /* We need to fit into seq->private pointer */
+ BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
+
+ error = mutex_lock_interruptible(&input_mutex);
+ if (error) {
+ state->mutex_acquired = false;
+ return ERR_PTR(error);
+ }
+
+ state->mutex_acquired = true;
return seq_list_start(&input_dev_list, *pos);
}
@@ -795,9 +814,12 @@ static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos)
return seq_list_next(v, &input_dev_list, pos);
}
-static void input_devices_seq_stop(struct seq_file *seq, void *v)
+static void input_seq_stop(struct seq_file *seq, void *v)
{
- mutex_unlock(&input_mutex);
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
+
+ if (state->mutex_acquired)
+ mutex_unlock(&input_mutex);
}
static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
@@ -861,7 +883,7 @@ static int input_devices_seq_show(struct seq_file *seq, void *v)
static const struct seq_operations input_devices_seq_ops = {
.start = input_devices_seq_start,
.next = input_devices_seq_next,
- .stop = input_devices_seq_stop,
+ .stop = input_seq_stop,
.show = input_devices_seq_show,
};
@@ -881,40 +903,49 @@ static const struct file_operations input_devices_fileops = {
static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
{
- if (mutex_lock_interruptible(&input_mutex))
- return NULL;
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
+ int error;
+
+ /* We need to fit into seq->private pointer */
+ BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
+
+ error = mutex_lock_interruptible(&input_mutex);
+ if (error) {
+ state->mutex_acquired = false;
+ return ERR_PTR(error);
+ }
+
+ state->mutex_acquired = true;
+ state->pos = *pos;
- seq->private = (void *)(unsigned long)*pos;
return seq_list_start(&input_handler_list, *pos);
}
static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- seq->private = (void *)(unsigned long)(*pos + 1);
- return seq_list_next(v, &input_handler_list, pos);
-}
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
-static void input_handlers_seq_stop(struct seq_file *seq, void *v)
-{
- mutex_unlock(&input_mutex);
+ state->pos = *pos + 1;
+ return seq_list_next(v, &input_handler_list, pos);
}
static int input_handlers_seq_show(struct seq_file *seq, void *v)
{
struct input_handler *handler = container_of(v, struct input_handler, node);
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
- seq_printf(seq, "N: Number=%ld Name=%s",
- (unsigned long)seq->private, handler->name);
+ seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
if (handler->fops)
seq_printf(seq, " Minor=%d", handler->minor);
seq_putc(seq, '\n');
return 0;
}
+
static const struct seq_operations input_handlers_seq_ops = {
.start = input_handlers_seq_start,
.next = input_handlers_seq_next,
- .stop = input_handlers_seq_stop,
+ .stop = input_seq_stop,
.show = input_handlers_seq_show,
};
@@ -1261,17 +1292,24 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
return 0;
}
-#define INPUT_DO_TOGGLE(dev, type, bits, on) \
- do { \
- int i; \
- if (!test_bit(EV_##type, dev->evbit)) \
- break; \
- for (i = 0; i < type##_MAX; i++) { \
- if (!test_bit(i, dev->bits##bit) || \
- !test_bit(i, dev->bits)) \
- continue; \
- dev->event(dev, EV_##type, i, on); \
- } \
+#define INPUT_DO_TOGGLE(dev, type, bits, on) \
+ do { \
+ int i; \
+ bool active; \
+ \
+ if (!test_bit(EV_##type, dev->evbit)) \
+ break; \
+ \
+ for (i = 0; i < type##_MAX; i++) { \
+ if (!test_bit(i, dev->bits##bit)) \
+ continue; \
+ \
+ active = test_bit(i, dev->bits); \
+ if (!active && !on) \
+ continue; \
+ \
+ dev->event(dev, EV_##type, i, on ? active : 0); \
+ } \
} while (0)
#ifdef CONFIG_PM
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 4709e15af607..28e6110d1ff8 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -233,6 +233,7 @@ struct atkbd {
*/
static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
static void *atkbd_platform_fixup_data;
+static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int);
static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
ssize_t (*handler)(struct atkbd *, char *));
@@ -393,6 +394,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
input_event(dev, EV_MSC, MSC_RAW, code);
+ if (atkbd_platform_scancode_fixup)
+ code = atkbd_platform_scancode_fixup(atkbd, code);
+
if (atkbd->translated) {
if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) {
@@ -574,11 +578,22 @@ static void atkbd_event_work(struct work_struct *work)
mutex_lock(&atkbd->event_mutex);
- if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
- atkbd_set_leds(atkbd);
+ if (!atkbd->enabled) {
+ /*
+ * Serio ports are resumed asynchronously so while driver core
+ * thinks that device is already fully operational in reality
+ * it may not be ready yet. In this case we need to keep
+ * rescheduling till reconnect completes.
+ */
+ schedule_delayed_work(&atkbd->event_work,
+ msecs_to_jiffies(100));
+ } else {
+ if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
+ atkbd_set_leds(atkbd);
- if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
- atkbd_set_repeat_rate(atkbd);
+ if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
+ atkbd_set_repeat_rate(atkbd);
+ }
mutex_unlock(&atkbd->event_mutex);
}
@@ -770,6 +785,30 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra
return 3;
}
+static int atkbd_reset_state(struct atkbd *atkbd)
+{
+ struct ps2dev *ps2dev = &atkbd->ps2dev;
+ unsigned char param[1];
+
+/*
+ * Set the LEDs to a predefined state (all off).
+ */
+
+ param[0] = 0;
+ if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS))
+ return -1;
+
+/*
+ * Set autorepeat to fastest possible.
+ */
+
+ param[0] = 0;
+ if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP))
+ return -1;
+
+ return 0;
+}
+
static int atkbd_activate(struct atkbd *atkbd)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
@@ -852,29 +891,6 @@ static unsigned int atkbd_hp_forced_release_keys[] = {
};
/*
- * Inventec system with broken key release on volume keys
- */
-static unsigned int atkbd_inventec_forced_release_keys[] = {
- 0xae, 0xb0, -1U
-};
-
-/*
- * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release
- * for its volume buttons
- */
-static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
- 0xae, 0xb0, -1U
-};
-
-/*
- * Perform fixup for HP (Compaq) Presario R4000 R4100 R4200 that don't generate
- * release for their volume buttons
- */
-static unsigned int atkbd_hp_r4000_forced_release_keys[] = {
- 0xae, 0xb0, -1U
-};
-
-/*
* Samsung NC10,NC20 with Fn+F? key release not working
*/
static unsigned int atkbd_samsung_forced_release_keys[] = {
@@ -882,14 +898,6 @@ static unsigned int atkbd_samsung_forced_release_keys[] = {
};
/*
- * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop
- * do not generate release events so we have to do it ourselves.
- */
-static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
- 0xb0, 0xae, -1U
-};
-
-/*
* Amilo Pi 3525 key release for Fn+Volume keys not working
*/
static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = {
@@ -911,6 +919,30 @@ static unsigned int atkdb_soltech_ta12_forced_release_keys[] = {
};
/*
+ * Many notebooks don't send key release event for volume up/down
+ * keys, with key list below common among them
+ */
+static unsigned int atkbd_volume_forced_release_keys[] = {
+ 0xae, 0xb0, -1U
+};
+
+/*
+ * OQO 01+ multimedia keys (64--66) generate e0 6x upon release whereas
+ * they should be generating e4-e6 (0x80 | code).
+ */
+static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd,
+ unsigned int code)
+{
+ if (atkbd->translated && atkbd->emul == 1 &&
+ (code == 0x64 || code == 0x65 || code == 0x66)) {
+ atkbd->emul = 0;
+ code |= 0x80;
+ }
+
+ return code;
+}
+
+/*
* atkbd_set_keycode_table() initializes keyboard's keycode table
* according to the selected scancode set
*/
@@ -1087,6 +1119,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
}
atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
+ atkbd_reset_state(atkbd);
atkbd_activate(atkbd);
} else {
@@ -1141,6 +1174,18 @@ static int atkbd_reconnect(struct serio *serio)
return -1;
atkbd_activate(atkbd);
+
+ /*
+ * Restore LED state and repeat rate. While input core
+ * will do this for us at resume time reconnect may happen
+ * because user requested it via sysfs or simply because
+ * keyboard was unplugged and plugged in again so we need
+ * to do it ourselves here.
+ */
+ atkbd_set_leds(atkbd);
+ if (!atkbd->softrepeat)
+ atkbd_set_repeat_rate(atkbd);
+
}
atkbd_enable(atkbd);
@@ -1267,6 +1312,7 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
atkbd->dev = new_dev;
atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
+ atkbd_reset_state(atkbd);
atkbd_activate(atkbd);
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
@@ -1388,6 +1434,7 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
atkbd->dev = new_dev;
atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra);
+ atkbd_reset_state(atkbd);
atkbd_activate(atkbd);
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
@@ -1513,6 +1560,13 @@ static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)
return 0;
}
+static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id)
+{
+ atkbd_platform_scancode_fixup = id->driver_data;
+
+ return 0;
+}
+
static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
{
.ident = "Dell Laptop",
@@ -1548,7 +1602,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_hp_zv6100_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "HP Presario R4000",
@@ -1557,7 +1611,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_hp_r4000_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "HP Presario R4100",
@@ -1566,7 +1620,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_hp_r4000_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "HP Presario R4200",
@@ -1575,7 +1629,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_hp_r4000_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "Inventec Symphony",
@@ -1584,7 +1638,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_inventec_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "Samsung NC10",
@@ -1620,7 +1674,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_amilo_pa1510_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "Fujitsu Amilo Pi 3525",
@@ -1649,6 +1703,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
.callback = atkbd_setup_forced_release,
.driver_data = atkdb_soltech_ta12_forced_release_keys,
},
+ {
+ .ident = "OQO Model 01+",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
+ },
+ .callback = atkbd_setup_scancode_fixup,
+ .driver_data = atkbd_oqo_01plus_scancode_fixup,
+ },
{ }
};
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index a88aff3816a0..77d130914259 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
}
error = request_irq(irq, gpio_keys_isr,
+ IRQF_SHARED |
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
button->desc ? button->desc : "gpio_keys",
bdata);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 02f4f8f1db6f..a9bb2544b2de 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -227,6 +227,7 @@ config INPUT_WINBOND_CIR
depends on X86 && PNP
select NEW_LEDS
select LEDS_CLASS
+ select LEDS_TRIGGERS
select BITREVERSE
help
Say Y here if you want to use the IR remote functionality found
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index 216a559f55ea..ea821b546969 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -209,7 +209,7 @@ static inline int hp_sdc_rtc_read_rt(struct timeval *res) {
/* Read the i8042 fast handshake timer */
static inline int hp_sdc_rtc_read_fhs(struct timeval *res) {
- uint64_t raw;
+ int64_t raw;
unsigned int tenms;
raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_FHS, 2);
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 5e6308694408..82811558ec33 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -107,8 +107,7 @@ static const struct dmi_system_id lifebook_dmi_table[] = {
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "CF-72"),
},
- .callback = lifebook_set_serio_phys,
- .driver_data = "isa0060/serio3",
+ .callback = lifebook_set_6byte_proto,
},
{
.ident = "Lifebook B142",
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index de745d751162..ab5dc5f5fd83 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -219,7 +219,7 @@ static const struct ps2pp_info *get_model_info(unsigned char model)
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL },
{ 72, PS2PP_KIND_TRACKMAN, 0 }, /* T-CH11: TrackMan Marble */
- { 73, 0, PS2PP_SIDE_BTN },
+ { 73, PS2PP_KIND_TRACKMAN, PS2PP_SIDE_BTN }, /* TrackMan FX */
{ 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 79, PS2PP_KIND_TRACKMAN, PS2PP_WHEEL }, /* TrackMan with wheel */
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 690aed905436..07c53798301a 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -581,7 +581,7 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties)
static int psmouse_extensions(struct psmouse *psmouse,
unsigned int max_proto, bool set_properties)
{
- bool synaptics_hardware = true;
+ bool synaptics_hardware = false;
/*
* We always check for lifebook because it does not disturb mouse
@@ -1673,7 +1673,7 @@ static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp)
{
int type = *((unsigned int *)kp->arg);
- return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name);
+ return sprintf(buffer, "%s", psmouse_protocol_by_type(type)->name);
}
static int __init psmouse_init(void)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index b66ff1ac7dea..f4a61252bcc9 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -652,6 +652,16 @@ static const struct dmi_system_id toshiba_dmi_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
},
+
+ },
+ {
+ .ident = "Toshiba Portege M300",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
+ },
+
},
{ }
};
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index a39bc4eb902b..2bcf1ace27c0 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -327,6 +327,17 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
},
},
{
+ /*
+ * Reset and GET ID commands issued via KBD port are
+ * sometimes being delivered to AUX3.
+ */
+ .ident = "Sony Vaio FZ-240E",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
+ },
+ },
+ {
.ident = "Amoi M636/A737",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
@@ -436,6 +447,27 @@ static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
},
},
+ {
+ .ident = "Dell Vostro 1320",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
+ },
+ },
+ {
+ .ident = "Dell Vostro 1520",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
+ },
+ },
+ {
+ .ident = "Dell Vostro 1720",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
+ },
+ },
{ }
};
@@ -661,7 +693,7 @@ static void i8042_pnp_exit(void)
static int __init i8042_pnp_init(void)
{
char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
- int pnp_data_busted = false;
+ bool pnp_data_busted = false;
int err;
#ifdef CONFIG_X86
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index a31578170ccc..1df02d25aca5 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -836,17 +836,32 @@ static int i8042_controller_selftest(void)
static int i8042_controller_init(void)
{
unsigned long flags;
+ int n = 0;
+ unsigned char ctr[2];
/*
- * Save the CTR for restoral on unload / reboot.
+ * Save the CTR for restore on unload / reboot.
*/
- if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
- printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n");
- return -EIO;
- }
+ do {
+ if (n >= 10) {
+ printk(KERN_ERR
+ "i8042.c: Unable to get stable CTR read.\n");
+ return -EIO;
+ }
+
+ if (n != 0)
+ udelay(50);
+
+ if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) {
+ printk(KERN_ERR
+ "i8042.c: Can't read CTR while initializing i8042.\n");
+ return -EIO;
+ }
- i8042_initial_ctr = i8042_ctr;
+ } while (n < 2 || ctr[0] != ctr[1]);
+
+ i8042_initial_ctr = i8042_ctr = ctr[0];
/*
* Disable the keyboard interface and interrupt.
@@ -895,6 +910,12 @@ static int i8042_controller_init(void)
return -EIO;
}
+/*
+ * Flush whatever accumulated while we were disabling keyboard port.
+ */
+
+ i8042_flush();
+
return 0;
}
@@ -914,7 +935,7 @@ static void i8042_controller_reset(void)
i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS;
i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT);
- if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR))
+ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n");
/*
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index c72565520e41..5a6ae646a636 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -111,8 +111,6 @@ static int avmcs_probe(struct pcmcia_device *p_dev)
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
-
/* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
@@ -198,7 +196,6 @@ static int avmcs_config(struct pcmcia_device *link)
*/
i = pcmcia_request_irq(link, &link->irq);
if (i != 0) {
- cs_error(link, RequestIRQ, i);
/* undo */
pcmcia_disable_device(link);
break;
@@ -209,7 +206,6 @@ static int avmcs_config(struct pcmcia_device *link)
*/
i = pcmcia_request_configuration(link, &link->conf);
if (i != 0) {
- cs_error(link, RequestConfiguration, i);
pcmcia_disable_device(link);
break;
}
diff --git a/drivers/isdn/hardware/eicon/maintidi.c b/drivers/isdn/hardware/eicon/maintidi.c
index 23960cb6eaab..41c26e756452 100644
--- a/drivers/isdn/hardware/eicon/maintidi.c
+++ b/drivers/isdn/hardware/eicon/maintidi.c
@@ -959,8 +959,9 @@ static int process_idi_event (diva_strace_context_t* pLib,
}
if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) {
char* tmp = &pLib->lines[0].pInterface->Layer2[0];
- dword l2_state;
- diva_strace_read_uint (pVar, &l2_state);
+ dword l2_state;
+ if (diva_strace_read_uint(pVar, &l2_state))
+ return -1;
switch (l2_state) {
case 0:
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index 27d5dd68f4fb..ae89fb89da64 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -2692,7 +2692,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS)
|| (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS))
{
- len = (byte)(&(((T30_INFO *) 0)->universal_6));
+ len = offsetof(T30_INFO, universal_6);
fax_info_change = false;
if (ncpi->length >= 4)
{
@@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
for (i = 0; i < w; i++)
((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i];
((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
- len = (byte)(((T30_INFO *) 0)->station_id + 20);
+ len = offsetof(T30_INFO, station_id) + 20;
w = fax_parms[5].length;
if (w > 20)
w = 20;
@@ -2788,7 +2788,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
}
else
{
- len = (byte)(&(((T30_INFO *) 0)->universal_6));
+ len = offsetof(T30_INFO, universal_6);
}
fax_info_change = true;
@@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
&& (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
&& (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
{
- len = ((byte)(((T30_INFO *) 0)->station_id + 20));
+ len = offsetof(T30_INFO, station_id) + 20;
if (plci->fax_connect_info_length < len)
{
((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
break;
}
ncpi = &m_parms[1];
- len = ((byte)(((T30_INFO *) 0)->station_id + 20));
+ len = offsetof(T30_INFO, station_id) + 20;
if (plci->fax_connect_info_length < len)
{
((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci)
if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
& ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
{
- i = ((word)(((T30_INFO *) 0)->station_id + 20)) + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
+ i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
while (i < plci->NL.RBuffer->length)
plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
}
@@ -7236,7 +7236,7 @@ static void nl_ind(PLCI *plci)
{
plci->RData[1].P = plci->RData[0].P;
plci->RData[1].PLength = plci->RData[0].PLength;
- plci->RData[0].P = v120_header_buffer + (-((int) v120_header_buffer) & 3);
+ plci->RData[0].P = v120_header_buffer + (-((unsigned long)v120_header_buffer) & 3);
if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1))
plci->RData[0].PLength = 1;
else
@@ -8473,7 +8473,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
}
len = nlc[0];
- pos = ((byte)(((T30_INFO *) 0)->station_id + 20));
+ pos = offsetof(T30_INFO, station_id) + 20;
if (pos < plci->fax_connect_info_length)
{
for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
@@ -8525,7 +8525,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
}
PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
- len = ((byte)(((T30_INFO *) 0)->station_id + 20));
+ len = offsetof(T30_INFO, station_id) + 20;
for (i = 0; i < len; i++)
plci->fax_connect_info_buffer[i] = nlc[1+i];
((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0;
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index faed794cf75a..a6624ad252c5 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -5481,7 +5481,7 @@ HFCmulti_init(void)
if (err) {
printk(KERN_ERR "error registering embedded driver: "
"%x\n", err);
- return -err;
+ return err;
}
HFC_cnt++;
printk(KERN_INFO "%d devices registered\n", HFC_cnt);
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index bf526a7a63af..d6fdf1f66754 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -594,6 +594,7 @@ Amd7930_l1hw(struct PStack *st, int pr, void *arg)
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen");
skb_queue_tail(&cs->sq, skb);
+ spin_unlock_irqrestore(&cs->lock, flags);
break;
}
if (cs->debug & DEB_DLOG_HEX)
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 23560c897ec3..f9bdff39cf4a 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -30,22 +30,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA car
MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL");
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"avma1_cs.c 1.00 1998/01/23 10:00:00 (Carsten Paeth)";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -119,7 +103,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
{
local_info_t *local;
- DEBUG(0, "avma1cs_attach()\n");
+ dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -139,8 +123,6 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
-
/* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
@@ -161,7 +143,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
static void avma1cs_detach(struct pcmcia_device *link)
{
- DEBUG(0, "avma1cs_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
avma1cs_release(link);
kfree(link->priv);
} /* avma1cs_detach */
@@ -203,7 +185,7 @@ static int avma1cs_config(struct pcmcia_device *link)
dev = link->priv;
- DEBUG(0, "avma1cs_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
devname[0] = 0;
if (link->prod_id[1])
@@ -218,7 +200,6 @@ static int avma1cs_config(struct pcmcia_device *link)
*/
i = pcmcia_request_irq(link, &link->irq);
if (i != 0) {
- cs_error(link, RequestIRQ, i);
/* undo */
pcmcia_disable_device(link);
break;
@@ -229,7 +210,6 @@ static int avma1cs_config(struct pcmcia_device *link)
*/
i = pcmcia_request_configuration(link, &link->conf);
if (i != 0) {
- cs_error(link, RequestConfiguration, i);
pcmcia_disable_device(link);
break;
}
@@ -281,7 +261,7 @@ static void avma1cs_release(struct pcmcia_device *link)
{
local_info_t *local = link->priv;
- DEBUG(0, "avma1cs_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link);
/* now unregister function with hisax */
HiSax_closecard(local->node.minor);
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
index 018bd293e580..0b0c2e5d806b 100644
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -382,7 +382,7 @@ MemwaitforXFW(struct IsdnCardState *cs, int hscx)
{
int to = 50;
- while ((!(MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) {
+ while (((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) {
udelay(1);
to--;
}
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index f4d0fe29bcf8..a2f709f53974 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -57,23 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
MODULE_AUTHOR("Klaus Lichtenwalder");
MODULE_LICENSE("Dual MPL/GPL");
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"elsa_cs.c $Revision: 1.2.2.4 $ $Date: 2004/01/25 15:07:06 $ (K.Lichtenwalder)";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -142,7 +125,7 @@ static int elsa_cs_probe(struct pcmcia_device *link)
{
local_info_t *local;
- DEBUG(0, "elsa_cs_attach()\n");
+ dev_dbg(&link->dev, "elsa_cs_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -155,7 +138,6 @@ static int elsa_cs_probe(struct pcmcia_device *link)
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
link->irq.Handler = NULL;
/*
@@ -188,7 +170,7 @@ static void elsa_cs_detach(struct pcmcia_device *link)
{
local_info_t *info = link->priv;
- DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link);
info->busy = 1;
elsa_cs_release(link);
@@ -231,30 +213,25 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
static int elsa_cs_config(struct pcmcia_device *link)
{
local_info_t *dev;
- int i, last_fn;
+ int i;
IsdnCard_t icard;
- DEBUG(0, "elsa_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
dev = link->priv;
i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
- if (i != 0) {
- last_fn = RequestIO;
- goto cs_failed;
- }
+ if (i != 0)
+ goto failed;
i = pcmcia_request_irq(link, &link->irq);
if (i != 0) {
link->irq.AssignedIRQ = 0;
- last_fn = RequestIRQ;
- goto cs_failed;
+ goto failed;
}
i = pcmcia_request_configuration(link, &link->conf);
- if (i != 0) {
- last_fn = RequestConfiguration;
- goto cs_failed;
- }
+ if (i != 0)
+ goto failed;
/* At this point, the dev_node_t structure(s) should be
initialized and arranged in a linked list at link->dev. *//* */
@@ -290,8 +267,7 @@ static int elsa_cs_config(struct pcmcia_device *link)
((local_info_t*)link->priv)->cardnr = i;
return 0;
-cs_failed:
- cs_error(link, last_fn, i);
+failed:
elsa_cs_release(link);
return -ENODEV;
} /* elsa_cs_config */
@@ -308,7 +284,7 @@ static void elsa_cs_release(struct pcmcia_device *link)
{
local_info_t *local = link->priv;
- DEBUG(0, "elsa_cs_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
if (local) {
if (local->cardnr >= 0) {
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c
index f181db464392..1657bba7879e 100644
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -477,62 +477,62 @@ static void
modem_set_init(struct IsdnCardState *cs) {
int timeout;
-#define RCV_DELAY 20000
+#define RCV_DELAY 20
modem_write_cmd(cs, MInit_1, strlen(MInit_1));
timeout = 1000;
while(timeout-- && cs->hw.elsa.transcnt)
udelay(1000);
debugl1(cs, "msi tout=%d", timeout);
- udelay(RCV_DELAY);
+ mdelay(RCV_DELAY);
modem_write_cmd(cs, MInit_2, strlen(MInit_2));
timeout = 1000;
while(timeout-- && cs->hw.elsa.transcnt)
udelay(1000);
debugl1(cs, "msi tout=%d", timeout);
- udelay(RCV_DELAY);
+ mdelay(RCV_DELAY);
modem_write_cmd(cs, MInit_3, strlen(MInit_3));
timeout = 1000;
while(timeout-- && cs->hw.elsa.transcnt)
udelay(1000);
debugl1(cs, "msi tout=%d", timeout);
- udelay(RCV_DELAY);
+ mdelay(RCV_DELAY);
modem_write_cmd(cs, MInit_4, strlen(MInit_4));
timeout = 1000;
while(timeout-- && cs->hw.elsa.transcnt)
udelay(1000);
debugl1(cs, "msi tout=%d", timeout);
- udelay(RCV_DELAY );
+ mdelay(RCV_DELAY);
modem_write_cmd(cs, MInit_5, strlen(MInit_5));
timeout = 1000;
while(timeout-- && cs->hw.elsa.transcnt)
udelay(1000);
debugl1(cs, "msi tout=%d", timeout);
- udelay(RCV_DELAY);
+ mdelay(RCV_DELAY);
modem_write_cmd(cs, MInit_6, strlen(MInit_6));
timeout = 1000;
while(timeout-- && cs->hw.elsa.transcnt)
udelay(1000);
debugl1(cs, "msi tout=%d", timeout);
- udelay(RCV_DELAY);
+ mdelay(RCV_DELAY);
modem_write_cmd(cs, MInit_7, strlen(MInit_7));
timeout = 1000;
while(timeout-- && cs->hw.elsa.transcnt)
udelay(1000);
debugl1(cs, "msi tout=%d", timeout);
- udelay(RCV_DELAY);
+ mdelay(RCV_DELAY);
}
static void
modem_set_dial(struct IsdnCardState *cs, int outgoing) {
int timeout;
-#define RCV_DELAY 20000
+#define RCV_DELAY 20
modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
timeout = 1000;
while(timeout-- && cs->hw.elsa.transcnt)
udelay(1000);
debugl1(cs, "msi tout=%d", timeout);
- udelay(RCV_DELAY);
+ mdelay(RCV_DELAY);
if (outgoing)
modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout));
else
@@ -541,7 +541,7 @@ modem_set_dial(struct IsdnCardState *cs, int outgoing) {
while(timeout-- && cs->hw.elsa.transcnt)
udelay(1000);
debugl1(cs, "msi tout=%d", timeout);
- udelay(RCV_DELAY);
+ mdelay(RCV_DELAY);
}
static void
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 9de54202c90c..a420b64472e3 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -817,8 +817,8 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
}
/* we have a complete hdlc packet */
if (finish) {
- if ((!fifo->skbuff->data[fifo->skbuff->len - 1])
- && (fifo->skbuff->len > 3)) {
+ if (fifo->skbuff->len > 3 &&
+ !fifo->skbuff->data[fifo->skbuff->len - 1]) {
if (fifon == HFCUSB_D_RX) {
DBG(HFCUSB_DBG_DCHANNEL,
diff --git a/drivers/isdn/hisax/hscx_irq.c b/drivers/isdn/hisax/hscx_irq.c
index 7b1ad5e4ecda..2387d76c721a 100644
--- a/drivers/isdn/hisax/hscx_irq.c
+++ b/drivers/isdn/hisax/hscx_irq.c
@@ -32,7 +32,7 @@ waitforXFW(struct IsdnCardState *cs, int hscx)
{
int to = 50;
- while ((!(READHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) {
+ while (((READHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) {
udelay(1);
to--;
}
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index 9aba646ba221..c80cbb8a2ef9 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -468,6 +468,7 @@ ICC_l1hw(struct PStack *st, int pr, void *arg)
if (cs->debug & L1_DEB_WARN)
debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
skb_queue_tail(&cs->sq, skb);
+ spin_unlock_irqrestore(&cs->lock, flags);
break;
}
if (cs->debug & DEB_DLOG_HEX)
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 9a3c9f5e4fe8..af5d393cc2d0 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -57,24 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
MODULE_AUTHOR("Marcus Niemann");
MODULE_LICENSE("Dual MPL/GPL");
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 (M.Niemann)";
-#else
-#define DEBUG(n, args...)
-#endif
-
/*====================================================================*/
@@ -151,7 +133,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
{
local_info_t *local;
- DEBUG(0, "sedlbauer_attach()\n");
+ dev_dbg(&link->dev, "sedlbauer_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -163,7 +145,6 @@ static int sedlbauer_probe(struct pcmcia_device *link)
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
/*
@@ -198,7 +179,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
static void sedlbauer_detach(struct pcmcia_device *link)
{
- DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
((local_info_t *)link->priv)->stop = 1;
sedlbauer_release(link);
@@ -214,9 +195,6 @@ static void sedlbauer_detach(struct pcmcia_device *link)
device available to the system.
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int sedlbauer_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
@@ -293,11 +271,11 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
req->Base = mem->win[0].host_addr;
req->Size = mem->win[0].len;
req->AccessSpeed = 0;
- if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
+ if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
return -ENODEV;
map.Page = 0;
map.CardOffset = mem->win[0].card_addr;
- if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+ if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
return -ENODEV;
}
return 0;
@@ -309,10 +287,10 @@ static int sedlbauer_config(struct pcmcia_device *link)
{
local_info_t *dev = link->priv;
win_req_t *req;
- int last_fn, last_ret;
+ int ret;
IsdnCard_t icard;
- DEBUG(0, "sedlbauer_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
if (!req)
@@ -330,8 +308,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
these things without consulting the CIS, and most client drivers
will only use the CIS to fill in implementation-defined details.
*/
- last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
- if (last_ret)
+ ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
+ if (ret)
goto failed;
/*
@@ -339,15 +317,20 @@ static int sedlbauer_config(struct pcmcia_device *link)
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
- if (link->conf.Attributes & CONF_ENABLE_IRQ)
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ }
/*
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*
At this point, the dev_node_t structure(s) need to be
@@ -380,19 +363,18 @@ static int sedlbauer_config(struct pcmcia_device *link)
icard.protocol = protocol;
icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
- last_ret = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->stop), &icard);
- if (last_ret < 0) {
- printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
- last_ret, link->io.BasePort1);
+ ret = hisax_init_pcmcia(link,
+ &(((local_info_t *)link->priv)->stop), &icard);
+ if (ret < 0) {
+ printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
+ ret, link->io.BasePort1);
sedlbauer_release(link);
return -ENODEV;
} else
- ((local_info_t*)link->priv)->cardnr = last_ret;
+ ((local_info_t *)link->priv)->cardnr = ret;
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
sedlbauer_release(link);
return -ENODEV;
@@ -410,7 +392,7 @@ failed:
static void sedlbauer_release(struct pcmcia_device *link)
{
local_info_t *local = link->priv;
- DEBUG(0, "sedlbauer_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
if (local) {
if (local->cardnr >= 0) {
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 623d111544d4..ea705394ce2b 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -38,23 +38,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Teles PCMCIA cards");
MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de");
MODULE_LICENSE("GPL");
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"teles_cs.c 2.10 2002/07/30 22:23:34 kkeil";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -133,7 +116,7 @@ static int teles_probe(struct pcmcia_device *link)
{
local_info_t *local;
- DEBUG(0, "teles_attach()\n");
+ dev_dbg(&link->dev, "teles_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -145,7 +128,6 @@ static int teles_probe(struct pcmcia_device *link)
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
link->irq.Handler = NULL;
/*
@@ -178,7 +160,7 @@ static void teles_detach(struct pcmcia_device *link)
{
local_info_t *info = link->priv;
- DEBUG(0, "teles_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "teles_detach(0x%p)\n", link);
info->busy = 1;
teles_cs_release(link);
@@ -221,30 +203,25 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev,
static int teles_cs_config(struct pcmcia_device *link)
{
local_info_t *dev;
- int i, last_fn;
+ int i;
IsdnCard_t icard;
- DEBUG(0, "teles_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
dev = link->priv;
i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
- if (i != 0) {
- last_fn = RequestIO;
+ if (i != 0)
goto cs_failed;
- }
i = pcmcia_request_irq(link, &link->irq);
if (i != 0) {
link->irq.AssignedIRQ = 0;
- last_fn = RequestIRQ;
goto cs_failed;
}
i = pcmcia_request_configuration(link, &link->conf);
- if (i != 0) {
- last_fn = RequestConfiguration;
+ if (i != 0)
goto cs_failed;
- }
/* At this point, the dev_node_t structure(s) should be
initialized and arranged in a linked list at link->dev. *//* */
@@ -283,7 +260,6 @@ static int teles_cs_config(struct pcmcia_device *link)
return 0;
cs_failed:
- cs_error(link, last_fn, i);
teles_cs_release(link);
return -ENODEV;
} /* teles_cs_config */
@@ -300,7 +276,7 @@ static void teles_cs_release(struct pcmcia_device *link)
{
local_info_t *local = link->priv;
- DEBUG(0, "teles_cs_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link);
if (local) {
if (local->cardnr >= 0) {
diff --git a/drivers/isdn/i4l/isdn_net.h b/drivers/isdn/i4l/isdn_net.h
index 74032d0881ef..7511f08effa5 100644
--- a/drivers/isdn/i4l/isdn_net.h
+++ b/drivers/isdn/i4l/isdn_net.h
@@ -83,19 +83,19 @@ static __inline__ isdn_net_local * isdn_net_get_locked_lp(isdn_net_dev *nd)
spin_lock_irqsave(&nd->queue_lock, flags);
lp = nd->queue; /* get lp on top of queue */
- spin_lock(&nd->queue->xmit_lock);
while (isdn_net_lp_busy(nd->queue)) {
- spin_unlock(&nd->queue->xmit_lock);
nd->queue = nd->queue->next;
if (nd->queue == lp) { /* not found -- should never happen */
lp = NULL;
goto errout;
}
- spin_lock(&nd->queue->xmit_lock);
}
lp = nd->queue;
nd->queue = nd->queue->next;
+ spin_unlock_irqrestore(&nd->queue_lock, flags);
+ spin_lock(&lp->xmit_lock);
local_bh_disable();
+ return lp;
errout:
spin_unlock_irqrestore(&nd->queue_lock, flags);
return lp;
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 2d14b64202a3..642d5aaf53ce 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -1535,10 +1535,8 @@ static int isdn_ppp_mp_bundle_array_init(void)
int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle);
if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL )
return -ENOMEM;
- for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+ for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
- skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags);
- }
return 0;
}
@@ -1571,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL)
return -ENOMEM;
lp->next = lp->last = lp; /* nobody else in a queue */
- skb_queue_head_init(&lp->netdev->pb->frags);
+ lp->netdev->pb->frags = NULL;
lp->netdev->pb->frames = 0;
lp->netdev->pb->seq = UINT_MAX;
}
@@ -1583,29 +1581,28 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
static u32 isdn_ppp_mp_get_seq( int short_seq,
struct sk_buff * skb, u32 last_seq );
-static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from,
- struct sk_buff *to);
-static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
- struct sk_buff *from, struct sk_buff *to,
- u32 lastseq);
-static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb);
+static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
+ struct sk_buff * from, struct sk_buff * to );
+static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
+ struct sk_buff * from, struct sk_buff * to );
+static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb );
static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb );
static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
- struct sk_buff *skb)
+ struct sk_buff *skb)
{
- struct sk_buff *newfrag, *frag, *start, *nextf;
- u32 newseq, minseq, thisseq;
- isdn_mppp_stats *stats;
struct ippp_struct *is;
+ isdn_net_local * lpq;
+ ippp_bundle * mp;
+ isdn_mppp_stats * stats;
+ struct sk_buff * newfrag, * frag, * start, *nextf;
+ u32 newseq, minseq, thisseq;
unsigned long flags;
- isdn_net_local *lpq;
- ippp_bundle *mp;
int slot;
spin_lock_irqsave(&net_dev->pb->lock, flags);
- mp = net_dev->pb;
- stats = &mp->stats;
+ mp = net_dev->pb;
+ stats = &mp->stats;
slot = lp->ppp_slot;
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: lp->ppp_slot(%d)\n",
@@ -1616,19 +1613,20 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
return;
}
is = ippp_table[slot];
- if (++mp->frames > stats->max_queue_len)
+ if( ++mp->frames > stats->max_queue_len )
stats->max_queue_len = mp->frames;
-
+
if (is->debug & 0x8)
isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb);
- newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
- skb, is->last_link_seqno);
+ newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
+ skb, is->last_link_seqno);
+
/* if this packet seq # is less than last already processed one,
* toss it right away, but check for sequence start case first
*/
- if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) {
+ if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) {
mp->seq = newseq; /* the first packet: required for
* rfc1990 non-compliant clients --
* prevents constant packet toss */
@@ -1638,7 +1636,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
spin_unlock_irqrestore(&mp->lock, flags);
return;
}
-
+
/* find the minimum received sequence number over all links */
is->last_link_seqno = minseq = newseq;
for (lpq = net_dev->queue;;) {
@@ -1659,31 +1657,22 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
* packets */
newfrag = skb;
- /* Insert new fragment into the proper sequence slot. */
- skb_queue_walk(&mp->frags, frag) {
- if (MP_SEQ(frag) == newseq) {
- isdn_ppp_mp_free_skb(mp, newfrag);
- newfrag = NULL;
- break;
- }
- if (MP_LT(newseq, MP_SEQ(frag))) {
- __skb_queue_before(&mp->frags, frag, newfrag);
- newfrag = NULL;
- break;
- }
- }
- if (newfrag)
- __skb_queue_tail(&mp->frags, newfrag);
+ /* if this new fragment is before the first one, then enqueue it now. */
+ if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
+ newfrag->next = frag;
+ mp->frags = frag = newfrag;
+ newfrag = NULL;
+ }
- frag = skb_peek(&mp->frags);
- start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) &&
- (MP_SEQ(frag) == mp->seq)) ? frag : NULL;
- if (!start)
- goto check_overflow;
+ start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
+ MP_SEQ(frag) == mp->seq ? frag : NULL;
- /* main fragment traversing loop
+ /*
+ * main fragment traversing loop
*
* try to accomplish several tasks:
+ * - insert new fragment into the proper sequence slot (once that's done
+ * newfrag will be set to NULL)
* - reassemble any complete fragment sequence (non-null 'start'
* indicates there is a continguous sequence present)
* - discard any incomplete sequences that are below minseq -- due
@@ -1692,46 +1681,71 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
* come to complete such sequence and it should be discarded
*
* loop completes when we accomplished the following tasks:
+ * - new fragment is inserted in the proper sequence ('newfrag' is
+ * set to NULL)
* - we hit a gap in the sequence, so no reassembly/processing is
* possible ('start' would be set to NULL)
*
* algorithm for this code is derived from code in the book
* 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
*/
- skb_queue_walk_safe(&mp->frags, frag, nextf) {
- thisseq = MP_SEQ(frag);
-
- /* check for misplaced start */
- if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
- printk(KERN_WARNING"isdn_mppp(seq %d): new "
- "BEGIN flag with no prior END", thisseq);
- stats->seqerrs++;
- stats->frame_drops++;
- isdn_ppp_mp_discard(mp, start, frag);
- start = frag;
- } else if (MP_LE(thisseq, minseq)) {
- if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
+ while (start != NULL || newfrag != NULL) {
+
+ thisseq = MP_SEQ(frag);
+ nextf = frag->next;
+
+ /* drop any duplicate fragments */
+ if (newfrag != NULL && thisseq == newseq) {
+ isdn_ppp_mp_free_skb(mp, newfrag);
+ newfrag = NULL;
+ }
+
+ /* insert new fragment before next element if possible. */
+ if (newfrag != NULL && (nextf == NULL ||
+ MP_LT(newseq, MP_SEQ(nextf)))) {
+ newfrag->next = nextf;
+ frag->next = nextf = newfrag;
+ newfrag = NULL;
+ }
+
+ if (start != NULL) {
+ /* check for misplaced start */
+ if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
+ printk(KERN_WARNING"isdn_mppp(seq %d): new "
+ "BEGIN flag with no prior END", thisseq);
+ stats->seqerrs++;
+ stats->frame_drops++;
+ start = isdn_ppp_mp_discard(mp, start,frag);
+ nextf = frag->next;
+ }
+ } else if (MP_LE(thisseq, minseq)) {
+ if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
start = frag;
- else {
+ else {
if (MP_FLAGS(frag) & MP_END_FRAG)
- stats->frame_drops++;
- __skb_unlink(skb, &mp->frags);
+ stats->frame_drops++;
+ if( mp->frags == frag )
+ mp->frags = nextf;
isdn_ppp_mp_free_skb(mp, frag);
+ frag = nextf;
continue;
- }
+ }
}
-
- /* if we have end fragment, then we have full reassembly
- * sequence -- reassemble and process packet now
+
+ /* if start is non-null and we have end fragment, then
+ * we have full reassembly sequence -- reassemble
+ * and process packet now
*/
- if (MP_FLAGS(frag) & MP_END_FRAG) {
- minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
- /* Reassemble the packet then dispatch it */
- isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq);
+ if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
+ minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
+ /* Reassemble the packet then dispatch it */
+ isdn_ppp_mp_reassembly(net_dev, lp, start, nextf);
+
+ start = NULL;
+ frag = NULL;
- start = NULL;
- frag = NULL;
- }
+ mp->frags = nextf;
+ }
/* check if need to update start pointer: if we just
* reassembled the packet and sequence is contiguous
@@ -1742,25 +1756,26 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
* below low watermark and set start to the next frag or
* clear start ptr.
*/
- if (nextf != (struct sk_buff *)&mp->frags &&
+ if (nextf != NULL &&
((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
- /* if we just reassembled and the next one is here,
- * then start another reassembly.
- */
- if (frag == NULL) {
+ /* if we just reassembled and the next one is here,
+ * then start another reassembly. */
+
+ if (frag == NULL) {
if (MP_FLAGS(nextf) & MP_BEGIN_FRAG)
- start = nextf;
- else {
- printk(KERN_WARNING"isdn_mppp(seq %d):"
- " END flag with no following "
- "BEGIN", thisseq);
+ start = nextf;
+ else
+ {
+ printk(KERN_WARNING"isdn_mppp(seq %d):"
+ " END flag with no following "
+ "BEGIN", thisseq);
stats->seqerrs++;
}
}
- } else {
- if (nextf != (struct sk_buff *)&mp->frags &&
- frag != NULL &&
- MP_LT(thisseq, minseq)) {
+
+ } else {
+ if ( nextf != NULL && frag != NULL &&
+ MP_LT(thisseq, minseq)) {
/* we've got a break in the sequence
* and we not at the end yet
* and we did not just reassembled
@@ -1769,39 +1784,41 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
* discard all the frames below low watermark
* and start over */
stats->frame_drops++;
- isdn_ppp_mp_discard(mp, start, nextf);
+ mp->frags = isdn_ppp_mp_discard(mp,start,nextf);
}
/* break in the sequence, no reassembly */
- start = NULL;
- }
- if (!start)
- break;
- }
-
-check_overflow:
+ start = NULL;
+ }
+
+ frag = nextf;
+ } /* while -- main loop */
+
+ if (mp->frags == NULL)
+ mp->frags = frag;
+
/* rather straighforward way to deal with (not very) possible
- * queue overflow
- */
+ * queue overflow */
if (mp->frames > MP_MAX_QUEUE_LEN) {
stats->overflows++;
- skb_queue_walk_safe(&mp->frags, frag, nextf) {
- if (mp->frames <= MP_MAX_QUEUE_LEN)
- break;
- __skb_unlink(frag, &mp->frags);
- isdn_ppp_mp_free_skb(mp, frag);
+ while (mp->frames > MP_MAX_QUEUE_LEN) {
+ frag = mp->frags->next;
+ isdn_ppp_mp_free_skb(mp, mp->frags);
+ mp->frags = frag;
}
}
spin_unlock_irqrestore(&mp->lock, flags);
}
-static void isdn_ppp_mp_cleanup(isdn_net_local *lp)
+static void isdn_ppp_mp_cleanup( isdn_net_local * lp )
{
- struct sk_buff *skb, *tmp;
-
- skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) {
- __skb_unlink(skb, &lp->netdev->pb->frags);
- isdn_ppp_mp_free_skb(lp->netdev->pb, skb);
- }
+ struct sk_buff * frag = lp->netdev->pb->frags;
+ struct sk_buff * nextfrag;
+ while( frag ) {
+ nextfrag = frag->next;
+ isdn_ppp_mp_free_skb(lp->netdev->pb, frag);
+ frag = nextfrag;
+ }
+ lp->netdev->pb->frags = NULL;
}
static u32 isdn_ppp_mp_get_seq( int short_seq,
@@ -1838,115 +1855,72 @@ static u32 isdn_ppp_mp_get_seq( int short_seq,
return seq;
}
-static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from,
- struct sk_buff *to)
+struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
+ struct sk_buff * from, struct sk_buff * to )
{
- if (from) {
- struct sk_buff *skb, *tmp;
- int freeing = 0;
-
- skb_queue_walk_safe(&mp->frags, skb, tmp) {
- if (skb == to)
- break;
- if (skb == from)
- freeing = 1;
- if (!freeing)
- continue;
- __skb_unlink(skb, &mp->frags);
- isdn_ppp_mp_free_skb(mp, skb);
+ if( from )
+ while (from != to) {
+ struct sk_buff * next = from->next;
+ isdn_ppp_mp_free_skb(mp, from);
+ from = next;
}
- }
-}
-
-static unsigned int calc_tot_len(struct sk_buff_head *queue,
- struct sk_buff *from, struct sk_buff *to)
-{
- unsigned int tot_len = 0;
- struct sk_buff *skb;
- int found_start = 0;
-
- skb_queue_walk(queue, skb) {
- if (skb == from)
- found_start = 1;
- if (!found_start)
- continue;
- tot_len += skb->len - MP_HEADER_LEN;
- if (skb == to)
- break;
- }
- return tot_len;
+ return from;
}
-/* Reassemble packet using fragments in the reassembly queue from
- * 'from' until 'to', inclusive.
- */
-static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
- struct sk_buff *from, struct sk_buff *to,
- u32 lastseq)
+void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
+ struct sk_buff * from, struct sk_buff * to )
{
- ippp_bundle *mp = net_dev->pb;
- unsigned int tot_len;
- struct sk_buff *skb;
+ ippp_bundle * mp = net_dev->pb;
int proto;
+ struct sk_buff * skb;
+ unsigned int tot_len;
if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
__func__, lp->ppp_slot);
return;
}
-
- tot_len = calc_tot_len(&mp->frags, from, to);
-
- if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) {
- if (ippp_table[lp->ppp_slot]->debug & 0x40)
+ if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
+ if( ippp_table[lp->ppp_slot]->debug & 0x40 )
printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
- "len %d\n", MP_SEQ(from), from->len);
+ "len %d\n", MP_SEQ(from), from->len );
skb = from;
skb_pull(skb, MP_HEADER_LEN);
- __skb_unlink(skb, &mp->frags);
mp->frames--;
} else {
- struct sk_buff *walk, *tmp;
- int found_start = 0;
+ struct sk_buff * frag;
+ int n;
- if (ippp_table[lp->ppp_slot]->debug & 0x40)
- printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
- "to %d, len %d\n", MP_SEQ(from), lastseq,
- tot_len);
+ for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++)
+ tot_len += frag->len - MP_HEADER_LEN;
- skb = dev_alloc_skb(tot_len);
- if (!skb)
+ if( ippp_table[lp->ppp_slot]->debug & 0x40 )
+ printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
+ "to %d, len %d\n", MP_SEQ(from),
+ (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len );
+ if( (skb = dev_alloc_skb(tot_len)) == NULL ) {
printk(KERN_ERR "isdn_mppp: cannot allocate sk buff "
- "of size %d\n", tot_len);
-
- found_start = 0;
- skb_queue_walk_safe(&mp->frags, walk, tmp) {
- if (walk == from)
- found_start = 1;
- if (!found_start)
- continue;
+ "of size %d\n", tot_len);
+ isdn_ppp_mp_discard(mp, from, to);
+ return;
+ }
- if (skb) {
- unsigned int len = walk->len - MP_HEADER_LEN;
- skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN,
- skb_put(skb, len),
- len);
- }
- __skb_unlink(walk, &mp->frags);
- isdn_ppp_mp_free_skb(mp, walk);
+ while( from != to ) {
+ unsigned int len = from->len - MP_HEADER_LEN;
- if (walk == to)
- break;
+ skb_copy_from_linear_data_offset(from, MP_HEADER_LEN,
+ skb_put(skb,len),
+ len);
+ frag = from->next;
+ isdn_ppp_mp_free_skb(mp, from);
+ from = frag;
}
}
- if (!skb)
- return;
-
proto = isdn_ppp_strip_proto(skb);
isdn_ppp_push_higher(net_dev, lp, skb, proto);
}
-static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb)
+static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb)
{
dev_kfree_skb(skb);
mp->frames--;
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
index 3e1532a180ff..0d05ec43012c 100644
--- a/drivers/isdn/mISDN/stack.c
+++ b/drivers/isdn/mISDN/stack.c
@@ -364,7 +364,7 @@ add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
static int
st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
{
- if (!ch->st || ch->st->layer1)
+ if (!ch->st || !ch->st->layer1)
return -EINVAL;
return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg);
}
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 7467980b8cf9..e5225d28f392 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -78,6 +78,8 @@ static int __devinit create_gpio_led(const struct gpio_led *template,
{
int ret, state;
+ led_dat->gpio = -1;
+
/* skip leds that aren't available */
if (!gpio_is_valid(template->gpio)) {
printk(KERN_INFO "Skipping unavailable LED gpio %d (%s)\n",
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index b40fb9b6c862..6f308a4757ee 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -405,7 +405,11 @@ static int __init via_pmu_start(void)
printk(KERN_ERR "via-pmu: can't map interrupt\n");
return -ENODEV;
}
- if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) {
+ /* We set IRQF_TIMER because we don't want the interrupt to be disabled
+ * between the 2 passes of driver suspend, we control our own disabling
+ * for that one
+ */
+ if (request_irq(irq, via_pmu_interrupt, IRQF_TIMER, "VIA-PMU", (void *)0)) {
printk(KERN_ERR "via-pmu: can't request irq %d\n", irq);
return -ENODEV;
}
@@ -419,7 +423,7 @@ static int __init via_pmu_start(void)
gpio_irq = irq_of_parse_and_map(gpio_node, 0);
if (gpio_irq != NO_IRQ) {
- if (request_irq(gpio_irq, gpio1_interrupt, 0,
+ if (request_irq(gpio_irq, gpio1_interrupt, IRQF_TIMER,
"GPIO1 ADB", (void *)0))
printk(KERN_ERR "pmu: can't get irq %d"
" (GPIO1)\n", gpio_irq);
@@ -925,8 +929,7 @@ proc_write_options(struct file *file, const char __user *buffer,
#ifdef CONFIG_ADB
/* Send an ADB command */
-static int
-pmu_send_request(struct adb_request *req, int sync)
+static int pmu_send_request(struct adb_request *req, int sync)
{
int i, ret;
@@ -1005,16 +1008,11 @@ pmu_send_request(struct adb_request *req, int sync)
}
/* Enable/disable autopolling */
-static int
-pmu_adb_autopoll(int devs)
+static int __pmu_adb_autopoll(int devs)
{
struct adb_request req;
- if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
- return -ENXIO;
-
if (devs) {
- adb_dev_map = devs;
pmu_request(&req, NULL, 5, PMU_ADB_CMD, 0, 0x86,
adb_dev_map >> 8, adb_dev_map);
pmu_adb_flags = 2;
@@ -1027,9 +1025,17 @@ pmu_adb_autopoll(int devs)
return 0;
}
+static int pmu_adb_autopoll(int devs)
+{
+ if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
+ return -ENXIO;
+
+ adb_dev_map = devs;
+ return __pmu_adb_autopoll(devs);
+}
+
/* Reset the ADB bus */
-static int
-pmu_adb_reset_bus(void)
+static int pmu_adb_reset_bus(void)
{
struct adb_request req;
int save_autopoll = adb_dev_map;
@@ -1038,13 +1044,13 @@ pmu_adb_reset_bus(void)
return -ENXIO;
/* anyone got a better idea?? */
- pmu_adb_autopoll(0);
+ __pmu_adb_autopoll(0);
- req.nbytes = 5;
+ req.nbytes = 4;
req.done = NULL;
req.data[0] = PMU_ADB_CMD;
- req.data[1] = 0;
- req.data[2] = ADB_BUSRESET;
+ req.data[1] = ADB_BUSRESET;
+ req.data[2] = 0;
req.data[3] = 0;
req.data[4] = 0;
req.reply_len = 0;
@@ -1056,7 +1062,7 @@ pmu_adb_reset_bus(void)
pmu_wait_complete(&req);
if (save_autopoll != 0)
- pmu_adb_autopoll(save_autopoll);
+ __pmu_adb_autopoll(save_autopoll);
return 0;
}
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index 1dc4185bd781..e355e7f6a536 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -46,7 +46,7 @@ obj-$(CONFIG_DM_LOG_USERSPACE) += dm-log-userspace.o
obj-$(CONFIG_DM_ZERO) += dm-zero.o
quiet_cmd_unroll = UNROLL $@
- cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
+ cmd_unroll = $(AWK) -f$(srctree)/$(src)/unroll.awk -vN=$(UNROLL) \
< $< > $@ || ( rm -f $@ && exit 1 )
ifeq ($(CONFIG_ALTIVEC),y)
@@ -59,56 +59,56 @@ endif
targets += raid6int1.c
$(obj)/raid6int1.c: UNROLL := 1
-$(obj)/raid6int1.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int1.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
targets += raid6int2.c
$(obj)/raid6int2.c: UNROLL := 2
-$(obj)/raid6int2.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int2.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
targets += raid6int4.c
$(obj)/raid6int4.c: UNROLL := 4
-$(obj)/raid6int4.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int4.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
targets += raid6int8.c
$(obj)/raid6int8.c: UNROLL := 8
-$(obj)/raid6int8.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int8.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
targets += raid6int16.c
$(obj)/raid6int16.c: UNROLL := 16
-$(obj)/raid6int16.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int16.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
targets += raid6int32.c
$(obj)/raid6int32.c: UNROLL := 32
-$(obj)/raid6int32.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int32.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
CFLAGS_raid6altivec1.o += $(altivec_flags)
targets += raid6altivec1.c
$(obj)/raid6altivec1.c: UNROLL := 1
-$(obj)/raid6altivec1.c: $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+$(obj)/raid6altivec1.c: $(src)/raid6altivec.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
CFLAGS_raid6altivec2.o += $(altivec_flags)
targets += raid6altivec2.c
$(obj)/raid6altivec2.c: UNROLL := 2
-$(obj)/raid6altivec2.c: $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+$(obj)/raid6altivec2.c: $(src)/raid6altivec.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
CFLAGS_raid6altivec4.o += $(altivec_flags)
targets += raid6altivec4.c
$(obj)/raid6altivec4.c: UNROLL := 4
-$(obj)/raid6altivec4.c: $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+$(obj)/raid6altivec4.c: $(src)/raid6altivec.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
CFLAGS_raid6altivec8.o += $(altivec_flags)
targets += raid6altivec8.c
$(obj)/raid6altivec8.c: UNROLL := 8
-$(obj)/raid6altivec8.c: $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+$(obj)/raid6altivec8.c: $(src)/raid6altivec.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
quiet_cmd_mktable = TABLE $@
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 6986b0059d23..60e2b322db11 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1624,10 +1624,11 @@ int bitmap_create(mddev_t *mddev)
bitmap->offset = mddev->bitmap_offset;
if (file) {
get_file(file);
- do_sync_mapping_range(file->f_mapping, 0, LLONG_MAX,
- SYNC_FILE_RANGE_WAIT_BEFORE |
- SYNC_FILE_RANGE_WRITE |
- SYNC_FILE_RANGE_WAIT_AFTER);
+ /* As future accesses to this file will use bmap,
+ * and bypass the page cache, we must sync the file
+ * first.
+ */
+ vfs_fsync(file, file->f_dentry, 1);
}
/* read superblock from bitmap file (this sets bitmap->chunksize) */
err = bitmap_read_sb(bitmap);
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index 556acff3952f..7dbe652efb5a 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -138,16 +138,6 @@ int dm_exception_store_type_unregister(struct dm_exception_store_type *type)
}
EXPORT_SYMBOL(dm_exception_store_type_unregister);
-/*
- * Round a number up to the nearest 'size' boundary. size must
- * be a power of 2.
- */
-static ulong round_up(ulong n, ulong size)
-{
- size--;
- return (n + size) & ~size;
-}
-
static int set_chunk_size(struct dm_exception_store *store,
const char *chunk_size_arg, char **error)
{
@@ -155,7 +145,8 @@ static int set_chunk_size(struct dm_exception_store *store,
char *value;
chunk_size_ulong = simple_strtoul(chunk_size_arg, &value, 10);
- if (*chunk_size_arg == '\0' || *value != '\0') {
+ if (*chunk_size_arg == '\0' || *value != '\0' ||
+ chunk_size_ulong > UINT_MAX) {
*error = "Invalid chunk size";
return -EINVAL;
}
@@ -165,40 +156,35 @@ static int set_chunk_size(struct dm_exception_store *store,
return 0;
}
- /*
- * Chunk size must be multiple of page size. Silently
- * round up if it's not.
- */
- chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
-
- return dm_exception_store_set_chunk_size(store, chunk_size_ulong,
+ return dm_exception_store_set_chunk_size(store,
+ (unsigned) chunk_size_ulong,
error);
}
int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
- unsigned long chunk_size_ulong,
+ unsigned chunk_size,
char **error)
{
/* Check chunk_size is a power of 2 */
- if (!is_power_of_2(chunk_size_ulong)) {
+ if (!is_power_of_2(chunk_size)) {
*error = "Chunk size is not a power of 2";
return -EINVAL;
}
/* Validate the chunk size against the device block size */
- if (chunk_size_ulong % (bdev_logical_block_size(store->cow->bdev) >> 9)) {
+ if (chunk_size % (bdev_logical_block_size(store->cow->bdev) >> 9)) {
*error = "Chunk size is not a multiple of device blocksize";
return -EINVAL;
}
- if (chunk_size_ulong > INT_MAX >> SECTOR_SHIFT) {
+ if (chunk_size > INT_MAX >> SECTOR_SHIFT) {
*error = "Chunk size is too high";
return -EINVAL;
}
- store->chunk_size = chunk_size_ulong;
- store->chunk_mask = chunk_size_ulong - 1;
- store->chunk_shift = ffs(chunk_size_ulong) - 1;
+ store->chunk_size = chunk_size;
+ store->chunk_mask = chunk_size - 1;
+ store->chunk_shift = ffs(chunk_size) - 1;
return 0;
}
@@ -251,7 +237,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
r = set_chunk_size(tmp_store, argv[2], &ti->error);
if (r)
- goto bad_cow;
+ goto bad_ctr;
r = type->ctr(tmp_store, 0, NULL);
if (r) {
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h
index 812c71872ba0..8a223a48802c 100644
--- a/drivers/md/dm-exception-store.h
+++ b/drivers/md/dm-exception-store.h
@@ -101,9 +101,9 @@ struct dm_exception_store {
struct dm_dev *cow;
/* Size of data blocks saved - must be a power of 2 */
- chunk_t chunk_size;
- chunk_t chunk_mask;
- chunk_t chunk_shift;
+ unsigned chunk_size;
+ unsigned chunk_mask;
+ unsigned chunk_shift;
void *context;
};
@@ -169,7 +169,7 @@ int dm_exception_store_type_register(struct dm_exception_store_type *type);
int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
- unsigned long chunk_size_ulong,
+ unsigned chunk_size,
char **error);
int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index 652bd33109e3..7ac2c1450d10 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -156,7 +156,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
}
/* The ptr value is sufficient for local unique id */
- lc->luid = (uint64_t)lc;
+ lc->luid = (unsigned long)lc;
lc->ti = ti;
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index d5b2e08750d5..0c746420c008 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -284,12 +284,13 @@ static int read_header(struct pstore *ps, int *new_snapshot)
{
int r;
struct disk_header *dh;
- chunk_t chunk_size;
+ unsigned chunk_size;
int chunk_size_supplied = 1;
char *chunk_err;
/*
- * Use default chunk size (or hardsect_size, if larger) if none supplied
+ * Use default chunk size (or logical_block_size, if larger)
+ * if none supplied
*/
if (!ps->store->chunk_size) {
ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
@@ -334,10 +335,9 @@ static int read_header(struct pstore *ps, int *new_snapshot)
return 0;
if (chunk_size_supplied)
- DMWARN("chunk size %llu in device metadata overrides "
- "table chunk size of %llu.",
- (unsigned long long)chunk_size,
- (unsigned long long)ps->store->chunk_size);
+ DMWARN("chunk size %u in device metadata overrides "
+ "table chunk size of %u.",
+ chunk_size, ps->store->chunk_size);
/* We had a bogus chunk_size. Fix stuff up. */
free_area(ps);
@@ -345,8 +345,8 @@ static int read_header(struct pstore *ps, int *new_snapshot)
r = dm_exception_store_set_chunk_size(ps->store, chunk_size,
&chunk_err);
if (r) {
- DMERR("invalid on-disk chunk size %llu: %s.",
- (unsigned long long)chunk_size, chunk_err);
+ DMERR("invalid on-disk chunk size %u: %s.",
+ chunk_size, chunk_err);
return r;
}
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 57f1bf7f3b7a..3a3ba46e6d4b 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -296,6 +296,7 @@ static void __insert_origin(struct origin *o)
*/
static int register_snapshot(struct dm_snapshot *snap)
{
+ struct dm_snapshot *l;
struct origin *o, *new_o;
struct block_device *bdev = snap->origin->bdev;
@@ -319,7 +320,11 @@ static int register_snapshot(struct dm_snapshot *snap)
__insert_origin(o);
}
- list_add_tail(&snap->list, &o->snapshots);
+ /* Sort the list according to chunk size, largest-first smallest-last */
+ list_for_each_entry(l, &o->snapshots, list)
+ if (l->store->chunk_size < snap->store->chunk_size)
+ break;
+ list_add_tail(&snap->list, &l->list);
up_write(&_origins_lock);
return 0;
@@ -668,6 +673,11 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
bio_list_init(&s->queued_bios);
INIT_WORK(&s->queued_bios_work, flush_queued_bios);
+ if (!s->store->chunk_size) {
+ ti->error = "Chunk size not set";
+ goto bad_load_and_register;
+ }
+
/* Add snapshot to the list of snapshots for this origin */
/* Exceptions aren't triggered till snapshot_resume() is called */
if (register_snapshot(s)) {
@@ -951,7 +961,7 @@ static void start_copy(struct dm_snap_pending_exception *pe)
src.bdev = bdev;
src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
- src.count = min(s->store->chunk_size, dev_size - src.sector);
+ src.count = min((sector_t)s->store->chunk_size, dev_size - src.sector);
dest.bdev = s->store->cow->bdev;
dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
@@ -1142,6 +1152,8 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
unsigned sz = 0;
struct dm_snapshot *snap = ti->private;
+ down_write(&snap->lock);
+
switch (type) {
case STATUSTYPE_INFO:
if (!snap->valid)
@@ -1173,6 +1185,8 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
break;
}
+ up_write(&snap->lock);
+
return 0;
}
@@ -1388,7 +1402,7 @@ static void origin_resume(struct dm_target *ti)
struct dm_dev *dev = ti->private;
struct dm_snapshot *snap;
struct origin *o;
- chunk_t chunk_size = 0;
+ unsigned chunk_size = 0;
down_read(&_origins_lock);
o = __lookup_origin(dev->bdev);
@@ -1465,7 +1479,7 @@ static int __init dm_snapshot_init(void)
r = dm_register_target(&snapshot_target);
if (r) {
DMERR("snapshot target register failed %d", r);
- return r;
+ goto bad_register_snapshot_target;
}
r = dm_register_target(&origin_target);
@@ -1522,6 +1536,9 @@ bad2:
dm_unregister_target(&origin_target);
bad1:
dm_unregister_target(&snapshot_target);
+
+bad_register_snapshot_target:
+ dm_exception_store_exit();
return r;
}
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 376f1ab48a24..724efc63904d 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -47,6 +47,7 @@ struct dm_io {
atomic_t io_count;
struct bio *bio;
unsigned long start_time;
+ spinlock_t endio_lock;
};
/*
@@ -578,8 +579,12 @@ static void dec_pending(struct dm_io *io, int error)
struct mapped_device *md = io->md;
/* Push-back supersedes any I/O errors */
- if (error && !(io->error > 0 && __noflush_suspending(md)))
- io->error = error;
+ if (unlikely(error)) {
+ spin_lock_irqsave(&io->endio_lock, flags);
+ if (!(io->error > 0 && __noflush_suspending(md)))
+ io->error = error;
+ spin_unlock_irqrestore(&io->endio_lock, flags);
+ }
if (atomic_dec_and_test(&io->io_count)) {
if (io->error == DM_ENDIO_REQUEUE) {
@@ -1226,6 +1231,7 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
atomic_set(&ci.io->io_count, 1);
ci.io->bio = bio;
ci.io->md = md;
+ spin_lock_init(&ci.io->endio_lock);
ci.sector = bio->bi_sector;
ci.sector_count = bio_sectors(bio);
if (unlikely(bio_empty_barrier(bio)))
@@ -1822,6 +1828,7 @@ static struct mapped_device *alloc_dev(int minor)
bad_bdev:
destroy_workqueue(md->wq);
bad_thread:
+ del_gendisk(md->disk);
put_disk(md->disk);
bad_disk:
blk_cleanup_queue(md->queue);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 26ba42a79129..b182f86a19dd 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -944,6 +944,14 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
desc->raid_disk < mddev->raid_disks */) {
set_bit(In_sync, &rdev->flags);
rdev->raid_disk = desc->raid_disk;
+ } else if (desc->state & (1<<MD_DISK_ACTIVE)) {
+ /* active but not in sync implies recovery up to
+ * reshape position. We don't know exactly where
+ * that is, so set to zero for now */
+ if (mddev->minor_version >= 91) {
+ rdev->recovery_offset = 0;
+ rdev->raid_disk = desc->raid_disk;
+ }
}
if (desc->state & (1<<MD_DISK_WRITEMOSTLY))
set_bit(WriteMostly, &rdev->flags);
@@ -1032,8 +1040,19 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
list_for_each_entry(rdev2, &mddev->disks, same_set) {
mdp_disk_t *d;
int desc_nr;
- if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
- && !test_bit(Faulty, &rdev2->flags))
+ int is_active = test_bit(In_sync, &rdev2->flags);
+
+ if (rdev2->raid_disk >= 0 &&
+ sb->minor_version >= 91)
+ /* we have nowhere to store the recovery_offset,
+ * but if it is not below the reshape_position,
+ * we can piggy-back on that.
+ */
+ is_active = 1;
+ if (rdev2->raid_disk < 0 ||
+ test_bit(Faulty, &rdev2->flags))
+ is_active = 0;
+ if (is_active)
desc_nr = rdev2->raid_disk;
else
desc_nr = next_spare++;
@@ -1043,16 +1062,16 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
d->number = rdev2->desc_nr;
d->major = MAJOR(rdev2->bdev->bd_dev);
d->minor = MINOR(rdev2->bdev->bd_dev);
- if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
- && !test_bit(Faulty, &rdev2->flags))
+ if (is_active)
d->raid_disk = rdev2->raid_disk;
else
d->raid_disk = rdev2->desc_nr; /* compatibility */
if (test_bit(Faulty, &rdev2->flags))
d->state = (1<<MD_DISK_FAULTY);
- else if (test_bit(In_sync, &rdev2->flags)) {
+ else if (is_active) {
d->state = (1<<MD_DISK_ACTIVE);
- d->state |= (1<<MD_DISK_SYNC);
+ if (test_bit(In_sync, &rdev2->flags))
+ d->state |= (1<<MD_DISK_SYNC);
active++;
working++;
} else {
@@ -1382,8 +1401,6 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
if (rdev->raid_disk >= 0 &&
!test_bit(In_sync, &rdev->flags)) {
- if (mddev->curr_resync_completed > rdev->recovery_offset)
- rdev->recovery_offset = mddev->curr_resync_completed;
if (rdev->recovery_offset > 0) {
sb->feature_map |=
cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
@@ -1917,6 +1934,14 @@ static void sync_sbs(mddev_t * mddev, int nospares)
*/
mdk_rdev_t *rdev;
+ /* First make sure individual recovery_offsets are correct */
+ list_for_each_entry(rdev, &mddev->disks, same_set) {
+ if (rdev->raid_disk >= 0 &&
+ !test_bit(In_sync, &rdev->flags) &&
+ mddev->curr_resync_completed > rdev->recovery_offset)
+ rdev->recovery_offset = mddev->curr_resync_completed;
+
+ }
list_for_each_entry(rdev, &mddev->disks, same_set) {
if (rdev->sb_events == mddev->events ||
(nospares &&
@@ -2631,7 +2656,7 @@ static void analyze_sbs(mddev_t * mddev)
rdev->desc_nr = i++;
rdev->raid_disk = rdev->desc_nr;
set_bit(In_sync, &rdev->flags);
- } else if (rdev->raid_disk >= mddev->raid_disks) {
+ } else if (rdev->raid_disk >= (mddev->raid_disks - min(0, mddev->delta_disks))) {
rdev->raid_disk = -1;
clear_bit(In_sync, &rdev->flags);
}
@@ -6504,8 +6529,9 @@ void md_do_sync(mddev_t *mddev)
skip:
mddev->curr_resync = 0;
mddev->curr_resync_completed = 0;
- mddev->resync_min = 0;
- mddev->resync_max = MaxSector;
+ if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery))
+ /* We completed so max setting can be forgotten. */
+ mddev->resync_max = MaxSector;
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
wake_up(&resync_wait);
set_bit(MD_RECOVERY_DONE, &mddev->recovery);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index d1b9bd5fd4f6..e07ce2e033a9 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -64,7 +64,7 @@ static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
/* allocate a r1bio with room for raid_disks entries in the bios array */
r1_bio = kzalloc(size, gfp_flags);
- if (!r1_bio)
+ if (!r1_bio && pi->mddev)
unplug_slaves(pi->mddev);
return r1_bio;
@@ -1650,11 +1650,12 @@ static void raid1d(mddev_t *mddev)
r1_bio->sector,
r1_bio->sectors);
unfreeze_array(conf);
- }
+ } else
+ md_error(mddev,
+ conf->mirrors[r1_bio->read_disk].rdev);
bio = r1_bio->bios[r1_bio->read_disk];
- if ((disk=read_balance(conf, r1_bio)) == -1 ||
- disk == r1_bio->read_disk) {
+ if ((disk=read_balance(conf, r1_bio)) == -1) {
printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
" read error for block %llu\n",
bdevname(bio->bi_bdev,b),
@@ -1683,6 +1684,7 @@ static void raid1d(mddev_t *mddev)
generic_make_request(bio);
}
}
+ cond_resched();
}
if (unplug)
unplug_slaves(mddev);
@@ -1978,13 +1980,14 @@ static int run(mddev_t *mddev)
conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
if (!conf->poolinfo)
goto out_no_mem;
- conf->poolinfo->mddev = mddev;
+ conf->poolinfo->mddev = NULL;
conf->poolinfo->raid_disks = mddev->raid_disks;
conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
r1bio_pool_free,
conf->poolinfo);
if (!conf->r1bio_pool)
goto out_no_mem;
+ conf->poolinfo->mddev = mddev;
spin_lock_init(&conf->device_lock);
mddev->queue->queue_lock = &conf->device_lock;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 51c4c5c4d87a..c2cb7b87b440 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -68,7 +68,7 @@ static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
/* allocate a r10bio with room for raid_disks entries in the bios array */
r10_bio = kzalloc(size, gfp_flags);
- if (!r10_bio)
+ if (!r10_bio && conf->mddev)
unplug_slaves(conf->mddev);
return r10_bio;
@@ -1632,6 +1632,7 @@ static void raid10d(mddev_t *mddev)
generic_make_request(bio);
}
}
+ cond_resched();
}
if (unplug)
unplug_slaves(mddev);
@@ -2095,7 +2096,6 @@ static int run(mddev_t *mddev)
if (!conf->tmppage)
goto out_free_conf;
- conf->mddev = mddev;
conf->raid_disks = mddev->raid_disks;
conf->near_copies = nc;
conf->far_copies = fc;
@@ -2132,6 +2132,7 @@ static int run(mddev_t *mddev)
goto out_free_conf;
}
+ conf->mddev = mddev;
spin_lock_init(&conf->device_lock);
mddev->queue->queue_lock = &conf->device_lock;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 94829804ab7f..d29215d966da 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -156,13 +156,16 @@ static inline int raid6_next_disk(int disk, int raid_disks)
static int raid6_idx_to_slot(int idx, struct stripe_head *sh,
int *count, int syndrome_disks)
{
- int slot;
+ int slot = *count;
+ if (sh->ddf_layout)
+ (*count)++;
if (idx == sh->pd_idx)
return syndrome_disks;
if (idx == sh->qd_idx)
return syndrome_disks + 1;
- slot = (*count)++;
+ if (!sh->ddf_layout)
+ (*count)++;
return slot;
}
@@ -717,7 +720,7 @@ static int set_syndrome_sources(struct page **srcs, struct stripe_head *sh)
int i;
for (i = 0; i < disks; i++)
- srcs[i] = (void *)raid6_empty_zero_page;
+ srcs[i] = NULL;
count = 0;
i = d0_idx;
@@ -727,9 +730,8 @@ static int set_syndrome_sources(struct page **srcs, struct stripe_head *sh)
srcs[slot] = sh->dev[i].page;
i = raid6_next_disk(i, disks);
} while (i != d0_idx);
- BUG_ON(count != syndrome_disks);
- return count;
+ return syndrome_disks;
}
static struct dma_async_tx_descriptor *
@@ -814,7 +816,7 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu)
* slot number conversion for 'faila' and 'failb'
*/
for (i = 0; i < disks ; i++)
- blocks[i] = (void *)raid6_empty_zero_page;
+ blocks[i] = NULL;
count = 0;
i = d0_idx;
do {
@@ -828,7 +830,6 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu)
failb = slot;
i = raid6_next_disk(i, disks);
} while (i != d0_idx);
- BUG_ON(count != syndrome_disks);
BUG_ON(faila == failb);
if (failb < faila)
@@ -845,7 +846,7 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu)
init_async_submit(&submit, ASYNC_TX_FENCE, NULL,
ops_complete_compute, sh,
to_addr_conv(sh, percpu));
- return async_gen_syndrome(blocks, 0, count+2,
+ return async_gen_syndrome(blocks, 0, syndrome_disks+2,
STRIPE_SIZE, &submit);
} else {
struct page *dest;
@@ -1139,7 +1140,7 @@ static void ops_run_check_pq(struct stripe_head *sh, struct raid5_percpu *percpu
&sh->ops.zero_sum_result, percpu->spare_page, &submit);
}
-static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
+static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
{
int overlap_clear = 0, i, disks = sh->disks;
struct dma_async_tx_descriptor *tx = NULL;
@@ -1204,22 +1205,55 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
put_cpu();
}
+#ifdef CONFIG_MULTICORE_RAID456
+static void async_run_ops(void *param, async_cookie_t cookie)
+{
+ struct stripe_head *sh = param;
+ unsigned long ops_request = sh->ops.request;
+
+ clear_bit_unlock(STRIPE_OPS_REQ_PENDING, &sh->state);
+ wake_up(&sh->ops.wait_for_ops);
+
+ __raid_run_ops(sh, ops_request);
+ release_stripe(sh);
+}
+
+static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
+{
+ /* since handle_stripe can be called outside of raid5d context
+ * we need to ensure sh->ops.request is de-staged before another
+ * request arrives
+ */
+ wait_event(sh->ops.wait_for_ops,
+ !test_and_set_bit_lock(STRIPE_OPS_REQ_PENDING, &sh->state));
+ sh->ops.request = ops_request;
+
+ atomic_inc(&sh->count);
+ async_schedule(async_run_ops, sh);
+}
+#else
+#define raid_run_ops __raid_run_ops
+#endif
+
static int grow_one_stripe(raid5_conf_t *conf)
{
struct stripe_head *sh;
+ int disks = max(conf->raid_disks, conf->previous_raid_disks);
sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL);
if (!sh)
return 0;
- memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev));
+ memset(sh, 0, sizeof(*sh) + (disks-1)*sizeof(struct r5dev));
sh->raid_conf = conf;
spin_lock_init(&sh->lock);
+ #ifdef CONFIG_MULTICORE_RAID456
+ init_waitqueue_head(&sh->ops.wait_for_ops);
+ #endif
- if (grow_buffers(sh, conf->raid_disks)) {
- shrink_buffers(sh, conf->raid_disks);
+ if (grow_buffers(sh, disks)) {
+ shrink_buffers(sh, disks);
kmem_cache_free(conf->slab_cache, sh);
return 0;
}
- sh->disks = conf->raid_disks;
/* we just created an active stripe so... */
atomic_set(&sh->count, 1);
atomic_inc(&conf->active_stripes);
@@ -1231,7 +1265,7 @@ static int grow_one_stripe(raid5_conf_t *conf)
static int grow_stripes(raid5_conf_t *conf, int num)
{
struct kmem_cache *sc;
- int devs = conf->raid_disks;
+ int devs = max(conf->raid_disks, conf->previous_raid_disks);
sprintf(conf->cache_name[0],
"raid%d-%s", conf->level, mdname(conf->mddev));
@@ -1329,6 +1363,9 @@ static int resize_stripes(raid5_conf_t *conf, int newsize)
nsh->raid_conf = conf;
spin_lock_init(&nsh->lock);
+ #ifdef CONFIG_MULTICORE_RAID456
+ init_waitqueue_head(&nsh->ops.wait_for_ops);
+ #endif
list_add(&nsh->lru, &newstripes);
}
@@ -1899,10 +1936,15 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
case ALGORITHM_PARITY_N:
break;
case ALGORITHM_ROTATING_N_CONTINUE:
+ /* Like left_symmetric, but P is before Q */
if (sh->pd_idx == 0)
i--; /* P D D D Q */
- else if (i > sh->pd_idx)
- i -= 2; /* D D Q P D */
+ else {
+ /* D D Q P D */
+ if (i < sh->pd_idx)
+ i += raid_disks;
+ i -= (sh->pd_idx + 1);
+ }
break;
case ALGORITHM_LEFT_ASYMMETRIC_6:
case ALGORITHM_RIGHT_ASYMMETRIC_6:
@@ -2896,7 +2938,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
*
*/
-static bool handle_stripe5(struct stripe_head *sh)
+static void handle_stripe5(struct stripe_head *sh)
{
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
@@ -3167,11 +3209,9 @@ static bool handle_stripe5(struct stripe_head *sh)
ops_run_io(sh, &s);
return_io(return_bi);
-
- return blocked_rdev == NULL;
}
-static bool handle_stripe6(struct stripe_head *sh)
+static void handle_stripe6(struct stripe_head *sh)
{
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks;
@@ -3455,17 +3495,14 @@ static bool handle_stripe6(struct stripe_head *sh)
ops_run_io(sh, &s);
return_io(return_bi);
-
- return blocked_rdev == NULL;
}
-/* returns true if the stripe was handled */
-static bool handle_stripe(struct stripe_head *sh)
+static void handle_stripe(struct stripe_head *sh)
{
if (sh->raid_conf->level == 6)
- return handle_stripe6(sh);
+ handle_stripe6(sh);
else
- return handle_stripe5(sh);
+ handle_stripe5(sh);
}
static void raid5_activate_delayed(raid5_conf_t *conf)
@@ -3503,9 +3540,10 @@ static void unplug_slaves(mddev_t *mddev)
{
raid5_conf_t *conf = mddev->private;
int i;
+ int devs = max(conf->raid_disks, conf->previous_raid_disks);
rcu_read_lock();
- for (i = 0; i < conf->raid_disks; i++) {
+ for (i = 0; i < devs; i++) {
mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
struct request_queue *r_queue = bdev_get_queue(rdev->bdev);
@@ -4011,6 +4049,8 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
sector_nr = conf->reshape_progress;
sector_div(sector_nr, new_data_disks);
if (sector_nr) {
+ mddev->curr_resync_completed = sector_nr;
+ sysfs_notify(&mddev->kobj, NULL, "sync_completed");
*skipped = 1;
return sector_nr;
}
@@ -4277,9 +4317,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
clear_bit(STRIPE_INSYNC, &sh->state);
spin_unlock(&sh->lock);
- /* wait for any blocked device to be handled */
- while (unlikely(!handle_stripe(sh)))
- ;
+ handle_stripe(sh);
release_stripe(sh);
return STRIPE_SECTORS;
@@ -4349,37 +4387,6 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
return handled;
}
-#ifdef CONFIG_MULTICORE_RAID456
-static void __process_stripe(void *param, async_cookie_t cookie)
-{
- struct stripe_head *sh = param;
-
- handle_stripe(sh);
- release_stripe(sh);
-}
-
-static void process_stripe(struct stripe_head *sh, struct list_head *domain)
-{
- async_schedule_domain(__process_stripe, sh, domain);
-}
-
-static void synchronize_stripe_processing(struct list_head *domain)
-{
- async_synchronize_full_domain(domain);
-}
-#else
-static void process_stripe(struct stripe_head *sh, struct list_head *domain)
-{
- handle_stripe(sh);
- release_stripe(sh);
- cond_resched();
-}
-
-static void synchronize_stripe_processing(struct list_head *domain)
-{
-}
-#endif
-
/*
* This is our raid5 kernel thread.
@@ -4393,7 +4400,6 @@ static void raid5d(mddev_t *mddev)
struct stripe_head *sh;
raid5_conf_t *conf = mddev->private;
int handled;
- LIST_HEAD(raid_domain);
pr_debug("+++ raid5d active\n");
@@ -4430,7 +4436,9 @@ static void raid5d(mddev_t *mddev)
spin_unlock_irq(&conf->device_lock);
handled++;
- process_stripe(sh, &raid_domain);
+ handle_stripe(sh);
+ release_stripe(sh);
+ cond_resched();
spin_lock_irq(&conf->device_lock);
}
@@ -4438,7 +4446,6 @@ static void raid5d(mddev_t *mddev)
spin_unlock_irq(&conf->device_lock);
- synchronize_stripe_processing(&raid_domain);
async_tx_issue_pending_all();
unplug_slaves(mddev);
@@ -4558,13 +4565,9 @@ raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks)
if (!sectors)
sectors = mddev->dev_sectors;
- if (!raid_disks) {
+ if (!raid_disks)
/* size is defined by the smallest of previous and new size */
- if (conf->raid_disks < conf->previous_raid_disks)
- raid_disks = conf->raid_disks;
- else
- raid_disks = conf->previous_raid_disks;
- }
+ raid_disks = min(conf->raid_disks, conf->previous_raid_disks);
sectors &= ~((sector_t)mddev->chunk_sectors - 1);
sectors &= ~((sector_t)mddev->new_chunk_sectors - 1);
@@ -4665,7 +4668,7 @@ static int raid5_alloc_percpu(raid5_conf_t *conf)
}
per_cpu_ptr(conf->percpu, cpu)->spare_page = spare_page;
}
- scribble = kmalloc(scribble_len(conf->raid_disks), GFP_KERNEL);
+ scribble = kmalloc(conf->scribble_len, GFP_KERNEL);
if (!scribble) {
err = -ENOMEM;
break;
@@ -4686,7 +4689,7 @@ static int raid5_alloc_percpu(raid5_conf_t *conf)
static raid5_conf_t *setup_conf(mddev_t *mddev)
{
raid5_conf_t *conf;
- int raid_disk, memory;
+ int raid_disk, memory, max_disks;
mdk_rdev_t *rdev;
struct disk_info *disk;
@@ -4722,15 +4725,28 @@ static raid5_conf_t *setup_conf(mddev_t *mddev)
conf = kzalloc(sizeof(raid5_conf_t), GFP_KERNEL);
if (conf == NULL)
goto abort;
+ spin_lock_init(&conf->device_lock);
+ init_waitqueue_head(&conf->wait_for_stripe);
+ init_waitqueue_head(&conf->wait_for_overlap);
+ INIT_LIST_HEAD(&conf->handle_list);
+ INIT_LIST_HEAD(&conf->hold_list);
+ INIT_LIST_HEAD(&conf->delayed_list);
+ INIT_LIST_HEAD(&conf->bitmap_list);
+ INIT_LIST_HEAD(&conf->inactive_list);
+ atomic_set(&conf->active_stripes, 0);
+ atomic_set(&conf->preread_active_stripes, 0);
+ atomic_set(&conf->active_aligned_reads, 0);
+ conf->bypass_threshold = BYPASS_THRESHOLD;
conf->raid_disks = mddev->raid_disks;
- conf->scribble_len = scribble_len(conf->raid_disks);
if (mddev->reshape_position == MaxSector)
conf->previous_raid_disks = mddev->raid_disks;
else
conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks;
+ max_disks = max(conf->raid_disks, conf->previous_raid_disks);
+ conf->scribble_len = scribble_len(max_disks);
- conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info),
+ conf->disks = kzalloc(max_disks * sizeof(struct disk_info),
GFP_KERNEL);
if (!conf->disks)
goto abort;
@@ -4744,24 +4760,11 @@ static raid5_conf_t *setup_conf(mddev_t *mddev)
if (raid5_alloc_percpu(conf) != 0)
goto abort;
- spin_lock_init(&conf->device_lock);
- init_waitqueue_head(&conf->wait_for_stripe);
- init_waitqueue_head(&conf->wait_for_overlap);
- INIT_LIST_HEAD(&conf->handle_list);
- INIT_LIST_HEAD(&conf->hold_list);
- INIT_LIST_HEAD(&conf->delayed_list);
- INIT_LIST_HEAD(&conf->bitmap_list);
- INIT_LIST_HEAD(&conf->inactive_list);
- atomic_set(&conf->active_stripes, 0);
- atomic_set(&conf->preread_active_stripes, 0);
- atomic_set(&conf->active_aligned_reads, 0);
- conf->bypass_threshold = BYPASS_THRESHOLD;
-
pr_debug("raid5: run(%s) called.\n", mdname(mddev));
list_for_each_entry(rdev, &mddev->disks, same_set) {
raid_disk = rdev->raid_disk;
- if (raid_disk >= conf->raid_disks
+ if (raid_disk >= max_disks
|| raid_disk < 0)
continue;
disk = conf->disks + raid_disk;
@@ -4793,7 +4796,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev)
}
memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
- conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
+ max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
if (grow_stripes(conf, conf->max_nr_stripes)) {
printk(KERN_ERR
"raid5: couldn't allocate %dkB for buffers\n", memory);
@@ -4820,11 +4823,40 @@ static raid5_conf_t *setup_conf(mddev_t *mddev)
return ERR_PTR(-ENOMEM);
}
+
+static int only_parity(int raid_disk, int algo, int raid_disks, int max_degraded)
+{
+ switch (algo) {
+ case ALGORITHM_PARITY_0:
+ if (raid_disk < max_degraded)
+ return 1;
+ break;
+ case ALGORITHM_PARITY_N:
+ if (raid_disk >= raid_disks - max_degraded)
+ return 1;
+ break;
+ case ALGORITHM_PARITY_0_6:
+ if (raid_disk == 0 ||
+ raid_disk == raid_disks - 1)
+ return 1;
+ break;
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ if (raid_disk == raid_disks - 1)
+ return 1;
+ }
+ return 0;
+}
+
static int run(mddev_t *mddev)
{
raid5_conf_t *conf;
int working_disks = 0, chunk_size;
+ int dirty_parity_disks = 0;
mdk_rdev_t *rdev;
+ sector_t reshape_offset = 0;
if (mddev->recovery_cp != MaxSector)
printk(KERN_NOTICE "raid5: %s is not clean"
@@ -4858,6 +4890,7 @@ static int run(mddev_t *mddev)
"on a stripe boundary\n");
return -EINVAL;
}
+ reshape_offset = here_new * mddev->new_chunk_sectors;
/* here_new is the stripe we will write to */
here_old = mddev->reshape_position;
sector_div(here_old, mddev->chunk_sectors *
@@ -4913,12 +4946,54 @@ static int run(mddev_t *mddev)
/*
* 0 for a fully functional array, 1 or 2 for a degraded array.
*/
- list_for_each_entry(rdev, &mddev->disks, same_set)
- if (rdev->raid_disk >= 0 &&
- test_bit(In_sync, &rdev->flags))
+ list_for_each_entry(rdev, &mddev->disks, same_set) {
+ if (rdev->raid_disk < 0)
+ continue;
+ if (test_bit(In_sync, &rdev->flags))
working_disks++;
+ /* This disc is not fully in-sync. However if it
+ * just stored parity (beyond the recovery_offset),
+ * when we don't need to be concerned about the
+ * array being dirty.
+ * When reshape goes 'backwards', we never have
+ * partially completed devices, so we only need
+ * to worry about reshape going forwards.
+ */
+ /* Hack because v0.91 doesn't store recovery_offset properly. */
+ if (mddev->major_version == 0 &&
+ mddev->minor_version > 90)
+ rdev->recovery_offset = reshape_offset;
+
+ printk("%d: w=%d pa=%d pr=%d m=%d a=%d r=%d op1=%d op2=%d\n",
+ rdev->raid_disk, working_disks, conf->prev_algo,
+ conf->previous_raid_disks, conf->max_degraded,
+ conf->algorithm, conf->raid_disks,
+ only_parity(rdev->raid_disk,
+ conf->prev_algo,
+ conf->previous_raid_disks,
+ conf->max_degraded),
+ only_parity(rdev->raid_disk,
+ conf->algorithm,
+ conf->raid_disks,
+ conf->max_degraded));
+ if (rdev->recovery_offset < reshape_offset) {
+ /* We need to check old and new layout */
+ if (!only_parity(rdev->raid_disk,
+ conf->algorithm,
+ conf->raid_disks,
+ conf->max_degraded))
+ continue;
+ }
+ if (!only_parity(rdev->raid_disk,
+ conf->prev_algo,
+ conf->previous_raid_disks,
+ conf->max_degraded))
+ continue;
+ dirty_parity_disks++;
+ }
- mddev->degraded = conf->raid_disks - working_disks;
+ mddev->degraded = (max(conf->raid_disks, conf->previous_raid_disks)
+ - working_disks);
if (mddev->degraded > conf->max_degraded) {
printk(KERN_ERR "raid5: not enough operational devices for %s"
@@ -4931,7 +5006,7 @@ static int run(mddev_t *mddev)
mddev->dev_sectors &= ~(mddev->chunk_sectors - 1);
mddev->resync_max_sectors = mddev->dev_sectors;
- if (mddev->degraded > 0 &&
+ if (mddev->degraded > dirty_parity_disks &&
mddev->recovery_cp != MaxSector) {
if (mddev->ok_start_degraded)
printk(KERN_WARNING
@@ -5357,9 +5432,11 @@ static int raid5_start_reshape(mddev_t *mddev)
!test_bit(Faulty, &rdev->flags)) {
if (raid5_add_disk(mddev, rdev) == 0) {
char nm[20];
- set_bit(In_sync, &rdev->flags);
+ if (rdev->raid_disk >= conf->previous_raid_disks)
+ set_bit(In_sync, &rdev->flags);
+ else
+ rdev->recovery_offset = 0;
added_devices++;
- rdev->recovery_offset = 0;
sprintf(nm, "rd%d", rdev->raid_disk);
if (sysfs_create_link(&mddev->kobj,
&rdev->kobj, nm))
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index 2390e0e83daf..dd708359b451 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -214,12 +214,20 @@ struct stripe_head {
int disks; /* disks in stripe */
enum check_states check_state;
enum reconstruct_states reconstruct_state;
- /* stripe_operations
+ /**
+ * struct stripe_operations
* @target - STRIPE_OP_COMPUTE_BLK target
+ * @target2 - 2nd compute target in the raid6 case
+ * @zero_sum_result - P and Q verification flags
+ * @request - async service request flags for raid_run_ops
*/
struct stripe_operations {
int target, target2;
enum sum_check_flags zero_sum_result;
+ #ifdef CONFIG_MULTICORE_RAID456
+ unsigned long request;
+ wait_queue_head_t wait_for_ops;
+ #endif
} ops;
struct r5dev {
struct bio req;
@@ -294,6 +302,8 @@ struct r6_state {
#define STRIPE_FULL_WRITE 13 /* all blocks are set to be overwritten */
#define STRIPE_BIOFILL_RUN 14
#define STRIPE_COMPUTE_RUN 15
+#define STRIPE_OPS_REQ_PENDING 16
+
/*
* Operation request flags
*/
@@ -478,7 +488,7 @@ static inline int algorithm_valid_raid6(int layout)
{
return (layout >= 0 && layout <= 5)
||
- (layout == 8 || layout == 10)
+ (layout >= 8 && layout <= 10)
||
(layout >= 16 && layout <= 20);
}
diff --git a/drivers/md/raid6altivec.uc b/drivers/md/raid6altivec.uc
index 699dfeee4944..2654d5c854be 100644
--- a/drivers/md/raid6altivec.uc
+++ b/drivers/md/raid6altivec.uc
@@ -15,7 +15,7 @@
*
* $#-way unrolled portable integer math RAID-6 instruction set
*
- * This file is postprocessed using unroll.pl
+ * This file is postprocessed using unroll.awk
*
* <benh> hpa: in process,
* you can just "steal" the vec unit with enable_kernel_altivec() (but
diff --git a/drivers/md/raid6int.uc b/drivers/md/raid6int.uc
index f9bf9cba357f..d1e276a14fab 100644
--- a/drivers/md/raid6int.uc
+++ b/drivers/md/raid6int.uc
@@ -15,7 +15,7 @@
*
* $#-way unrolled portable integer math RAID-6 instruction set
*
- * This file is postprocessed using unroll.pl
+ * This file is postprocessed using unroll.awk
*/
#include <linux/raid/pq.h>
diff --git a/drivers/md/raid6test/Makefile b/drivers/md/raid6test/Makefile
index 58ffdf4f5161..2874cbef529d 100644
--- a/drivers/md/raid6test/Makefile
+++ b/drivers/md/raid6test/Makefile
@@ -7,7 +7,7 @@ CC = gcc
OPTFLAGS = -O2 # Adjust as desired
CFLAGS = -I.. -I ../../../include -g $(OPTFLAGS)
LD = ld
-PERL = perl
+AWK = awk
AR = ar
RANLIB = ranlib
@@ -35,35 +35,35 @@ raid6.a: raid6int1.o raid6int2.o raid6int4.o raid6int8.o raid6int16.o \
raid6test: test.c raid6.a
$(CC) $(CFLAGS) -o raid6test $^
-raid6altivec1.c: raid6altivec.uc ../unroll.pl
- $(PERL) ../unroll.pl 1 < raid6altivec.uc > $@
+raid6altivec1.c: raid6altivec.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=1 < raid6altivec.uc > $@
-raid6altivec2.c: raid6altivec.uc ../unroll.pl
- $(PERL) ../unroll.pl 2 < raid6altivec.uc > $@
+raid6altivec2.c: raid6altivec.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=2 < raid6altivec.uc > $@
-raid6altivec4.c: raid6altivec.uc ../unroll.pl
- $(PERL) ../unroll.pl 4 < raid6altivec.uc > $@
+raid6altivec4.c: raid6altivec.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=4 < raid6altivec.uc > $@
-raid6altivec8.c: raid6altivec.uc ../unroll.pl
- $(PERL) ../unroll.pl 8 < raid6altivec.uc > $@
+raid6altivec8.c: raid6altivec.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=8 < raid6altivec.uc > $@
-raid6int1.c: raid6int.uc ../unroll.pl
- $(PERL) ../unroll.pl 1 < raid6int.uc > $@
+raid6int1.c: raid6int.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=1 < raid6int.uc > $@
-raid6int2.c: raid6int.uc ../unroll.pl
- $(PERL) ../unroll.pl 2 < raid6int.uc > $@
+raid6int2.c: raid6int.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=2 < raid6int.uc > $@
-raid6int4.c: raid6int.uc ../unroll.pl
- $(PERL) ../unroll.pl 4 < raid6int.uc > $@
+raid6int4.c: raid6int.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=4 < raid6int.uc > $@
-raid6int8.c: raid6int.uc ../unroll.pl
- $(PERL) ../unroll.pl 8 < raid6int.uc > $@
+raid6int8.c: raid6int.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=8 < raid6int.uc > $@
-raid6int16.c: raid6int.uc ../unroll.pl
- $(PERL) ../unroll.pl 16 < raid6int.uc > $@
+raid6int16.c: raid6int.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=16 < raid6int.uc > $@
-raid6int32.c: raid6int.uc ../unroll.pl
- $(PERL) ../unroll.pl 32 < raid6int.uc > $@
+raid6int32.c: raid6int.uc ../unroll.awk
+ $(AWK) ../unroll.awk -vN=32 < raid6int.uc > $@
raid6tables.c: mktables
./mktables > raid6tables.c
diff --git a/drivers/md/unroll.awk b/drivers/md/unroll.awk
new file mode 100644
index 000000000000..c6aa03631df8
--- /dev/null
+++ b/drivers/md/unroll.awk
@@ -0,0 +1,20 @@
+
+# This filter requires one command line option of form -vN=n
+# where n must be a decimal number.
+#
+# Repeat each input line containing $$ n times, replacing $$ with 0...n-1.
+# Replace each $# with n, and each $* with a single $.
+
+BEGIN {
+ n = N + 0
+}
+{
+ if (/\$\$/) { rep = n } else { rep = 1 }
+ for (i = 0; i < rep; ++i) {
+ tmp = $0
+ gsub(/\$\$/, i, tmp)
+ gsub(/\$\#/, n, tmp)
+ gsub(/\$\*/, "$", tmp)
+ print tmp
+ }
+}
diff --git a/drivers/md/unroll.pl b/drivers/md/unroll.pl
deleted file mode 100644
index 3acc710a20ea..000000000000
--- a/drivers/md/unroll.pl
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/perl
-#
-# Take a piece of C code and for each line which contains the sequence $$
-# repeat n times with $ replaced by 0...n-1; the sequence $# is replaced
-# by the unrolling factor, and $* with a single $
-#
-
-($n) = @ARGV;
-$n += 0;
-
-while ( defined($line = <STDIN>) ) {
- if ( $line =~ /\$\$/ ) {
- $rep = $n;
- } else {
- $rep = 1;
- }
- for ( $i = 0 ; $i < $rep ; $i++ ) {
- $tmp = $line;
- $tmp =~ s/\$\$/$i/g;
- $tmp =~ s/\$\#/$n/g;
- $tmp =~ s/\$\*/\$/g;
- print $tmp;
- }
-}
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index 655474b29e21..abd4791acb0e 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -64,7 +64,7 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
ir->ir_type = ir_type;
- memset(ir->ir_codes, sizeof(ir->ir_codes), 0);
+ memset(ir->ir_codes, 0, sizeof(ir->ir_codes));
/*
* FIXME: This is a temporary workaround to use the new IR tables
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index 64595112000d..3a50ce96fcb9 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -616,13 +616,13 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
case RF2:
map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] -
prog_cal[RF1] + prog_tab[RF1]) /
- ((rf_freq[RF2] - rf_freq[RF1]) / 1000);
+ (s32)((rf_freq[RF2] - rf_freq[RF1]) / 1000);
map[i].rf2 = rf_freq[RF2] / 1000;
break;
case RF3:
map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] -
prog_cal[RF2] + prog_tab[RF2]) /
- ((rf_freq[RF3] - rf_freq[RF2]) / 1000);
+ (s32)((rf_freq[RF3] - rf_freq[RF2]) / 1000);
map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2];
map[i].rf3 = rf_freq[RF3] / 1000;
break;
@@ -1000,12 +1000,12 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe,
struct tda18271_std_map_item *map;
char *mode;
int ret;
- u32 freq = params->frequency * 62500;
+ u32 freq = params->frequency * 125 *
+ ((params->mode == V4L2_TUNER_RADIO) ? 1 : 1000) / 2;
priv->mode = TDA18271_ANALOG;
if (params->mode == V4L2_TUNER_RADIO) {
- freq = freq / 1000;
map = &std_map->fm_radio;
mode = "fm";
} else if (params->std & V4L2_STD_MN) {
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index ddf639ed2fd8..98082416aa52 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -31,6 +31,7 @@
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/poll.h>
+#include <linux/semaphore.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/freezer.h>
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 9744b0692417..0e4b97fba384 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -75,7 +75,7 @@ config DVB_USB_DIB0700
select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
- select DVB_TUNER_DIB0070
+ select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
index 0737c6377892..3df2045b7d2d 100644
--- a/drivers/media/dvb/dvb-usb/ce6230.c
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -105,7 +105,7 @@ static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int i = 0;
struct req_t req;
int ret = 0;
- memset(&req, 0, sizeof(&req));
+ memset(&req, 0, sizeof(req));
if (num > 2)
return -EINVAL;
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index f65591fb7cec..2a53dd096eef 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -663,6 +663,14 @@ static struct zl10353_config cxusb_zl10353_xc3028_config = {
.parallel_ts = 1,
};
+static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
+ .demod_address = 0x0f,
+ .if2 = 45600,
+ .no_tuner = 1,
+ .parallel_ts = 1,
+ .disable_i2c_gate_ctrl = 1,
+};
+
static struct mt352_config cxusb_mt352_xc3028_config = {
.demod_address = 0x0f,
.if2 = 4560,
@@ -894,7 +902,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
if ((adap->fe = dvb_attach(zl10353_attach,
- &cxusb_zl10353_xc3028_config,
+ &cxusb_zl10353_xc3028_config_no_i2c_gate,
&adap->dev->i2c_adap)) == NULL)
return -EIO;
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 0b2812aa30a4..6bd8951ea02b 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1925,7 +1925,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ NULL },
},
{ "Leadtek Winfast DTV Dongle (STK7700P based)",
- { &dib0700_usb_id_table[8] },
+ { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
{ NULL },
},
{ "AVerMedia AVerTV DVB-T Express",
@@ -2064,7 +2064,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 12,
+ .num_device_descs = 11,
.devices = {
{ "DiBcom STK7070P reference design",
{ &dib0700_usb_id_table[15], NULL },
@@ -2098,11 +2098,6 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[30], NULL },
{ NULL },
},
- { "Terratec Cinergy T USB XXS/ T3",
- { &dib0700_usb_id_table[33],
- &dib0700_usb_id_table[52], NULL },
- { NULL },
- },
{ "Elgato EyeTV DTT",
{ &dib0700_usb_id_table[49], NULL },
{ NULL },
@@ -2343,8 +2338,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[59], NULL },
{ NULL },
},
- { "Terratec Cinergy T USB XXS (HD)",
- { &dib0700_usb_id_table[34], &dib0700_usb_id_table[60] },
+ { "Terratec Cinergy T USB XXS (HD)/ T3",
+ { &dib0700_usb_id_table[33],
+ &dib0700_usb_id_table[52],
+ &dib0700_usb_id_table[60], NULL},
{ NULL },
},
},
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index d1b67fe0f011..485d061319ab 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -1050,28 +1050,28 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
c->operand[4] = 0; /* slot */
c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */
c->operand[6] = 0; /* more/last */
- /* c->operand[7] = XXXprogram_info_length + 17; */ /* length */
- c->operand[8] = list_management;
- c->operand[9] = 0x01; /* pmt_cmd=OK_descramble */
+ /* Use three bytes for length field in case length > 127 */
+ c->operand[10] = list_management;
+ c->operand[11] = 0x01; /* pmt_cmd=OK_descramble */
/* TS program map table */
- c->operand[10] = 0x02; /* Table id=2 */
- c->operand[11] = 0x80; /* Section syntax + length */
- /* c->operand[12] = XXXprogram_info_length + 12; */
- c->operand[13] = msg[1]; /* Program number */
- c->operand[14] = msg[2];
- c->operand[15] = 0x01; /* Version number=0 + current/next=1 */
- c->operand[16] = 0x00; /* Section number=0 */
- c->operand[17] = 0x00; /* Last section number=0 */
- c->operand[18] = 0x1f; /* PCR_PID=1FFF */
- c->operand[19] = 0xff;
- c->operand[20] = (program_info_length >> 8); /* Program info length */
- c->operand[21] = (program_info_length & 0xff);
+ c->operand[12] = 0x02; /* Table id=2 */
+ c->operand[13] = 0x80; /* Section syntax + length */
+ /* c->operand[14] = XXXprogram_info_length + 12; */
+ c->operand[15] = msg[1]; /* Program number */
+ c->operand[16] = msg[2];
+ c->operand[17] = 0x01; /* Version number=0 + current/next=1 */
+ c->operand[18] = 0x00; /* Section number=0 */
+ c->operand[19] = 0x00; /* Last section number=0 */
+ c->operand[20] = 0x1f; /* PCR_PID=1FFF */
+ c->operand[21] = 0xff;
+ c->operand[22] = (program_info_length >> 8); /* Program info length */
+ c->operand[23] = (program_info_length & 0xff);
/* CA descriptors at programme level */
read_pos = 6;
- write_pos = 22;
+ write_pos = 24;
if (program_info_length > 0) {
pmt_cmd_id = msg[read_pos++];
if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
@@ -1113,8 +1113,10 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
c->operand[write_pos++] = 0x00;
c->operand[write_pos++] = 0x00;
- c->operand[7] = write_pos - 8;
- c->operand[12] = write_pos - 13;
+ c->operand[7] = 0x82;
+ c->operand[8] = (write_pos - 10) >> 8;
+ c->operand[9] = (write_pos - 10) & 0xff;
+ c->operand[14] = write_pos - 15;
crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1);
c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff;
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c
index 7ba43630a25d..e49cdc88b0c7 100644
--- a/drivers/media/dvb/firewire/firedtv-fe.c
+++ b/drivers/media/dvb/firewire/firedtv-fe.c
@@ -141,18 +141,12 @@ static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
return -EOPNOTSUPP;
}
-#define ACCEPTED 0x9
-
static int fdtv_set_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct firedtv *fdtv = fe->sec_priv;
- /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */
- if (avc_tuner_dsd(fdtv, params) != ACCEPTED)
- return -EINVAL;
- else
- return 0; /* not sure of this... */
+ return avc_tuner_dsd(fdtv, params);
}
static int fdtv_get_frontend(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
index 8a2e1e710adb..eec9e52ffa75 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -51,6 +51,7 @@ struct dib0070_config {
#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
extern u16 dib0070_wbd_offset(struct dvb_frontend *);
+extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
#else
static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
{
@@ -63,7 +64,11 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
+
+static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
#endif
-extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
#endif
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 55ef6eeb0769..0781f94e05d2 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -1375,6 +1375,11 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
if (dib7000p_identify(st) != 0)
goto error;
+ /* FIXME: make sure the dev.parent field is initialized, or else
+ request_firmware() will hit an OOPS (this should be moved somewhere
+ more common) */
+ st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
+
dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
dib7000p_demod_reset(st);
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index 81e623a90f09..1fd8306371e2 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -27,6 +27,7 @@
#include <linux/pci.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/vmalloc.h>
#include "dvbdev.h"
#include "dvb_demux.h"
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
index 8c1aed77ea30..85a222c4eaa0 100644
--- a/drivers/media/dvb/siano/Kconfig
+++ b/drivers/media/dvb/siano/Kconfig
@@ -4,7 +4,7 @@
config SMS_SIANO_MDTV
tristate "Siano SMS1xxx based MDTV receiver"
- depends on DVB_CORE && INPUT
+ depends on DVB_CORE && INPUT && HAS_DMA
---help---
Choose Y or M here if you have MDTV receiver with a Siano chipset.
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index cb8a358b7310..8f88a586b0dd 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -529,6 +529,12 @@ struct usb_device_id smsusb_id_table[] = {
.driver_info = SMS1XXX_BOARD_SIANO_NICE },
{ USB_DEVICE(0x187f, 0x0301),
.driver_info = SMS1XXX_BOARD_SIANO_VENICE },
+ { USB_DEVICE(0x2040, 0xb900),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0xb910),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0xc000),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ } /* Terminating entry */
};
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index c3f579de6e71..c6cf11661868 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -181,12 +181,10 @@ static void gemtek_pci_mute(struct gemtek_pci *card)
static void gemtek_pci_unmute(struct gemtek_pci *card)
{
- mutex_lock(&card->lock);
if (card->mute) {
gemtek_pci_setfrequency(card, card->current_frequency);
card->mute = false;
}
- mutex_unlock(&card->lock);
}
static int gemtek_pci_getsignal(struct gemtek_pci *card)
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 939d1e512974..a6724019c66f 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -1299,7 +1299,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
tvnorm = &bttv_tvnorms[norm];
- if (!memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
+ if (memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
sizeof (tvnorm->cropcap))) {
bttv_crop_reset(&btv->crop[0], norm);
btv->crop[1] = btv->crop[0]; /* current = default */
@@ -3800,11 +3800,34 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
if (!V4L2_FIELD_HAS_BOTH(item->vb.field) &&
(item->vb.queue.next != &btv->capture)) {
item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue);
+ /* Mike Isely <isely@pobox.com> - Only check
+ * and set up the bottom field in the logic
+ * below. Don't ever do the top field. This
+ * of course means that if we set up the
+ * bottom field in the above code that we'll
+ * actually skip a field. But that's OK.
+ * Having processed only a single buffer this
+ * time, then the next time around the first
+ * available buffer should be for a top field.
+ * That will then cause us here to set up a
+ * top then a bottom field in the normal way.
+ * The alternative to this understanding is
+ * that we set up the second available buffer
+ * as a top field, but that's out of order
+ * since this driver always processes the top
+ * field first - the effect will be the two
+ * buffers being returned in the wrong order,
+ * with the second buffer also being delayed
+ * by one field time (owing to the fifo nature
+ * of videobuf). Worse still, we'll be stuck
+ * doing fields out of order now every time
+ * until something else causes a field to be
+ * dropped. By effectively forcing a field to
+ * drop this way then we always get back into
+ * sync within a single frame time. (Out of
+ * order fields can screw up deinterlacing
+ * algorithms.) */
if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) {
- if (NULL == set->top &&
- V4L2_FIELD_TOP == item->vb.field) {
- set->top = item;
- }
if (NULL == set->bottom &&
V4L2_FIELD_BOTTOM == item->vb.field) {
set->bottom = item;
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index c015da813dda..d14cfb200ed0 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -1426,7 +1426,6 @@ static __init int vpif_probe(struct platform_device *pdev)
struct vpif_display_config *config;
int i, j = 0, k, q, m, err = 0;
struct i2c_adapter *i2c_adap;
- struct vpif_config *config;
struct common_obj *common;
struct channel_obj *ch;
struct video_device *vfd;
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 7bd8a70f0a0b..ac947aecb9c3 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -383,6 +383,11 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)
static int snd_em28xx_prepare(struct snd_pcm_substream *substream)
{
+ struct em28xx *dev = snd_pcm_substream_chip(substream);
+
+ dev->adev.hwptr_done_capture = 0;
+ dev->adev.capture_transfer_done = 0;
+
return 0;
}
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index bdb249bd9d5d..c0fd5c6feeac 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1584,8 +1584,8 @@ struct em28xx_board em28xx_boards[] = {
[EM2870_BOARD_REDDO_DVB_C_USB_BOX] = {
.name = "Reddo DVB-C USB TV Box",
.tuner_type = TUNER_ABSENT,
+ .tuner_gpio = reddo_dvb_c_usb_box,
.has_dvb = 1,
- .dvb_gpio = reddo_dvb_c_usb_box,
},
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 59400e858965..a27afeb6f39b 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -35,12 +35,25 @@ static
const
struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
{
+ .ident = "BRUNEINIT",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "BRUNENIT"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "BRUNENIT"),
+ DMI_MATCH(DMI_BOARD_VERSION, "00030D0000000001")
+ }
+ }, {
.ident = "Fujitsu-Siemens Amilo Xa 2528",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
}
}, {
+ .ident = "Fujitsu-Siemens Amilo Xi 2528",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2528")
+ }
+ }, {
.ident = "Fujitsu-Siemens Amilo Xi 2550",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
@@ -57,6 +70,13 @@ static
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
+ DMI_MATCH(DMI_BIOS_DATE, "12/02/2008")
+ }
+ }, {
+ .ident = "MSI GX700",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
}
}, {
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 140c8f320e47..f8328b9efae5 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -483,7 +483,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
data[3] = 0x2c; /* reg 2, H size/8 */
data[4] = 0x48; /* reg 3, V size/4 */
data[6] = 0x06; /* reg 5, H start */
- data[8] = 0x06 + sd->sensor_type; /* reg 7, V start */
+ data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */
break;
}
err_code = mr_write(gspca_dev, 11);
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 2f6e135d94bc..a5c190e93799 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -2919,7 +2919,7 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
/* A false positive here is likely, until OVT gives me
* the definitive SOF/EOF format */
if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
- gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
sd->packet_nr = 0;
}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 65489d6b0d89..bfae63f5584c 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -394,7 +394,8 @@ frame_data:
PDEBUG(D_PACK, "End of frame detected");
/* Complete the last frame (if any) */
- gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET,
+ frame, data, 0);
if (chunk_len)
PDEBUG(D_ERR, "Chunk length is "
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 5f37952c75cf..72802291e812 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -28,6 +28,7 @@
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
+#include <linux/sched.h>
#include <linux/time.h>
#include <linux/version.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index dff2e5e2d8c6..7db82bdf6f31 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -17,6 +17,7 @@
#include <linux/clk.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 6952e9602d5d..51b683c63b70 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -26,6 +26,7 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/sched.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
@@ -1432,7 +1433,9 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
icd->sense = &sense;
cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
- ret = v4l2_subdev_call(sd, video, s_fmt, f);
+ ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f);
+ cam_f.fmt.pix.pixelformat = pix->pixelformat;
+ *pix = cam_f.fmt.pix;
icd->sense = NULL;
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 9e3262c0ba37..2c0bb06cab3b 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -598,11 +598,6 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize)
buf = list_entry(dma_q->active.next,
struct s2255_buffer, vb.queue);
- if (!waitqueue_active(&buf->vb.done)) {
- /* no one active */
- rc = -1;
- goto unlock;
- }
list_del(&buf->vb.queue);
do_gettimeofday(&buf->vb.ts);
dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i);
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 71145bff94fa..09013229d4aa 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -3428,6 +3428,7 @@ struct saa7134_board saa7134_boards[] = {
.tuner_config = 3,
.mpeg = SAA7134_MPEG_DVB,
.ts_type = SAA7134_MPEG_TS_SERIAL,
+ .ts_force_val = 1,
.gpiomask = 0x0800100, /* GPIO 21 is an INPUT */
.inputs = {{
.name = name_tv,
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 3fa652279ac0..03488ba4c99c 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -262,11 +262,13 @@ int saa7134_ts_start(struct saa7134_dev *dev)
switch (saa7134_boards[dev->board].ts_type) {
case SAA7134_MPEG_TS_PARALLEL:
saa_writeb(SAA7134_TS_SERIAL0, 0x40);
- saa_writeb(SAA7134_TS_PARALLEL, 0xec);
+ saa_writeb(SAA7134_TS_PARALLEL, 0xec |
+ (saa7134_boards[dev->board].ts_force_val << 4));
break;
case SAA7134_MPEG_TS_SERIAL:
saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
- saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
+ saa_writeb(SAA7134_TS_PARALLEL, 0x6c |
+ (saa7134_boards[dev->board].ts_force_val << 4));
saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
saa_writeb(SAA7134_TS_SERIAL1, 0x02);
break;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 6ee3e9b7769e..f8697d46ff5f 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -360,6 +360,7 @@ struct saa7134_board {
enum saa7134_mpeg_type mpeg;
enum saa7134_mpeg_ts_type ts_type;
unsigned int vid_port_opts;
+ unsigned int ts_force_val:1;
};
#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
index c45966edc0cf..9c1d3ac43869 100644
--- a/drivers/media/video/saa7164/saa7164-cmd.c
+++ b/drivers/media/video/saa7164/saa7164-cmd.c
@@ -347,7 +347,7 @@ int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command,
/* Prepare some basic command/response structures */
memset(&command_t, 0, sizeof(command_t));
- memset(&response_t, 0, sizeof(&response_t));
+ memset(&response_t, 0, sizeof(response_t));
pcommand_t = &command_t;
presponse_t = &response_t;
command_t.id = id;
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 65ac474c517a..9c8b7c7b89ee 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -31,6 +31,7 @@
#include <linux/platform_device.h>
#include <linux/videodev2.h>
#include <linux/pm_runtime.h>
+#include <linux/sched.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
@@ -1173,8 +1174,8 @@ static int get_scales(struct soc_camera_device *icd,
width_in = scale_up(cam->ceu_rect.width, *scale_h);
height_in = scale_up(cam->ceu_rect.height, *scale_v);
- *scale_h = calc_generic_scale(cam->ceu_rect.width, icd->user_width);
- *scale_v = calc_generic_scale(cam->ceu_rect.height, icd->user_height);
+ *scale_h = calc_generic_scale(width_in, icd->user_width);
+ *scale_v = calc_generic_scale(height_in, icd->user_height);
return 0;
}
@@ -1723,11 +1724,12 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
err = soc_camera_host_register(&pcdev->ici);
if (err)
- goto exit_free_irq;
+ goto exit_free_clk;
return 0;
-exit_free_irq:
+exit_free_clk:
+ pm_runtime_disable(&pdev->dev);
free_irq(pcdev->irq, pcdev);
exit_release_mem:
if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
@@ -1747,6 +1749,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
struct sh_mobile_ceu_dev, ici);
soc_camera_host_unregister(soc_host);
+ pm_runtime_disable(&pdev->dev);
free_irq(pcdev->irq, pcdev);
if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
dma_release_declared_memory(&pdev->dev);
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 59aa7a3694c2..95fdeb23c2c1 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -1097,6 +1097,13 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
return v4l2_subdev_call(sd, video, s_crop, a);
}
+static void soc_camera_device_init(struct device *dev, void *pdata)
+{
+ dev->platform_data = pdata;
+ dev->bus = &soc_camera_bus_type;
+ dev->release = dummy_release;
+}
+
int soc_camera_host_register(struct soc_camera_host *ici)
{
struct soc_camera_host *ix;
@@ -1158,15 +1165,19 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
list_for_each_entry(icd, &devices, list) {
if (icd->iface == ici->nr) {
+ void *pdata = icd->dev.platform_data;
/* The bus->remove will be called */
device_unregister(&icd->dev);
- /* Not before device_unregister(), .remove
- * needs parent to call ici->ops->remove() */
- icd->dev.parent = NULL;
-
- /* If the host module is loaded again, device_register()
- * would complain "already initialised" */
- memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj));
+ /*
+ * Not before device_unregister(), .remove
+ * needs parent to call ici->ops->remove().
+ * If the host module is loaded again, device_register()
+ * would complain "already initialised," since 2.6.32
+ * this is also needed to prevent use-after-free of the
+ * device private data.
+ */
+ memset(&icd->dev, 0, sizeof(icd->dev));
+ soc_camera_device_init(&icd->dev, pdata);
}
}
@@ -1198,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
* man, stay reasonable... */
return -ENOMEM;
- icd->devnum = num;
- icd->dev.bus = &soc_camera_bus_type;
-
- icd->dev.release = dummy_release;
+ icd->devnum = num;
icd->use_count = 0;
icd->host_priv = NULL;
mutex_init(&icd->video_lock);
@@ -1309,12 +1317,13 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
icd->iface = icl->bus_id;
icd->pdev = &pdev->dev;
platform_set_drvdata(pdev, icd);
- icd->dev.platform_data = icl;
ret = soc_camera_device_register(icd);
if (ret < 0)
goto escdevreg;
+ soc_camera_device_init(&icd->dev, icl);
+
icd->user_width = DEFAULT_WIDTH;
icd->user_height = DEFAULT_HEIGHT;
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index c3225a561748..1b89735e62fd 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -348,7 +348,7 @@ static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,
__s32 value, __u8 *data)
{
data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
- data[2] = min(abs(value), 0xff);
+ data[2] = min((int)abs(value), 0xff);
}
static struct uvc_control_mapping uvc_ctrl_mappings[] = {
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index f960e8ea4f17..a6e41d12b221 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -90,7 +90,8 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
ctrl->dwMaxVideoFrameSize =
frame->dwMaxVideoFrameBufferSize;
- if (stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
+ if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) &&
+ stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
stream->intf->num_altsetting > 1) {
u32 interval;
u32 bandwidth;
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 635ffc7b0391..c3065c4bcba9 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -19,6 +19,7 @@
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/dma-mapping.h>
+#include <linux/sched.h>
#include <media/videobuf-dma-contig.h>
struct videobuf_dma_contig_memory {
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index e832e975da60..a1c47ee95c0e 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -795,7 +795,7 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
twl->client = i2c_new_dummy(client->adapter,
twl->address);
if (!twl->client) {
- dev_err(&twl->client->dev,
+ dev_err(&client->dev,
"can't attach client %d\n", i);
status = -ENOMEM;
goto fail;
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 49b7885c2702..7f27576ca046 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -29,7 +29,7 @@
/* Current settings - values are 2*2^(reg_val/4) microamps. These are
* exported since they are used by multiple drivers.
*/
-int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL] = {
+int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
2,
2,
3,
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index d3015dfb9134..ac056ea6b66e 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -507,6 +507,8 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
{
int i, ret;
+ mutex_init(&wm831x->irq_lock);
+
if (!irq) {
dev_warn(wm831x->dev,
"No interrupt specified - functionality limited\n");
@@ -521,7 +523,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
}
wm831x->irq = irq;
- mutex_init(&wm831x->irq_lock);
INIT_WORK(&wm831x->irq_work, wm831x_irq_worker);
/* Mask the individual interrupt sources */
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index db39f4a52f53..2cb2736d65aa 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -158,6 +158,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
struct i2c_msg msg[2];
u8 msgbuf[2];
struct i2c_client *client;
+ unsigned long timeout, read_time;
int status, i;
memset(msg, 0, sizeof(msg));
@@ -183,47 +184,60 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
if (count > io_limit)
count = io_limit;
- /* Smaller eeproms can work given some SMBus extension calls */
if (at24->use_smbus) {
+ /* Smaller eeproms can work given some SMBus extension calls */
if (count > I2C_SMBUS_BLOCK_MAX)
count = I2C_SMBUS_BLOCK_MAX;
- status = i2c_smbus_read_i2c_block_data(client, offset,
- count, buf);
- dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n",
- count, offset, status);
- return (status < 0) ? -EIO : status;
+ } else {
+ /*
+ * When we have a better choice than SMBus calls, use a
+ * combined I2C message. Write address; then read up to
+ * io_limit data bytes. Note that read page rollover helps us
+ * here (unlike writes). msgbuf is u8 and will cast to our
+ * needs.
+ */
+ i = 0;
+ if (at24->chip.flags & AT24_FLAG_ADDR16)
+ msgbuf[i++] = offset >> 8;
+ msgbuf[i++] = offset;
+
+ msg[0].addr = client->addr;
+ msg[0].buf = msgbuf;
+ msg[0].len = i;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].buf = buf;
+ msg[1].len = count;
}
/*
- * When we have a better choice than SMBus calls, use a combined
- * I2C message. Write address; then read up to io_limit data bytes.
- * Note that read page rollover helps us here (unlike writes).
- * msgbuf is u8 and will cast to our needs.
+ * Reads fail if the previous write didn't complete yet. We may
+ * loop a few times until this one succeeds, waiting at least
+ * long enough for one entire page write to work.
*/
- i = 0;
- if (at24->chip.flags & AT24_FLAG_ADDR16)
- msgbuf[i++] = offset >> 8;
- msgbuf[i++] = offset;
-
- msg[0].addr = client->addr;
- msg[0].buf = msgbuf;
- msg[0].len = i;
+ timeout = jiffies + msecs_to_jiffies(write_timeout);
+ do {
+ read_time = jiffies;
+ if (at24->use_smbus) {
+ status = i2c_smbus_read_i2c_block_data(client, offset,
+ count, buf);
+ } else {
+ status = i2c_transfer(client->adapter, msg, 2);
+ if (status == 2)
+ status = count;
+ }
+ dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n",
+ count, offset, status, jiffies);
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].buf = buf;
- msg[1].len = count;
+ if (status == count)
+ return count;
- status = i2c_transfer(client->adapter, msg, 2);
- dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n",
- count, offset, status);
+ /* REVISIT: at HZ=100, this is sloooow */
+ msleep(1);
+ } while (time_before(read_time, timeout));
- if (status == 2)
- return count;
- else if (status >= 0)
- return -EIO;
- else
- return status;
+ return -ETIMEDOUT;
}
static ssize_t at24_read(struct at24_data *at24,
diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c
index ccd4408a26c7..3f2375c5ba5b 100644
--- a/drivers/misc/sgi-gru/gruprocfs.c
+++ b/drivers/misc/sgi-gru/gruprocfs.c
@@ -161,14 +161,15 @@ static int options_show(struct seq_file *s, void *p)
static ssize_t options_write(struct file *file, const char __user *userbuf,
size_t count, loff_t *data)
{
- unsigned long val;
- char buf[80];
+ char buf[20];
- if (strncpy_from_user(buf, userbuf, sizeof(buf) - 1) < 0)
+ if (count >= sizeof(buf))
+ return -EINVAL;
+ if (copy_from_user(buf, userbuf, count))
return -EFAULT;
- buf[count - 1] = '\0';
- if (!strict_strtoul(buf, 10, &val))
- gru_options = val;
+ buf[count] = '\0';
+ if (strict_strtoul(buf, 0, &gru_options))
+ return -EINVAL;
return count;
}
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index c76677afda1b..b5bbe59f9c57 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -106,7 +106,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
#if defined CONFIG_X86_64
- mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset);
+ mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset,
+ UV_AFFINITY_CPU);
if (mq->irq < 0) {
dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
-mq->irq);
@@ -136,7 +137,7 @@ static void
xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq)
{
#if defined CONFIG_X86_64
- uv_teardown_irq(mq->irq, mq->mmr_blade, mq->mmr_offset);
+ uv_teardown_irq(mq->irq);
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
int mmr_pnode;
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index e556d42cc45a..63924e0c7ea9 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -72,7 +72,6 @@
#include <asm/irq.h>
#include <asm/gpio.h>
-#include <asm/mach/mmc.h>
#include <mach/board.h>
#include <mach/cpu.h>
#include <mach/at91_mci.h>
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index e7a331de5733..b8fd7af1ceeb 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1529,6 +1529,7 @@ static int mmc_omap_remove(struct platform_device *pdev)
host->pdata->cleanup(&pdev->dev);
mmc_omap_fclk_enable(host, 0);
+ free_irq(host->irq, host);
clk_put(host->fclk);
clk_disable(host->iclk);
clk_put(host->iclk);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4487cc097911..0aecaaebef3d 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2013,7 +2013,7 @@ static struct platform_driver omap_hsmmc_driver = {
static int __init omap_hsmmc_init(void)
{
/* Register the MMC driver */
- return platform_driver_register(&omap_hsmmc_driver);
+ return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe);
}
static void __exit omap_hsmmc_cleanup(void)
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index b00d67319058..9fb480bb0e0a 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -760,6 +760,8 @@ static int pxamci_remove(struct platform_device *pdev)
if (mmc) {
struct pxamci_host *host = mmc_priv(mmc);
+ mmc_remove_host(mmc);
+
if (host->pdata) {
gpio_cd = host->pdata->gpio_card_detect;
gpio_ro = host->pdata->gpio_card_ro;
@@ -779,8 +781,6 @@ static int pxamci_remove(struct platform_device *pdev)
if (host->pdata && host->pdata->exit)
host->pdata->exit(&pdev->dev, mmc);
- mmc_remove_host(mmc);
-
pxamci_stop_clock(host);
writel(TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 841e085ab74a..14be0755d7cd 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -486,6 +486,7 @@ config MTD_BFIN_ASYNC
config MTD_GPIO_ADDR
tristate "GPIO-assisted Flash Chip Support"
+ depends on GENERIC_GPIO || GPIOLIB
depends on MTD_COMPLEX_MAPPINGS
select MTD_PARTITIONS
help
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 1d5cf8636723..ae2f6dbe43c3 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -58,4 +58,6 @@ obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o
+obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
+obj-$(CONFIG_MTD_VMU) += vmu-flash.o
obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o
diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c
index 44ef9a49a860..1ad5caf9fe69 100644
--- a/drivers/mtd/maps/gpio-addr-flash.c
+++ b/drivers/mtd/maps/gpio-addr-flash.c
@@ -13,7 +13,9 @@
* Licensed under the GPL-2 or later.
*/
+#include <linux/gpio.h>
#include <linux/init.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
@@ -23,9 +25,6 @@
#include <linux/platform_device.h>
#include <linux/types.h>
-#include <asm/gpio.h>
-#include <asm/io.h>
-
#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); })
#define DRIVER_NAME "gpio-addr-flash"
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index d600c2deff73..689d6a79ffc0 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -118,11 +118,9 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
dev->offset, mrq.CardOffset);
mrq.Page = 0;
- ret = pcmcia_map_mem_page(win, &mrq);
- if (ret != 0) {
- cs_error(dev->p_dev, MapMemPage, ret);
+ ret = pcmcia_map_mem_page(dev->p_dev, win, &mrq);
+ if (ret != 0)
return NULL;
- }
dev->offset = mrq.CardOffset;
}
return dev->win_base + (to & (dev->win_size-1));
@@ -327,8 +325,6 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
ret = pcmcia_modify_configuration(link, &mod);
- if (ret != 0)
- cs_error(link, ModifyConfiguration, ret);
}
@@ -348,107 +344,116 @@ static void pcmciamtd_release(struct pcmcia_device *link)
iounmap(dev->win_base);
dev->win_base = NULL;
}
- pcmcia_release_window(link->win);
+ pcmcia_release_window(link, link->win);
}
pcmcia_disable_device(link);
}
-static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
+#ifdef CONFIG_MTD_DEBUG
+static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv_data)
{
- int rc;
- tuple_t tuple;
cisparse_t parse;
- u_char buf[64];
-
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = RETURN_FIRST_TUPLE;
-
- rc = pcmcia_get_first_tuple(link, &tuple);
- while (rc == 0) {
- rc = pcmcia_get_tuple_data(link, &tuple);
- if (rc != 0) {
- cs_error(link, GetTupleData, rc);
- break;
- }
- rc = pcmcia_parse_tuple(&tuple, &parse);
- if (rc != 0) {
- cs_error(link, ParseTuple, rc);
- break;
- }
- switch(tuple.TupleCode) {
- case CISTPL_FORMAT: {
- cistpl_format_t *t = &parse.format;
- (void)t; /* Shut up, gcc */
- DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
- t->type, t->edc, t->offset, t->length);
- break;
+ if (!pcmcia_parse_tuple(tuple, &parse)) {
+ cistpl_format_t *t = &parse.format;
+ (void)t; /* Shut up, gcc */
+ DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
+ t->type, t->edc, t->offset, t->length);
+ }
+ return -ENOSPC;
+}
- }
+static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv_data)
+{
+ cisparse_t parse;
+ int i;
- case CISTPL_DEVICE: {
- cistpl_device_t *t = &parse.device;
- int i;
- DEBUG(2, "Common memory:");
- dev->pcmcia_map.size = t->dev[0].size;
- for(i = 0; i < t->ndev; i++) {
- DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
- DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
- DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
- DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
- }
- break;
- }
+ if (!pcmcia_parse_tuple(tuple, &parse)) {
+ cistpl_jedec_t *t = &parse.jedec;
+ for (i = 0; i < t->nid; i++)
+ DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
+ }
+ return -ENOSPC;
+}
+#endif
- case CISTPL_VERS_1: {
- cistpl_vers_1_t *t = &parse.version_1;
- int i;
- if(t->ns) {
- dev->mtd_name[0] = '\0';
- for(i = 0; i < t->ns; i++) {
- if(i)
- strcat(dev->mtd_name, " ");
- strcat(dev->mtd_name, t->str+t->ofs[i]);
- }
- }
- DEBUG(2, "Found name: %s", dev->mtd_name);
- break;
- }
+static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv_data)
+{
+ struct pcmciamtd_dev *dev = priv_data;
+ cisparse_t parse;
+ cistpl_device_t *t = &parse.device;
+ int i;
- case CISTPL_JEDEC_C: {
- cistpl_jedec_t *t = &parse.jedec;
- int i;
- for(i = 0; i < t->nid; i++) {
- DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
- }
- break;
- }
+ if (pcmcia_parse_tuple(tuple, &parse))
+ return -EINVAL;
+
+ DEBUG(2, "Common memory:");
+ dev->pcmcia_map.size = t->dev[0].size;
+ /* from here on: DEBUG only */
+ for (i = 0; i < t->ndev; i++) {
+ DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
+ DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
+ DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
+ DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
+ }
+ return 0;
+}
- case CISTPL_DEVICE_GEO: {
- cistpl_device_geo_t *t = &parse.device_geo;
- int i;
- dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
- for(i = 0; i < t->ngeo; i++) {
- DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
- DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
- DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
- DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
- DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
- DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
- }
- break;
- }
+static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv_data)
+{
+ struct pcmciamtd_dev *dev = priv_data;
+ cisparse_t parse;
+ cistpl_device_geo_t *t = &parse.device_geo;
+ int i;
- default:
- DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
- }
+ if (pcmcia_parse_tuple(tuple, &parse))
+ return -EINVAL;
+
+ dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
+ /* from here on: DEBUG only */
+ for (i = 0; i < t->ngeo; i++) {
+ DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
+ DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
+ DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
+ DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
+ DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
+ DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
+ }
+ return 0;
+}
+
+
+static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
+{
+ int i;
- rc = pcmcia_get_next_tuple(link, &tuple);
+ if (p_dev->prod_id[0]) {
+ dev->mtd_name[0] = '\0';
+ for (i = 0; i < 4; i++) {
+ if (i)
+ strcat(dev->mtd_name, " ");
+ if (p_dev->prod_id[i])
+ strcat(dev->mtd_name, p_dev->prod_id[i]);
+ }
+ DEBUG(2, "Found name: %s", dev->mtd_name);
}
+
+#ifdef CONFIG_MTD_DEBUG
+ pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL);
+ pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL);
+#endif
+ pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev);
+ pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev);
+
if(!dev->pcmcia_map.size)
dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
@@ -481,16 +486,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link,
* MTD device available to the system.
*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int pcmciamtd_config(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev = link->priv;
struct mtd_info *mtd = NULL;
cs_status_t status;
win_req_t req;
- int last_ret = 0, last_fn = 0;
int ret;
int i;
static char *probes[] = { "jedec_probe", "cfi_probe" };
@@ -529,7 +530,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
int ret;
DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
req.Size >> 10, req.AccessSpeed);
- ret = pcmcia_request_window(&link, &req, &link->win);
+ ret = pcmcia_request_window(link, &req, &link->win);
DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
if(ret) {
req.Size >>= 1;
@@ -577,7 +578,6 @@ static int pcmciamtd_config(struct pcmcia_device *link)
DEBUG(2, "Setting Configuration");
ret = pcmcia_request_configuration(link, &link->conf);
if (ret != 0) {
- cs_error(link, RequestConfiguration, ret);
if (dev->win_base) {
iounmap(dev->win_base);
dev->win_base = NULL;
@@ -652,8 +652,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
link->dev_node = &dev->node;
return 0;
- cs_failed:
- cs_error(link, last_fn, last_ret);
+ failed:
err("CS Error, exiting");
pcmciamtd_release(link);
return -ENODEV;
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index fdb97f3d30e9..d7a47574d21e 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -209,8 +209,8 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
}
subdev->mtd->owner = THIS_MODULE;
- printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, "
- "%d-bit\n", phys, subdev->mtd->size >> 20,
+ printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %uMiB, %d-bit\n",
+ phys, (unsigned)(subdev->mtd->size >> 20),
subdev->map.bankwidth * 8);
return 0;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 22113865438b..2957cc70da3d 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -761,6 +761,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @page: page number to read
*
* Not for syndrome calculating ecc controllers, which use a special oob layout
*/
@@ -777,6 +778,7 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @page: page number to read
*
* We need a special oob layout and handling even when OOB isn't used.
*/
@@ -818,6 +820,7 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *c
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @page: page number to read
*/
static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf, int page)
@@ -939,6 +942,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @page: page number to read
*
* Not for syndrome calculating ecc controllers which need a special oob layout
*/
@@ -983,6 +987,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @page: page number to read
*
* Hardware ECC for large page chips, require OOB to be read first.
* For this ECC mode, the write_page method is re-used from ECC_HW.
@@ -1031,6 +1036,7 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @page: page number to read
*
* The hw generator calculates the error syndrome automatically. Therefor
* we need a special oob layout and handling.
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index e1f7d0a78b9d..14cec04c34f9 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -42,6 +42,7 @@
#include <linux/log2.h>
#include <linux/kthread.h>
#include <linux/reboot.h>
+#include <linux/kernel.h>
#include "ubi.h"
/* Maximum length of the 'mtd=' parameter */
@@ -1257,7 +1258,7 @@ static int __init bytes_str_to_int(const char *str)
unsigned long result;
result = simple_strtoul(str, &endp, 0);
- if (str == endp || result < 0) {
+ if (str == endp || result >= INT_MAX) {
printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
str);
return -EINVAL;
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index e7161adc419d..90af61a2c3e4 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -794,16 +794,15 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
* number.
*/
image_seq = be32_to_cpu(ech->image_seq);
- if (!si->image_seq_set) {
+ if (!ubi->image_seq && image_seq)
ubi->image_seq = image_seq;
- si->image_seq_set = 1;
- } else if (ubi->image_seq && ubi->image_seq != image_seq) {
+ if (ubi->image_seq && image_seq &&
+ ubi->image_seq != image_seq) {
ubi_err("bad image sequence number %d in PEB %d, "
"expected %d", image_seq, pnum, ubi->image_seq);
ubi_dbg_dump_ec_hdr(ech);
return -EINVAL;
}
-
}
/* OK, we've done with the EC header, let's look at the VID header */
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h
index bab31695dace..ff179ad7ca55 100644
--- a/drivers/mtd/ubi/scan.h
+++ b/drivers/mtd/ubi/scan.h
@@ -103,7 +103,6 @@ struct ubi_scan_volume {
* @ec_sum: a temporary variable used when calculating @mean_ec
* @ec_count: a temporary variable used when calculating @mean_ec
* @corr_count: count of corrupted PEBs
- * @image_seq_set: indicates @ubi->image_seq is known
*
* This data structure contains the result of scanning and may be used by other
* UBI sub-systems to build final UBI data structures, further error-recovery
@@ -127,7 +126,6 @@ struct ubi_scan_info {
uint64_t ec_sum;
int ec_count;
int corr_count;
- int image_seq_set;
};
struct ubi_device;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 712776089b46..b2f71f79baaf 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -975,7 +975,7 @@ config ENC28J60_WRITEVERIFY
config ETHOC
tristate "OpenCores 10/100 Mbps Ethernet MAC support"
- depends on NET_ETHERNET && HAS_IOMEM
+ depends on NET_ETHERNET && HAS_IOMEM && HAS_DMA
select MII
select PHYLIB
select CRC32
@@ -1741,6 +1741,7 @@ config KS8851
config KS8851_MLL
tristate "Micrel KS8851 MLL"
depends on HAS_IOMEM
+ select MII
help
This platform driver is for Micrel KS8851 Address/data bus
multiplexed network chip.
@@ -2482,6 +2483,8 @@ config S6GMAC
To compile this driver as a module, choose M here. The module
will be called s6gmac.
+source "drivers/net/stmmac/Kconfig"
+
endif # NETDEV_1000
#
@@ -3230,4 +3233,12 @@ config VIRTIO_NET
This is the virtual network driver for virtio. It can be used with
lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
+config VMXNET3
+ tristate "VMware VMXNET3 ethernet driver"
+ depends on PCI && X86 && INET
+ help
+ This driver supports VMware's vmxnet3 virtual ethernet NIC.
+ To compile this driver as a module, choose M here: the
+ module will be called vmxnet3.
+
endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index d866b8cf65d1..246323d7f161 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -2,6 +2,10 @@
# Makefile for the Linux network (ethercard) device drivers.
#
+obj-$(CONFIG_MII) += mii.o
+obj-$(CONFIG_MDIO) += mdio.o
+obj-$(CONFIG_PHYLIB) += phy/
+
obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
obj-$(CONFIG_E1000) += e1000/
@@ -26,6 +30,7 @@ obj-$(CONFIG_TEHUTI) += tehuti.o
obj-$(CONFIG_ENIC) += enic/
obj-$(CONFIG_JME) += jme.o
obj-$(CONFIG_BE2NET) += benet/
+obj-$(CONFIG_VMXNET3) += vmxnet3/
gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o \
@@ -95,15 +100,12 @@ obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
obj-$(CONFIG_RIONET) += rionet.o
obj-$(CONFIG_SH_ETH) += sh_eth.o
+obj-$(CONFIG_STMMAC_ETH) += stmmac/
#
# end link order section
#
-obj-$(CONFIG_MII) += mii.o
-obj-$(CONFIG_MDIO) += mdio.o
-obj-$(CONFIG_PHYLIB) += phy/
-
obj-$(CONFIG_SUNDANCE) += sundance.o
obj-$(CONFIG_HAMACHI) += hamachi.o
obj-$(CONFIG_NET) += Space.o loopback.o
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 5f0b05c2d71f..d82a9a994753 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -1209,7 +1209,8 @@ static int __devinit ace_init(struct net_device *dev)
memset(ap->info, 0, sizeof(struct ace_info));
memset(ap->skb, 0, sizeof(struct ace_skb));
- if (ace_load_firmware(dev))
+ ecode = ace_load_firmware(dev);
+ if (ecode)
goto init_error;
ap->fw_running = 0;
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 2be49c817995..b25467ac895c 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -628,15 +628,6 @@ static int ep93xx_open(struct net_device *dev)
if (ep93xx_alloc_buffers(ep))
return -ENOMEM;
- if (is_zero_ether_addr(dev->dev_addr)) {
- random_ether_addr(dev->dev_addr);
- printk(KERN_INFO "%s: generated random MAC address "
- "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", dev->name,
- dev->dev_addr[0], dev->dev_addr[1],
- dev->dev_addr[2], dev->dev_addr[3],
- dev->dev_addr[4], dev->dev_addr[5]);
- }
-
napi_enable(&ep->napi);
if (ep93xx_start_hw(dev)) {
@@ -877,6 +868,9 @@ static int ep93xx_eth_probe(struct platform_device *pdev)
ep->mii.mdio_write = ep93xx_mdio_write;
ep->mdc_divisor = 40; /* Max HCLK 100 MHz, min MDIO clk 2.5 MHz. */
+ if (is_zero_ether_addr(dev->dev_addr))
+ random_ether_addr(dev->dev_addr);
+
err = register_netdev(dev);
if (err) {
dev_err(&pdev->dev, "Failed to register netdev\n");
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 04f63c77071d..3f4b4300f533 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -34,6 +34,7 @@
*
*
*/
+#include <linux/capability.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -1087,7 +1088,14 @@ static struct net_device * au1000_probe(int port_num)
return NULL;
}
- if ((err = register_netdev(dev)) != 0) {
+ dev->base_addr = base;
+ dev->irq = irq;
+ dev->netdev_ops = &au1000_netdev_ops;
+ SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
+ dev->watchdog_timeo = ETH_TX_TIMEOUT;
+
+ err = register_netdev(dev);
+ if (err != 0) {
printk(KERN_ERR "%s: Cannot register net device, error %d\n",
DRV_NAME, err);
free_netdev(dev);
@@ -1208,12 +1216,6 @@ static struct net_device * au1000_probe(int port_num)
aup->tx_db_inuse[i] = pDB;
}
- dev->base_addr = base;
- dev->irq = irq;
- dev->netdev_ops = &au1000_netdev_ops;
- SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
- dev->watchdog_timeo = ETH_TX_TIMEOUT;
-
/*
* The boot code uses the ethernet controller, so reset it to start
* fresh. au1000_init() expects that the device is in reset state.
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index e046943ef29d..2a9132343b66 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -912,9 +912,6 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id)
bp->istat = istat;
__b44_disable_ints(bp);
__napi_schedule(&bp->napi);
- } else {
- printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
- dev->name);
}
irq_ack:
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index a80da0e14a52..3b79a225628a 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -259,6 +259,8 @@ struct be_adapter {
u32 port_num;
bool promiscuous;
u32 cap;
+ u32 rx_fc; /* Rx flow control */
+ u32 tx_fc; /* Tx flow control */
};
extern const struct ethtool_ops be_ethtool_ops;
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 89876ade5e33..28a0eda92680 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -243,15 +243,26 @@ static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
int be_cmd_POST(struct be_adapter *adapter)
{
- u16 stage, error;
+ u16 stage;
+ int status, timeout = 0;
- error = be_POST_stage_get(adapter, &stage);
- if (error || stage != POST_STAGE_ARMFW_RDY) {
- dev_err(&adapter->pdev->dev, "POST failed.\n");
- return -1;
- }
+ do {
+ status = be_POST_stage_get(adapter, &stage);
+ if (status) {
+ dev_err(&adapter->pdev->dev, "POST error; stage=0x%x\n",
+ stage);
+ return -1;
+ } else if (stage != POST_STAGE_ARMFW_RDY) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(2 * HZ);
+ timeout += 2;
+ } else {
+ return 0;
+ }
+ } while (timeout < 20);
- return 0;
+ dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage);
+ return -1;
}
static inline void *embedded_payload(struct be_mcc_wrb *wrb)
@@ -729,8 +740,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
/* Create an rx filtering policy configuration on an i/f
* Uses mbox
*/
-int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
- bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
+int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
+ u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_if_create *req;
@@ -746,8 +757,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req));
- req->capability_flags = cpu_to_le32(flags);
- req->enable_flags = cpu_to_le32(flags);
+ req->capability_flags = cpu_to_le32(cap_flags);
+ req->enable_flags = cpu_to_le32(en_flags);
req->pmac_invalid = pmac_invalid;
if (!pmac_invalid)
memcpy(req->mac_addr, mac, ETH_ALEN);
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index a86f917f85f4..e5f9676cf1bc 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -68,7 +68,7 @@ enum {
#define CQE_STATUS_COMPL_MASK 0xFFFF
#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */
#define CQE_STATUS_EXTD_MASK 0xFFFF
-#define CQE_STATUS_EXTD_SHIFT 0 /* bits 0 - 15 */
+#define CQE_STATUS_EXTD_SHIFT 16 /* bits 16 - 31 */
struct be_mcc_compl {
u32 status; /* dword 0 */
@@ -720,8 +720,9 @@ extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
u32 if_id, u32 *pmac_id);
extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id);
-extern int be_cmd_if_create(struct be_adapter *adapter, u32 if_flags, u8 *mac,
- bool pmac_invalid, u32 *if_handle, u32 *pmac_id);
+extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags,
+ u32 en_flags, u8 *mac, bool pmac_invalid,
+ u32 *if_handle, u32 *pmac_id);
extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle);
extern int be_cmd_eq_create(struct be_adapter *adapter,
struct be_queue_info *eq, int eq_delay);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index cda5bf2fc50a..f0fd95b43c07 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -323,10 +323,12 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
if (ecmd->autoneg != 0)
return -EINVAL;
+ adapter->tx_fc = ecmd->tx_pause;
+ adapter->rx_fc = ecmd->rx_pause;
- status = be_cmd_set_flow_control(adapter, ecmd->tx_pause,
- ecmd->rx_pause);
- if (!status)
+ status = be_cmd_set_flow_control(adapter,
+ adapter->tx_fc, adapter->rx_fc);
+ if (status)
dev_warn(&adapter->pdev->dev, "Pause param set failed.\n");
return status;
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 6d5e81f7046f..876b357101fa 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1610,29 +1610,42 @@ static int be_open(struct net_device *netdev)
status = be_cmd_link_status_query(adapter, &link_up);
if (status)
- return status;
+ goto ret_sts;
be_link_status_update(adapter, link_up);
+ status = be_vid_config(adapter);
+ if (status)
+ goto ret_sts;
+
+ status = be_cmd_set_flow_control(adapter,
+ adapter->tx_fc, adapter->rx_fc);
+ if (status)
+ goto ret_sts;
+
schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
- return 0;
+ret_sts:
+ return status;
}
static int be_setup(struct be_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- u32 if_flags;
+ u32 cap_flags, en_flags;
int status;
- if_flags = BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_PROMISCUOUS |
- BE_IF_FLAGS_MCAST_PROMISCUOUS | BE_IF_FLAGS_UNTAGGED |
- BE_IF_FLAGS_PASS_L3L4_ERRORS;
- status = be_cmd_if_create(adapter, if_flags, netdev->dev_addr,
- false/* pmac_invalid */, &adapter->if_handle,
- &adapter->pmac_id);
+ cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+ BE_IF_FLAGS_MCAST_PROMISCUOUS |
+ BE_IF_FLAGS_PROMISCUOUS |
+ BE_IF_FLAGS_PASS_L3L4_ERRORS;
+ en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+ BE_IF_FLAGS_PASS_L3L4_ERRORS;
+
+ status = be_cmd_if_create(adapter, cap_flags, en_flags,
+ netdev->dev_addr, false/* pmac_invalid */,
+ &adapter->if_handle, &adapter->pmac_id);
if (status != 0)
goto do_none;
-
status = be_tx_queues_create(adapter);
if (status != 0)
goto if_destroy;
@@ -1645,17 +1658,8 @@ static int be_setup(struct be_adapter *adapter)
if (status != 0)
goto rx_qs_destroy;
- status = be_vid_config(adapter);
- if (status != 0)
- goto mccqs_destroy;
-
- status = be_cmd_set_flow_control(adapter, true, true);
- if (status != 0)
- goto mccqs_destroy;
return 0;
-mccqs_destroy:
- be_mcc_queues_destroy(adapter);
rx_qs_destroy:
be_rx_queues_destroy(adapter);
tx_qs_destroy:
@@ -1906,6 +1910,10 @@ static void be_netdev_init(struct net_device *netdev)
adapter->rx_csum = true;
+ /* Default settings for Rx and Tx flow control */
+ adapter->rx_fc = true;
+ adapter->tx_fc = true;
+
netif_set_gso_max_size(netdev, 65535);
BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
@@ -2055,6 +2063,10 @@ static int be_hw_up(struct be_adapter *adapter)
if (status)
return status;
+ status = be_cmd_reset_function(adapter);
+ if (status)
+ return status;
+
status = be_cmd_get_fw_ver(adapter, adapter->fw_ver);
if (status)
return status;
@@ -2108,10 +2120,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
if (status)
goto free_netdev;
- status = be_cmd_reset_function(adapter);
- if (status)
- goto ctrl_clean;
-
status = be_stats_init(adapter);
if (status)
goto ctrl_clean;
@@ -2168,6 +2176,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
be_close(netdev);
rtnl_unlock();
}
+ be_cmd_get_flow_control(adapter, &adapter->tx_fc, &adapter->rx_fc);
be_clear(adapter);
pci_save_state(pdev);
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 6c7f795d12de..a4d83409f205 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -361,9 +361,12 @@ struct l2_fhdr {
#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE (1<<28)
#define BNX2_L2CTX_HOST_BDIDX 0x00000004
-#define BNX2_L2CTX_STATUSB_NUM_SHIFT 16
-#define BNX2_L2CTX_STATUSB_NUM(sb_id) \
- (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_STATUSB_NUM_SHIFT) : 0)
+#define BNX2_L2CTX_L5_STATUSB_NUM_SHIFT 16
+#define BNX2_L2CTX_L2_STATUSB_NUM_SHIFT 24
+#define BNX2_L2CTX_L5_STATUSB_NUM(sb_id) \
+ (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L5_STATUSB_NUM_SHIFT) : 0)
+#define BNX2_L2CTX_L2_STATUSB_NUM(sb_id) \
+ (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L2_STATUSB_NUM_SHIFT) : 0)
#define BNX2_L2CTX_HOST_BSEQ 0x00000008
#define BNX2_L2CTX_NX_BSEQ 0x0000000c
#define BNX2_L2CTX_NX_BDHADDR_HI 0x00000010
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 69c5b15e22da..40fb5eefc72e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -691,7 +691,7 @@ static int bond_check_dev_link(struct bonding *bond,
struct net_device *slave_dev, int reporting)
{
const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
- static int (*ioctl)(struct net_device *, struct ifreq *, int);
+ int (*ioctl)(struct net_device *, struct ifreq *, int);
struct ifreq ifr;
struct mii_ioctl_data *mii;
@@ -3665,10 +3665,10 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb,
if (skb->protocol == htons(ETH_P_IP)) {
return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
- (data->h_dest[5] ^ bond_dev->dev_addr[5])) % count;
+ (data->h_dest[5] ^ data->h_source[5])) % count;
}
- return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+ return (data->h_dest[5] ^ data->h_source[5]) % count;
}
/*
@@ -3695,7 +3695,7 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb,
}
- return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+ return (data->h_dest[5] ^ data->h_source[5]) % count;
}
/*
@@ -3706,7 +3706,7 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb,
{
struct ethhdr *data = (struct ethhdr *)skb->data;
- return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+ return (data->h_dest[5] ^ data->h_source[5]) % count;
}
/*-------------------------- Device entry points ----------------------------*/
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index df32c109b7ac..772f6d2489ce 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -35,66 +35,16 @@ config CAN_CALC_BITTIMING
arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw".
If unsure, say Y.
-config CAN_SJA1000
- depends on CAN_DEV && HAS_IOMEM
- tristate "Philips SJA1000"
- ---help---
- Driver for the SJA1000 CAN controllers from Philips or NXP
-
-config CAN_SJA1000_ISA
- depends on CAN_SJA1000 && ISA
- tristate "ISA Bus based legacy SJA1000 driver"
- ---help---
- This driver adds legacy support for SJA1000 chips connected to
- the ISA bus using I/O port, memory mapped or indirect access.
-
-config CAN_SJA1000_PLATFORM
- depends on CAN_SJA1000
- tristate "Generic Platform Bus based SJA1000 driver"
- ---help---
- This driver adds support for the SJA1000 chips connected to
- the "platform bus" (Linux abstraction for directly to the
- processor attached devices). Which can be found on various
- boards from Phytec (http://www.phytec.de) like the PCM027,
- PCM038.
-
-config CAN_SJA1000_OF_PLATFORM
- depends on CAN_SJA1000 && PPC_OF
- tristate "Generic OF Platform Bus based SJA1000 driver"
- ---help---
- This driver adds support for the SJA1000 chips connected to
- the OpenFirmware "platform bus" found on embedded systems with
- OpenFirmware bindings, e.g. if you have a PowerPC based system
- you may want to enable this option.
-
-config CAN_EMS_PCI
- tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card"
- depends on PCI && CAN_SJA1000
- ---help---
- This driver is for the one, two or four channel CPC-PCI,
- CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
- (http://www.ems-wuensche.de).
-
-config CAN_EMS_USB
- tristate "EMS CPC-USB/ARM7 CAN/USB interface"
- depends on USB && CAN_DEV
- ---help---
- This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
- from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
-
-config CAN_KVASER_PCI
- tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
- depends on PCI && CAN_SJA1000
- ---help---
- This driver is for the the PCIcanx and PCIcan cards (1, 2 or
- 4 channel) from Kvaser (http://www.kvaser.com).
-
config CAN_AT91
tristate "Atmel AT91 onchip CAN controller"
- depends on CAN && CAN_DEV && ARCH_AT91SAM9263
+ depends on CAN_DEV && ARCH_AT91SAM9263
---help---
This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
+source "drivers/net/can/sja1000/Kconfig"
+
+source "drivers/net/can/usb/Kconfig"
+
config CAN_DEBUG_DEVICES
bool "CAN devices debugging messages"
depends on CAN
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index f0b9a1e1db46..2868fe842a41 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -589,6 +589,22 @@ static int can_changelink(struct net_device *dev,
return 0;
}
+static size_t can_get_size(const struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ size_t size;
+
+ size = nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */
+ size += sizeof(struct can_ctrlmode); /* IFLA_CAN_CTRLMODE */
+ size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */
+ size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */
+ size += sizeof(struct can_clock); /* IFLA_CAN_CLOCK */
+ if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */
+ size += sizeof(struct can_bittiming_const);
+
+ return size;
+}
+
static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
struct can_priv *priv = netdev_priv(dev);
@@ -613,6 +629,11 @@ nla_put_failure:
return -EMSGSIZE;
}
+static size_t can_get_xstats_size(const struct net_device *dev)
+{
+ return sizeof(struct can_device_stats);
+}
+
static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
{
struct can_priv *priv = netdev_priv(dev);
@@ -639,7 +660,9 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
.setup = can_setup,
.newlink = can_newlink,
.changelink = can_changelink,
+ .get_size = can_get_size,
.fill_info = can_fill_info,
+ .get_xstats_size = can_get_xstats_size,
.fill_xstats = can_fill_xstats,
};
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
new file mode 100644
index 000000000000..4c674927f247
--- /dev/null
+++ b/drivers/net/can/sja1000/Kconfig
@@ -0,0 +1,47 @@
+menuconfig CAN_SJA1000
+ tristate "Philips/NXP SJA1000 devices"
+ depends on CAN_DEV && HAS_IOMEM
+
+if CAN_SJA1000
+
+config CAN_SJA1000_ISA
+ tristate "ISA Bus based legacy SJA1000 driver"
+ depends on ISA
+ ---help---
+ This driver adds legacy support for SJA1000 chips connected to
+ the ISA bus using I/O port, memory mapped or indirect access.
+
+config CAN_SJA1000_PLATFORM
+ tristate "Generic Platform Bus based SJA1000 driver"
+ ---help---
+ This driver adds support for the SJA1000 chips connected to
+ the "platform bus" (Linux abstraction for directly to the
+ processor attached devices). Which can be found on various
+ boards from Phytec (http://www.phytec.de) like the PCM027,
+ PCM038.
+
+config CAN_SJA1000_OF_PLATFORM
+ tristate "Generic OF Platform Bus based SJA1000 driver"
+ depends on PPC_OF
+ ---help---
+ This driver adds support for the SJA1000 chips connected to
+ the OpenFirmware "platform bus" found on embedded systems with
+ OpenFirmware bindings, e.g. if you have a PowerPC based system
+ you may want to enable this option.
+
+config CAN_EMS_PCI
+ tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card"
+ depends on PCI
+ ---help---
+ This driver is for the one, two or four channel CPC-PCI,
+ CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
+ (http://www.ems-wuensche.de).
+
+config CAN_KVASER_PCI
+ tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
+ depends on PCI
+ ---help---
+ This driver is for the the PCIcanx and PCIcan cards (1, 2 or
+ 4 channel) from Kvaser (http://www.kvaser.com).
+
+endif
diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c
index 3373560405ba..9dd076a626a5 100644
--- a/drivers/net/can/sja1000/sja1000_of_platform.c
+++ b/drivers/net/can/sja1000/sja1000_of_platform.c
@@ -213,6 +213,7 @@ static struct of_device_id __devinitdata sja1000_ofp_table[] = {
{.compatible = "nxp,sja1000"},
{},
};
+MODULE_DEVICE_TABLE(of, sja1000_ofp_table);
static struct of_platform_driver sja1000_ofp_driver = {
.owner = THIS_MODULE,
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig
new file mode 100644
index 000000000000..bbc78e0b8a15
--- /dev/null
+++ b/drivers/net/can/usb/Kconfig
@@ -0,0 +1,10 @@
+menu "CAN USB interfaces"
+ depends on USB && CAN_DEV
+
+config CAN_EMS_USB
+ tristate "EMS CPC-USB/ARM7 CAN/USB interface"
+ ---help---
+ This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
+ from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
+
+endmenu
diff --git a/drivers/net/can/usb/Makefile b/drivers/net/can/usb/Makefile
index c3f75ba701b1..0afd51d4c7a5 100644
--- a/drivers/net/can/usb/Makefile
+++ b/drivers/net/can/usb/Makefile
@@ -3,3 +3,5 @@
#
obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 9012e0abc626..abdbd9c2b788 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -319,7 +319,7 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
- cf->can_id = msg->msg.can_msg.id;
+ cf->can_id = le32_to_cpu(msg->msg.can_msg.id);
cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8);
if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME
@@ -813,6 +813,9 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc;
}
+ /* Respect byte order */
+ msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id);
+
for (i = 0; i < MAX_TX_URBS; i++) {
if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) {
context = &dev->tx_contexts[i];
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 05916aafa4f1..f857afe8e488 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -4342,11 +4342,11 @@ static int cas_open(struct net_device *dev)
cas_unlock_all_restore(cp, flags);
}
+ err = -ENOMEM;
if (cas_tx_tiny_alloc(cp) < 0)
- return -ENOMEM;
+ goto err_unlock;
/* alloc rx descriptors */
- err = -ENOMEM;
if (cas_alloc_rxds(cp) < 0)
goto err_tx_tiny;
@@ -4386,6 +4386,7 @@ err_spare:
cas_free_rxds(cp);
err_tx_tiny:
cas_tx_tiny_free(cp);
+err_unlock:
mutex_unlock(&cp->pm_mutex);
return err;
}
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 46c87ec7960c..3bf1b04f2cab 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2264,9 +2264,9 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev)
cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_CTX_TYPE, val);
if (sb_id == 0)
- val = 2 << BNX2_L2CTX_STATUSB_NUM_SHIFT;
+ val = 2 << BNX2_L2CTX_L2_STATUSB_NUM_SHIFT;
else
- val = BNX2_L2CTX_STATUSB_NUM(sb_id);
+ val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id);
cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val);
rxbd = (struct rx_bd *) (cp->l2_ring + BCM_PAGE_SIZE);
@@ -2423,7 +2423,7 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
cp->int_num = 0;
if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) {
u32 sb_id = cp->status_blk_num;
- u32 sb = BNX2_L2CTX_STATUSB_NUM(sb_id);
+ u32 sb = BNX2_L2CTX_L5_STATUSB_NUM(sb_id);
cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT;
cnic_ctx_wr(dev, cp->kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb);
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index f86612857a73..6366061712f4 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -879,7 +879,7 @@ recycle:
pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
PCI_DMA_FROMDEVICE);
(*sd->pg_chunk.p_cnt)--;
- if (!*sd->pg_chunk.p_cnt)
+ if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
pci_unmap_page(adap->pdev,
sd->pg_chunk.mapping,
fl->alloc_size,
@@ -2088,7 +2088,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
PCI_DMA_FROMDEVICE);
(*sd->pg_chunk.p_cnt)--;
- if (!*sd->pg_chunk.p_cnt)
+ if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
pci_unmap_page(adap->pdev,
sd->pg_chunk.mapping,
fl->alloc_size,
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 65a2d0ba64e2..e3478314c002 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -164,16 +164,14 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
# define EMAC_MBP_MCASTCHAN(ch) ((ch) & 0x7)
/* EMAC mac_control register */
-#define EMAC_MACCONTROL_TXPTYPE (0x200)
-#define EMAC_MACCONTROL_TXPACEEN (0x40)
-#define EMAC_MACCONTROL_MIIEN (0x20)
-#define EMAC_MACCONTROL_GIGABITEN (0x80)
-#define EMAC_MACCONTROL_GIGABITEN_SHIFT (7)
-#define EMAC_MACCONTROL_FULLDUPLEXEN (0x1)
+#define EMAC_MACCONTROL_TXPTYPE BIT(9)
+#define EMAC_MACCONTROL_TXPACEEN BIT(6)
+#define EMAC_MACCONTROL_GMIIEN BIT(5)
+#define EMAC_MACCONTROL_GIGABITEN BIT(7)
+#define EMAC_MACCONTROL_FULLDUPLEXEN BIT(0)
#define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15)
/* GIGABIT MODE related bits */
-#define EMAC_DM646X_MACCONTORL_GMIIEN BIT(5)
#define EMAC_DM646X_MACCONTORL_GIG BIT(7)
#define EMAC_DM646X_MACCONTORL_GIGFORCE BIT(17)
@@ -192,10 +190,10 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_RX_BUFFER_OFFSET_MASK (0xFFFF)
/* MAC_IN_VECTOR (0x180) register bit fields */
-#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT (0x20000)
-#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT (0x10000)
-#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC (0x0100)
-#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC (0x01)
+#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT BIT(17)
+#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT BIT(16)
+#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC BIT(8)
+#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC BIT(0)
/** NOTE:: For DM646x the IN_VECTOR has changed */
#define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC BIT(EMAC_DEF_RX_CH)
@@ -203,7 +201,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_DM646X_MAC_IN_VECTOR_HOST_INT BIT(26)
#define EMAC_DM646X_MAC_IN_VECTOR_STATPEND_INT BIT(27)
-
/* CPPI bit positions */
#define EMAC_CPPI_SOP_BIT BIT(31)
#define EMAC_CPPI_EOP_BIT BIT(30)
@@ -333,6 +330,9 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_DM646X_MAC_EOI_C0_RXEN (0x01)
#define EMAC_DM646X_MAC_EOI_C0_TXEN (0x02)
+/* EMAC Stats Clear Mask */
+#define EMAC_STATS_CLR_MASK (0xFFFFFFFF)
+
/** net_buf_obj: EMAC network bufferdata structure
*
* EMAC network buffer data structure
@@ -747,8 +747,7 @@ static void emac_update_phystatus(struct emac_priv *priv)
if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) {
mac_control = emac_read(EMAC_MACCONTROL);
- mac_control |= (EMAC_DM646X_MACCONTORL_GMIIEN |
- EMAC_DM646X_MACCONTORL_GIG |
+ mac_control |= (EMAC_DM646X_MACCONTORL_GIG |
EMAC_DM646X_MACCONTORL_GIGFORCE);
} else {
/* Clear the GIG bit and GIGFORCE bit */
@@ -2105,7 +2104,7 @@ static int emac_hw_enable(struct emac_priv *priv)
/* Enable MII */
val = emac_read(EMAC_MACCONTROL);
- val |= (EMAC_MACCONTROL_MIIEN);
+ val |= (EMAC_MACCONTROL_GMIIEN);
emac_write(EMAC_MACCONTROL, val);
/* Enable NAPI and interrupts */
@@ -2137,9 +2136,6 @@ static int emac_poll(struct napi_struct *napi, int budget)
u32 status = 0;
u32 num_pkts = 0;
- if (!netif_running(ndev))
- return 0;
-
/* Check interrupt vectors and call packet processing */
status = emac_read(EMAC_MACINVECTOR);
@@ -2218,7 +2214,7 @@ void emac_poll_controller(struct net_device *ndev)
struct emac_priv *priv = netdev_priv(ndev);
emac_int_disable(priv);
- emac_irq(ndev->irq, priv);
+ emac_irq(ndev->irq, ndev);
emac_int_enable(priv);
}
#endif
@@ -2548,40 +2544,49 @@ static int emac_dev_stop(struct net_device *ndev)
static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
{
struct emac_priv *priv = netdev_priv(ndev);
+ u32 mac_control;
+ u32 stats_clear_mask;
/* update emac hardware stats and reset the registers*/
+ mac_control = emac_read(EMAC_MACCONTROL);
+
+ if (mac_control & EMAC_MACCONTROL_GMIIEN)
+ stats_clear_mask = EMAC_STATS_CLR_MASK;
+ else
+ stats_clear_mask = 0;
+
priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
- emac_write(EMAC_RXMCASTFRAMES, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXMCASTFRAMES, stats_clear_mask);
priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
emac_read(EMAC_TXSINGLECOLL) +
emac_read(EMAC_TXMULTICOLL));
- emac_write(EMAC_TXCOLLISION, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_TXSINGLECOLL, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_TXMULTICOLL, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_TXCOLLISION, stats_clear_mask);
+ emac_write(EMAC_TXSINGLECOLL, stats_clear_mask);
+ emac_write(EMAC_TXMULTICOLL, stats_clear_mask);
priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
emac_read(EMAC_RXJABBER) +
emac_read(EMAC_RXUNDERSIZED));
- emac_write(EMAC_RXOVERSIZED, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_RXJABBER, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_RXUNDERSIZED, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXOVERSIZED, stats_clear_mask);
+ emac_write(EMAC_RXJABBER, stats_clear_mask);
+ emac_write(EMAC_RXUNDERSIZED, stats_clear_mask);
priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
emac_read(EMAC_RXMOFOVERRUNS));
- emac_write(EMAC_RXSOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_RXMOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXSOFOVERRUNS, stats_clear_mask);
+ emac_write(EMAC_RXMOFOVERRUNS, stats_clear_mask);
priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
- emac_write(EMAC_RXDMAOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXDMAOVERRUNS, stats_clear_mask);
priv->net_dev_stats.tx_carrier_errors +=
emac_read(EMAC_TXCARRIERSENSE);
- emac_write(EMAC_TXCARRIERSENSE, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_TXCARRIERSENSE, stats_clear_mask);
priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
- emac_write(EMAC_TXUNDERRUN, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
return &priv->net_dev_stats;
}
diff --git a/drivers/net/dm9000.h b/drivers/net/dm9000.h
index 80817c2edfb3..fb1c924d79b4 100644
--- a/drivers/net/dm9000.h
+++ b/drivers/net/dm9000.h
@@ -50,7 +50,7 @@
#define DM9000_RCSR 0x32
#define CHIPR_DM9000A 0x19
-#define CHIPR_DM9000B 0x1B
+#define CHIPR_DM9000B 0x1A
#define DM9000_MRCMDX 0xF0
#define DM9000_MRCMD 0xF2
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 5d2f48f02251..d269a68ce354 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -157,6 +157,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/mii.h>
@@ -602,6 +603,7 @@ struct nic {
struct mem *mem;
dma_addr_t dma_addr;
+ struct pci_pool *cbs_pool;
dma_addr_t cbs_dma_addr;
u8 adaptive_ifs;
u8 tx_threshold;
@@ -1427,19 +1429,31 @@ static int e100_phy_init(struct nic *nic)
} else
DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
- /* Isolate all the PHY ids */
- for (addr = 0; addr < 32; addr++)
- mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
- /* Select the discovered PHY */
- bmcr &= ~BMCR_ISOLATE;
- mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
-
/* Get phy ID */
id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2);
nic->phy = (u32)id_hi << 16 | (u32)id_lo;
DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy);
+ /* Select the phy and isolate the rest */
+ for (addr = 0; addr < 32; addr++) {
+ if (addr != nic->mii.phy_id) {
+ mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
+ } else if (nic->phy != phy_82552_v) {
+ bmcr = mdio_read(netdev, addr, MII_BMCR);
+ mdio_write(netdev, addr, MII_BMCR,
+ bmcr & ~BMCR_ISOLATE);
+ }
+ }
+ /*
+ * Workaround for 82552:
+ * Clear the ISOLATE bit on selected phy_id last (mirrored on all
+ * other phy_id's) using bmcr value from addr discovery loop above.
+ */
+ if (nic->phy == phy_82552_v)
+ mdio_write(netdev, nic->mii.phy_id, MII_BMCR,
+ bmcr & ~BMCR_ISOLATE);
+
/* Handle National tx phys */
#define NCS_PHY_MODEL_MASK 0xFFF0FFFF
if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) {
@@ -1781,9 +1795,7 @@ static void e100_clean_cbs(struct nic *nic)
nic->cb_to_clean = nic->cb_to_clean->next;
nic->cbs_avail++;
}
- pci_free_consistent(nic->pdev,
- sizeof(struct cb) * nic->params.cbs.count,
- nic->cbs, nic->cbs_dma_addr);
+ pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr);
nic->cbs = NULL;
nic->cbs_avail = 0;
}
@@ -1801,8 +1813,8 @@ static int e100_alloc_cbs(struct nic *nic)
nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;
nic->cbs_avail = 0;
- nic->cbs = pci_alloc_consistent(nic->pdev,
- sizeof(struct cb) * count, &nic->cbs_dma_addr);
+ nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL,
+ &nic->cbs_dma_addr);
if (!nic->cbs)
return -ENOMEM;
@@ -2829,7 +2841,11 @@ static int __devinit e100_probe(struct pci_dev *pdev,
DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
goto err_out_free;
}
-
+ nic->cbs_pool = pci_pool_create(netdev->name,
+ nic->pdev,
+ nic->params.cbs.count * sizeof(struct cb),
+ sizeof(u32),
+ 0);
DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
(unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0),
pdev->irq, netdev->dev_addr);
@@ -2859,6 +2875,7 @@ static void __devexit e100_remove(struct pci_dev *pdev)
unregister_netdev(netdev);
e100_free(nic);
pci_iounmap(pdev, nic->csr);
+ pci_pool_destroy(nic->cbs_pool);
free_netdev(netdev);
pci_release_regions(pdev);
pci_disable_device(pdev);
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index c0f185beb8bc..1190167a8b3d 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -76,6 +76,7 @@
/* Extended Device Control */
#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_SPD_BYPS 0x00008000 /* Speed Select Bypass */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
@@ -347,6 +348,7 @@
/* Extended Configuration Control and Size */
#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
+#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008
#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 981936c1fb46..3e187b0e4203 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -141,6 +141,22 @@ struct e1000_info;
#define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */
#define HV_TNCRS_LOWER PHY_REG(778, 30)
+#define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */
+
+/* BM PHY Copper Specific Status */
+#define BM_CS_STATUS 17
+#define BM_CS_STATUS_LINK_UP 0x0400
+#define BM_CS_STATUS_RESOLVED 0x0800
+#define BM_CS_STATUS_SPEED_MASK 0xC000
+#define BM_CS_STATUS_SPEED_1000 0x8000
+
+/* 82577 Mobile Phy Status Register */
+#define HV_M_STATUS 26
+#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000
+#define HV_M_STATUS_SPEED_MASK 0x0300
+#define HV_M_STATUS_SPEED_1000 0x0200
+#define HV_M_STATUS_LINK_UP 0x0040
+
enum e1000_boards {
board_82571,
board_82572,
@@ -519,9 +535,13 @@ extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw);
extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw);
extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw);
extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset,
+ u16 *data);
extern s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw);
extern s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active);
extern s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset,
+ u16 data);
extern s32 e1000e_phy_sw_reset(struct e1000_hw *hw);
extern s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw);
extern s32 e1000e_get_cfg_done(struct e1000_hw *hw);
@@ -538,7 +558,11 @@ extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset,
+ u16 data);
extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset,
+ u16 *data);
extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
@@ -546,7 +570,11 @@ extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000e_check_downshift(struct e1000_hw *hw);
extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset,
+ u16 *data);
extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset,
+ u16 data);
extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow);
extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 1bf4d2a5d34f..e82638ecae88 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -327,10 +327,18 @@ static int e1000_set_pauseparam(struct net_device *netdev,
hw->fc.current_mode = hw->fc.requested_mode;
- retval = ((hw->phy.media_type == e1000_media_type_fiber) ?
- hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw));
+ if (hw->phy.media_type == e1000_media_type_fiber) {
+ retval = hw->mac.ops.setup_link(hw);
+ /* implicit goto out */
+ } else {
+ retval = e1000e_force_mac_fc(hw);
+ if (retval)
+ goto out;
+ e1000e_set_fc_watermarks(hw);
+ }
}
+out:
clear_bit(__E1000_RESETTING, &adapter->state);
return retval;
}
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index fd44d9f90769..aaea41ef794d 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -764,11 +764,13 @@ struct e1000_phy_operations {
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_phy_info)(struct e1000_hw *);
s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
+ s32 (*read_phy_reg_locked)(struct e1000_hw *, u32, u16 *);
void (*release_phy)(struct e1000_hw *);
s32 (*reset_phy)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
s32 (*write_phy_reg)(struct e1000_hw *, u32, u16);
+ s32 (*write_phy_reg_locked)(struct e1000_hw *, u32, u16);
s32 (*cfg_on_link_up)(struct e1000_hw *);
};
@@ -901,6 +903,7 @@ struct e1000_shadow_ram {
struct e1000_dev_spec_ich8lan {
bool kmrn_lock_loss_workaround_enabled;
struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS];
+ bool nvm_k1_enabled;
};
struct e1000_hw {
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 99df2abf82a9..eff3f4783655 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -122,6 +122,27 @@
#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */
+#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */
+
+/* SMBus Address Phy Register */
+#define HV_SMB_ADDR PHY_REG(768, 26)
+#define HV_SMB_ADDR_PEC_EN 0x0200
+#define HV_SMB_ADDR_VALID 0x0080
+
+/* Strapping Option Register - RO */
+#define E1000_STRAP 0x0000C
+#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
+#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17
+
+/* OEM Bits Phy Register */
+#define HV_OEM_BITS PHY_REG(768, 25)
+#define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */
+#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
+#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
+
+#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
+#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
+
/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
/* Offset 04h HSFSTS */
union ich8_hws_flash_status {
@@ -200,6 +221,10 @@ static s32 e1000_setup_led_pchlan(struct e1000_hw *hw);
static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
+static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
+static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
+static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
+static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
{
@@ -242,7 +267,11 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan;
phy->ops.read_phy_reg = e1000_read_phy_reg_hv;
+ phy->ops.read_phy_reg_locked = e1000_read_phy_reg_hv_locked;
+ phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan;
+ phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan;
phy->ops.write_phy_reg = e1000_write_phy_reg_hv;
+ phy->ops.write_phy_reg_locked = e1000_write_phy_reg_hv_locked;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
phy->id = e1000_phy_unknown;
@@ -303,6 +332,8 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
case IGP03E1000_E_PHY_ID:
phy->type = e1000_phy_igp_3;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+ phy->ops.read_phy_reg_locked = e1000e_read_phy_reg_igp_locked;
+ phy->ops.write_phy_reg_locked = e1000e_write_phy_reg_igp_locked;
break;
case IFE_E_PHY_ID:
case IFE_PLUS_E_PHY_ID:
@@ -469,14 +500,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
goto out;
}
- if (hw->mac.type == e1000_pchlan) {
- ret_val = e1000e_write_kmrn_reg(hw,
- E1000_KMRNCTRLSTA_K1_CONFIG,
- E1000_KMRNCTRLSTA_K1_ENABLE);
- if (ret_val)
- goto out;
- }
-
/*
* First we want to see if the MII Status Register reports
* link. If so, then we want to get the current speed/duplex
@@ -486,6 +509,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
if (ret_val)
goto out;
+ if (hw->mac.type == e1000_pchlan) {
+ ret_val = e1000_k1_gig_workaround_hv(hw, link);
+ if (ret_val)
+ goto out;
+ }
+
if (!link)
goto out; /* No link detected */
@@ -568,12 +597,39 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
static DEFINE_MUTEX(nvm_mutex);
/**
+ * e1000_acquire_nvm_ich8lan - Acquire NVM mutex
+ * @hw: pointer to the HW structure
+ *
+ * Acquires the mutex for performing NVM operations.
+ **/
+static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw)
+{
+ mutex_lock(&nvm_mutex);
+
+ return 0;
+}
+
+/**
+ * e1000_release_nvm_ich8lan - Release NVM mutex
+ * @hw: pointer to the HW structure
+ *
+ * Releases the mutex used while performing NVM operations.
+ **/
+static void e1000_release_nvm_ich8lan(struct e1000_hw *hw)
+{
+ mutex_unlock(&nvm_mutex);
+
+ return;
+}
+
+static DEFINE_MUTEX(swflag_mutex);
+
+/**
* e1000_acquire_swflag_ich8lan - Acquire software control flag
* @hw: pointer to the HW structure
*
- * Acquires the software control flag for performing NVM and PHY
- * operations. This is a function pointer entry point only called by
- * read/write routines for the PHY and NVM parts.
+ * Acquires the software control flag for performing PHY and select
+ * MAC CSR accesses.
**/
static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
{
@@ -582,7 +638,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
might_sleep();
- mutex_lock(&nvm_mutex);
+ mutex_lock(&swflag_mutex);
while (timeout) {
extcnf_ctrl = er32(EXTCNF_CTRL);
@@ -599,7 +655,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
goto out;
}
- timeout = PHY_CFG_TIMEOUT * 2;
+ timeout = SW_FLAG_TIMEOUT;
extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
ew32(EXTCNF_CTRL, extcnf_ctrl);
@@ -623,7 +679,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
out:
if (ret_val)
- mutex_unlock(&nvm_mutex);
+ mutex_unlock(&swflag_mutex);
return ret_val;
}
@@ -632,9 +688,8 @@ out:
* e1000_release_swflag_ich8lan - Release software control flag
* @hw: pointer to the HW structure
*
- * Releases the software control flag for performing NVM and PHY operations.
- * This is a function pointer entry point only called by read/write
- * routines for the PHY and NVM parts.
+ * Releases the software control flag for performing PHY and select
+ * MAC CSR accesses.
**/
static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
{
@@ -644,7 +699,9 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
ew32(EXTCNF_CTRL, extcnf_ctrl);
- mutex_unlock(&nvm_mutex);
+ mutex_unlock(&swflag_mutex);
+
+ return;
}
/**
@@ -752,6 +809,327 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
}
/**
+ * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration
+ * @hw: pointer to the HW structure
+ *
+ * SW should configure the LCD from the NVM extended configuration region
+ * as a workaround for certain parts.
+ **/
+static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
+ s32 ret_val;
+ u16 word_addr, reg_data, reg_addr, phy_page = 0;
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+
+ /*
+ * Initialize the PHY from the NVM on ICH platforms. This
+ * is needed due to an issue where the NVM configuration is
+ * not properly autoloaded after power transitions.
+ * Therefore, after each PHY reset, we will load the
+ * configuration data out of the NVM manually.
+ */
+ if ((hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) ||
+ (hw->mac.type == e1000_pchlan)) {
+ struct e1000_adapter *adapter = hw->adapter;
+
+ /* Check if SW needs to configure the PHY */
+ if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) ||
+ (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) ||
+ (hw->mac.type == e1000_pchlan))
+ sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
+ else
+ sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
+
+ data = er32(FEXTNVM);
+ if (!(data & sw_cfg_mask))
+ goto out;
+
+ /* Wait for basic configuration completes before proceeding */
+ e1000_lan_init_done_ich8lan(hw);
+
+ /*
+ * Make sure HW does not configure LCD from PHY
+ * extended configuration before SW configuration
+ */
+ data = er32(EXTCNF_CTRL);
+ if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
+ goto out;
+
+ cnf_size = er32(EXTCNF_SIZE);
+ cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
+ cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT;
+ if (!cnf_size)
+ goto out;
+
+ cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
+ cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
+
+ if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
+ (hw->mac.type == e1000_pchlan)) {
+ /*
+ * HW configures the SMBus address and LEDs when the
+ * OEM and LCD Write Enable bits are set in the NVM.
+ * When both NVM bits are cleared, SW will configure
+ * them instead.
+ */
+ data = er32(STRAP);
+ data &= E1000_STRAP_SMBUS_ADDRESS_MASK;
+ reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT;
+ reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
+ ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR,
+ reg_data);
+ if (ret_val)
+ goto out;
+
+ data = er32(LEDCTL);
+ ret_val = e1000_write_phy_reg_hv_locked(hw,
+ HV_LED_CONFIG,
+ (u16)data);
+ if (ret_val)
+ goto out;
+ }
+ /* Configure LCD from extended configuration region. */
+
+ /* cnf_base_addr is in DWORD */
+ word_addr = (u16)(cnf_base_addr << 1);
+
+ for (i = 0; i < cnf_size; i++) {
+ ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1,
+ &reg_data);
+ if (ret_val)
+ goto out;
+
+ ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1),
+ 1, &reg_addr);
+ if (ret_val)
+ goto out;
+
+ /* Save off the PHY page for future writes. */
+ if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) {
+ phy_page = reg_data;
+ continue;
+ }
+
+ reg_addr &= PHY_REG_MASK;
+ reg_addr |= phy_page;
+
+ ret_val = phy->ops.write_phy_reg_locked(hw,
+ (u32)reg_addr,
+ reg_data);
+ if (ret_val)
+ goto out;
+ }
+ }
+
+out:
+ hw->phy.ops.release_phy(hw);
+ return ret_val;
+}
+
+/**
+ * e1000_k1_gig_workaround_hv - K1 Si workaround
+ * @hw: pointer to the HW structure
+ * @link: link up bool flag
+ *
+ * If K1 is enabled for 1Gbps, the MAC might stall when transitioning
+ * from a lower speed. This workaround disables K1 whenever link is at 1Gig
+ * If link is down, the function will restore the default K1 setting located
+ * in the NVM.
+ **/
+static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link)
+{
+ s32 ret_val = 0;
+ u16 status_reg = 0;
+ bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled;
+
+ if (hw->mac.type != e1000_pchlan)
+ goto out;
+
+ /* Wrap the whole flow with the sw flag */
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ goto out;
+
+ /* Disable K1 when link is 1Gbps, otherwise use the NVM setting */
+ if (link) {
+ if (hw->phy.type == e1000_phy_82578) {
+ ret_val = hw->phy.ops.read_phy_reg_locked(hw,
+ BM_CS_STATUS,
+ &status_reg);
+ if (ret_val)
+ goto release;
+
+ status_reg &= BM_CS_STATUS_LINK_UP |
+ BM_CS_STATUS_RESOLVED |
+ BM_CS_STATUS_SPEED_MASK;
+
+ if (status_reg == (BM_CS_STATUS_LINK_UP |
+ BM_CS_STATUS_RESOLVED |
+ BM_CS_STATUS_SPEED_1000))
+ k1_enable = false;
+ }
+
+ if (hw->phy.type == e1000_phy_82577) {
+ ret_val = hw->phy.ops.read_phy_reg_locked(hw,
+ HV_M_STATUS,
+ &status_reg);
+ if (ret_val)
+ goto release;
+
+ status_reg &= HV_M_STATUS_LINK_UP |
+ HV_M_STATUS_AUTONEG_COMPLETE |
+ HV_M_STATUS_SPEED_MASK;
+
+ if (status_reg == (HV_M_STATUS_LINK_UP |
+ HV_M_STATUS_AUTONEG_COMPLETE |
+ HV_M_STATUS_SPEED_1000))
+ k1_enable = false;
+ }
+
+ /* Link stall fix for link up */
+ ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
+ 0x0100);
+ if (ret_val)
+ goto release;
+
+ } else {
+ /* Link stall fix for link down */
+ ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
+ 0x4100);
+ if (ret_val)
+ goto release;
+ }
+
+ ret_val = e1000_configure_k1_ich8lan(hw, k1_enable);
+
+release:
+ hw->phy.ops.release_phy(hw);
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_configure_k1_ich8lan - Configure K1 power state
+ * @hw: pointer to the HW structure
+ * @enable: K1 state to configure
+ *
+ * Configure the K1 power state based on the provided parameter.
+ * Assumes semaphore already acquired.
+ *
+ * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
+ **/
+static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
+{
+ s32 ret_val = 0;
+ u32 ctrl_reg = 0;
+ u32 ctrl_ext = 0;
+ u32 reg = 0;
+ u16 kmrn_reg = 0;
+
+ ret_val = e1000e_read_kmrn_reg_locked(hw,
+ E1000_KMRNCTRLSTA_K1_CONFIG,
+ &kmrn_reg);
+ if (ret_val)
+ goto out;
+
+ if (k1_enable)
+ kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE;
+ else
+ kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE;
+
+ ret_val = e1000e_write_kmrn_reg_locked(hw,
+ E1000_KMRNCTRLSTA_K1_CONFIG,
+ kmrn_reg);
+ if (ret_val)
+ goto out;
+
+ udelay(20);
+ ctrl_ext = er32(CTRL_EXT);
+ ctrl_reg = er32(CTRL);
+
+ reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
+ reg |= E1000_CTRL_FRCSPD;
+ ew32(CTRL, reg);
+
+ ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS);
+ udelay(20);
+ ew32(CTRL, ctrl_reg);
+ ew32(CTRL_EXT, ctrl_ext);
+ udelay(20);
+
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration
+ * @hw: pointer to the HW structure
+ * @d0_state: boolean if entering d0 or d3 device state
+ *
+ * SW will configure Gbe Disable and LPLU based on the NVM. The four bits are
+ * collectively called OEM bits. The OEM Write Enable bit and SW Config bit
+ * in NVM determines whether HW should configure LPLU and Gbe Disable.
+ **/
+static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
+{
+ s32 ret_val = 0;
+ u32 mac_reg;
+ u16 oem_reg;
+
+ if (hw->mac.type != e1000_pchlan)
+ return ret_val;
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+
+ mac_reg = er32(EXTCNF_CTRL);
+ if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)
+ goto out;
+
+ mac_reg = er32(FEXTNVM);
+ if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M))
+ goto out;
+
+ mac_reg = er32(PHY_CTRL);
+
+ ret_val = hw->phy.ops.read_phy_reg_locked(hw, HV_OEM_BITS, &oem_reg);
+ if (ret_val)
+ goto out;
+
+ oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU);
+
+ if (d0_state) {
+ if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE)
+ oem_reg |= HV_OEM_BITS_GBE_DIS;
+
+ if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)
+ oem_reg |= HV_OEM_BITS_LPLU;
+ } else {
+ if (mac_reg & E1000_PHY_CTRL_NOND0A_GBE_DISABLE)
+ oem_reg |= HV_OEM_BITS_GBE_DIS;
+
+ if (mac_reg & E1000_PHY_CTRL_NOND0A_LPLU)
+ oem_reg |= HV_OEM_BITS_LPLU;
+ }
+ /* Restart auto-neg to activate the bits */
+ if (!e1000_check_reset_block(hw))
+ oem_reg |= HV_OEM_BITS_RESTART_AN;
+ ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg);
+
+out:
+ hw->phy.ops.release_phy(hw);
+
+ return ret_val;
+}
+
+
+/**
* e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
* done after every PHY reset.
**/
@@ -791,10 +1169,20 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
ret_val = hw->phy.ops.acquire_phy(hw);
if (ret_val)
return ret_val;
+
hw->phy.addr = 1;
- e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
+ ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
+ if (ret_val)
+ goto out;
hw->phy.ops.release_phy(hw);
+ /*
+ * Configure the K1 Si workaround during phy reset assuming there is
+ * link so that it disables K1 if link is in 1Gbps.
+ */
+ ret_val = e1000_k1_gig_workaround_hv(hw, true);
+
+out:
return ret_val;
}
@@ -840,11 +1228,8 @@ static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw)
**/
static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i;
- u32 data, cnf_size, cnf_base_addr, sw_cfg_mask;
- s32 ret_val;
- u16 word_addr, reg_data, reg_addr, phy_page = 0;
+ s32 ret_val = 0;
+ u16 reg;
ret_val = e1000e_phy_hw_reset_generic(hw);
if (ret_val)
@@ -859,81 +1244,20 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
return ret_val;
}
- /*
- * Initialize the PHY from the NVM on ICH platforms. This
- * is needed due to an issue where the NVM configuration is
- * not properly autoloaded after power transitions.
- * Therefore, after each PHY reset, we will load the
- * configuration data out of the NVM manually.
- */
- if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) {
- struct e1000_adapter *adapter = hw->adapter;
-
- /* Check if SW needs configure the PHY */
- if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) ||
- (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M))
- sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
- else
- sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
-
- data = er32(FEXTNVM);
- if (!(data & sw_cfg_mask))
- return 0;
-
- /* Wait for basic configuration completes before proceeding */
- e1000_lan_init_done_ich8lan(hw);
-
- /*
- * Make sure HW does not configure LCD from PHY
- * extended configuration before SW configuration
- */
- data = er32(EXTCNF_CTRL);
- if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
- return 0;
-
- cnf_size = er32(EXTCNF_SIZE);
- cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
- cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT;
- if (!cnf_size)
- return 0;
-
- cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
- cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
-
- /* Configure LCD from extended configuration region. */
-
- /* cnf_base_addr is in DWORD */
- word_addr = (u16)(cnf_base_addr << 1);
-
- for (i = 0; i < cnf_size; i++) {
- ret_val = e1000_read_nvm(hw,
- (word_addr + i * 2),
- 1,
- &reg_data);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_nvm(hw,
- (word_addr + i * 2 + 1),
- 1,
- &reg_addr);
- if (ret_val)
- return ret_val;
-
- /* Save off the PHY page for future writes. */
- if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) {
- phy_page = reg_data;
- continue;
- }
+ /* Dummy read to clear the phy wakeup bit after lcd reset */
+ if (hw->mac.type == e1000_pchlan)
+ e1e_rphy(hw, BM_WUC, &reg);
- reg_addr |= phy_page;
+ /* Configure the LCD with the extended configuration region in NVM */
+ ret_val = e1000_sw_lcd_config_ich8lan(hw);
+ if (ret_val)
+ goto out;
- ret_val = e1e_wphy(hw, (u32)reg_addr, reg_data);
- if (ret_val)
- return ret_val;
- }
- }
+ /* Configure the LCD with the OEM bits in NVM */
+ if (hw->mac.type == e1000_pchlan)
+ ret_val = e1000_oem_bits_config_ich8lan(hw, true);
+out:
return 0;
}
@@ -1054,6 +1378,38 @@ static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw)
}
/**
+ * e1000_set_lplu_state_pchlan - Set Low Power Link Up state
+ * @hw: pointer to the HW structure
+ * @active: true to enable LPLU, false to disable
+ *
+ * Sets the LPLU state according to the active flag. For PCH, if OEM write
+ * bit are disabled in the NVM, writing the LPLU bits in the MAC will not set
+ * the phy speed. This function will manually set the LPLU bit and restart
+ * auto-neg as hw would do. D3 and D0 LPLU will call the same function
+ * since it configures the same bit.
+ **/
+static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active)
+{
+ s32 ret_val = 0;
+ u16 oem_reg;
+
+ ret_val = e1e_rphy(hw, HV_OEM_BITS, &oem_reg);
+ if (ret_val)
+ goto out;
+
+ if (active)
+ oem_reg |= HV_OEM_BITS_LPLU;
+ else
+ oem_reg &= ~HV_OEM_BITS_LPLU;
+
+ oem_reg |= HV_OEM_BITS_RESTART_AN;
+ ret_val = e1e_wphy(hw, HV_OEM_BITS, oem_reg);
+
+out:
+ return ret_val;
+}
+
+/**
* e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state
* @hw: pointer to the HW structure
* @active: TRUE to enable LPLU, FALSE to disable
@@ -1314,12 +1670,11 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
(words == 0)) {
hw_dbg(hw, "nvm parameter(s) out of bounds\n");
- return -E1000_ERR_NVM;
+ ret_val = -E1000_ERR_NVM;
+ goto out;
}
- ret_val = e1000_acquire_swflag_ich8lan(hw);
- if (ret_val)
- goto out;
+ nvm->ops.acquire_nvm(hw);
ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
if (ret_val) {
@@ -1345,7 +1700,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
}
}
- e1000_release_swflag_ich8lan(hw);
+ nvm->ops.release_nvm(hw);
out:
if (ret_val)
@@ -1603,11 +1958,15 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
return -E1000_ERR_NVM;
}
+ nvm->ops.acquire_nvm(hw);
+
for (i = 0; i < words; i++) {
dev_spec->shadow_ram[offset+i].modified = 1;
dev_spec->shadow_ram[offset+i].value = data[i];
}
+ nvm->ops.release_nvm(hw);
+
return 0;
}
@@ -1637,9 +1996,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
if (nvm->type != e1000_nvm_flash_sw)
goto out;
- ret_val = e1000_acquire_swflag_ich8lan(hw);
- if (ret_val)
- goto out;
+ nvm->ops.acquire_nvm(hw);
/*
* We're writing to the opposite bank so if we're on bank 1,
@@ -1657,7 +2014,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
old_bank_offset = 0;
ret_val = e1000_erase_flash_bank_ich8lan(hw, 1);
if (ret_val) {
- e1000_release_swflag_ich8lan(hw);
+ nvm->ops.release_nvm(hw);
goto out;
}
} else {
@@ -1665,7 +2022,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
new_bank_offset = 0;
ret_val = e1000_erase_flash_bank_ich8lan(hw, 0);
if (ret_val) {
- e1000_release_swflag_ich8lan(hw);
+ nvm->ops.release_nvm(hw);
goto out;
}
}
@@ -1723,7 +2080,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
if (ret_val) {
/* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
hw_dbg(hw, "Flash commit failed.\n");
- e1000_release_swflag_ich8lan(hw);
+ nvm->ops.release_nvm(hw);
goto out;
}
@@ -1736,7 +2093,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data);
if (ret_val) {
- e1000_release_swflag_ich8lan(hw);
+ nvm->ops.release_nvm(hw);
goto out;
}
data &= 0xBFFF;
@@ -1744,7 +2101,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
act_offset * 2 + 1,
(u8)(data >> 8));
if (ret_val) {
- e1000_release_swflag_ich8lan(hw);
+ nvm->ops.release_nvm(hw);
goto out;
}
@@ -1757,7 +2114,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
if (ret_val) {
- e1000_release_swflag_ich8lan(hw);
+ nvm->ops.release_nvm(hw);
goto out;
}
@@ -1767,7 +2124,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
dev_spec->shadow_ram[i].value = 0xFFFF;
}
- e1000_release_swflag_ich8lan(hw);
+ nvm->ops.release_nvm(hw);
/*
* Reload the EEPROM, or else modifications will not appear
@@ -1831,14 +2188,12 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
**/
void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw)
{
+ struct e1000_nvm_info *nvm = &hw->nvm;
union ich8_flash_protected_range pr0;
union ich8_hws_flash_status hsfsts;
u32 gfpreg;
- s32 ret_val;
- ret_val = e1000_acquire_swflag_ich8lan(hw);
- if (ret_val)
- return;
+ nvm->ops.acquire_nvm(hw);
gfpreg = er32flash(ICH_FLASH_GFPREG);
@@ -1859,7 +2214,7 @@ void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw)
hsfsts.hsf_status.flockdn = true;
ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval);
- e1000_release_swflag_ich8lan(hw);
+ nvm->ops.release_nvm(hw);
}
/**
@@ -2229,6 +2584,8 @@ static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
**/
static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
{
+ struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
+ u16 reg;
u32 ctrl, icr, kab;
s32 ret_val;
@@ -2263,6 +2620,18 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
ew32(PBS, E1000_PBS_16K);
}
+ if (hw->mac.type == e1000_pchlan) {
+ /* Save the NVM K1 bit setting*/
+ ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, &reg);
+ if (ret_val)
+ return ret_val;
+
+ if (reg & E1000_NVM_K1_ENABLE)
+ dev_spec->nvm_k1_enabled = true;
+ else
+ dev_spec->nvm_k1_enabled = false;
+ }
+
ctrl = er32(CTRL);
if (!e1000_check_reset_block(hw)) {
@@ -2304,7 +2673,19 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
hw_dbg(hw, "Auto Read Done did not complete\n");
}
}
+ /* Dummy read to clear the phy wakeup bit after lcd reset */
+ if (hw->mac.type == e1000_pchlan)
+ e1e_rphy(hw, BM_WUC, &reg);
+ ret_val = e1000_sw_lcd_config_ich8lan(hw);
+ if (ret_val)
+ goto out;
+
+ if (hw->mac.type == e1000_pchlan) {
+ ret_val = e1000_oem_bits_config_ich8lan(hw, true);
+ if (ret_val)
+ goto out;
+ }
/*
* For PCH, this write will make sure that any noise
* will be detected as a CRC error and be dropped rather than show up
@@ -2323,6 +2704,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
if (hw->mac.type == e1000_pchlan)
ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
+out:
return ret_val;
}
@@ -2627,14 +3009,6 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
if (ret_val)
return ret_val;
- if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) {
- ret_val = e1000e_write_kmrn_reg(hw,
- E1000_KMRNCTRLSTA_K1_CONFIG,
- E1000_KMRNCTRLSTA_K1_DISABLE);
- if (ret_val)
- return ret_val;
- }
-
if ((hw->mac.type == e1000_ich8lan) &&
(hw->phy.type == e1000_phy_igp_3) &&
(*speed == SPEED_1000)) {
@@ -2843,9 +3217,8 @@ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
E1000_PHY_CTRL_GBE_DISABLE;
ew32(PHY_CTRL, phy_ctrl);
- /* Workaround SWFLAG unexpectedly set during S0->Sx */
if (hw->mac.type == e1000_pchlan)
- udelay(500);
+ e1000_phy_hw_reset_ich8lan(hw);
default:
break;
}
@@ -3113,9 +3486,9 @@ static struct e1000_phy_operations ich8_phy_ops = {
};
static struct e1000_nvm_operations ich8_nvm_ops = {
- .acquire_nvm = e1000_acquire_swflag_ich8lan,
+ .acquire_nvm = e1000_acquire_nvm_ich8lan,
.read_nvm = e1000_read_nvm_ich8lan,
- .release_nvm = e1000_release_swflag_ich8lan,
+ .release_nvm = e1000_release_nvm_ich8lan,
.update_nvm = e1000_update_nvm_checksum_ich8lan,
.valid_led_default = e1000_valid_led_default_ich8lan,
.validate_nvm = e1000_validate_nvm_checksum_ich8lan,
@@ -3186,6 +3559,7 @@ struct e1000_info e1000_pch_info = {
| FLAG_HAS_AMT
| FLAG_HAS_FLASH
| FLAG_HAS_JUMBO_FRAMES
+ | FLAG_DISABLE_FC_PAUSE_TIME /* errata */
| FLAG_APME_IN_WUC,
.pba = 26,
.max_hw_frame_size = 4096,
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 0687c6aa4e46..fad8f9ea0043 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter)
/*
* flow control settings
*
- * The high water mark must be low enough to fit two full frame
+ * The high water mark must be low enough to fit one full frame
* (or the size used for early receive) above it in the Rx FIFO.
* Set it to the lower of:
* - 90% of the Rx FIFO size, and
* - the full Rx FIFO size minus the early receive size (for parts
* with ERT support assuming ERT set to E1000_ERT_2048), or
- * - the full Rx FIFO size minus two full frames
+ * - the full Rx FIFO size minus one full frame
*/
- if ((adapter->flags & FLAG_HAS_ERT) &&
- (adapter->netdev->mtu > ETH_DATA_LEN))
- hwm = min(((pba << 10) * 9 / 10),
- ((pba << 10) - (E1000_ERT_2048 << 3)));
- else
- hwm = min(((pba << 10) * 9 / 10),
- ((pba << 10) - (2 * adapter->max_frame_size)));
+ if (hw->mac.type == e1000_pchlan) {
+ /*
+ * Workaround PCH LOM adapter hangs with certain network
+ * loads. If hangs persist, try disabling Tx flow control.
+ */
+ if (adapter->netdev->mtu > ETH_DATA_LEN) {
+ fc->high_water = 0x3500;
+ fc->low_water = 0x1500;
+ } else {
+ fc->high_water = 0x5000;
+ fc->low_water = 0x3000;
+ }
+ } else {
+ if ((adapter->flags & FLAG_HAS_ERT) &&
+ (adapter->netdev->mtu > ETH_DATA_LEN))
+ hwm = min(((pba << 10) * 9 / 10),
+ ((pba << 10) - (E1000_ERT_2048 << 3)));
+ else
+ hwm = min(((pba << 10) * 9 / 10),
+ ((pba << 10) - adapter->max_frame_size));
- fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
- fc->low_water = (fc->high_water - (2 * adapter->max_frame_size));
- fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */
+ fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
+ fc->low_water = fc->high_water - 8;
+ }
if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
fc->pause_time = 0xFFFF;
@@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter)
if (mac->ops.init_hw(hw))
e_err("Hardware Error\n");
+ /* additional part of the flow-control workaround above */
+ if (hw->mac.type == e1000_pchlan)
+ ew32(FCRTV_PCH, 0x1000);
+
e1000_update_mng_vlan(adapter);
/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
@@ -3610,7 +3627,7 @@ static void e1000_watchdog_task(struct work_struct *work)
case SPEED_100:
txb2b = 0;
netdev->tx_queue_len = 100;
- /* maybe add some timeout factor ? */
+ adapter->tx_timeout_factor = 10;
break;
}
@@ -4288,8 +4305,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
msleep(1);
- /* e1000e_down has a dependency on max_frame_size */
+ /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
adapter->max_frame_size = max_frame;
+ e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
+ netdev->mtu = new_mtu;
if (netif_running(netdev))
e1000e_down(adapter);
@@ -4319,9 +4338,6 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
+ ETH_FCS_LEN;
- e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
- netdev->mtu = new_mtu;
-
if (netif_running(netdev))
e1000e_up(adapter);
else
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 994401fd0664..85f955f70417 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -71,7 +71,6 @@ static const u16 e1000_igp_2_cable_length_table[] =
#define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15)
#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */
#define I82577_CTRL_REG 23
-#define I82577_CTRL_DOWNSHIFT_MASK (7 << 10)
/* 82577 specific PHY registers */
#define I82577_PHY_CTRL_2 18
@@ -95,13 +94,6 @@ static const u16 e1000_igp_2_cable_length_table[] =
/* BM PHY Copper Specific Control 1 */
#define BM_CS_CTRL1 16
-/* BM PHY Copper Specific Status */
-#define BM_CS_STATUS 17
-#define BM_CS_STATUS_LINK_UP 0x0400
-#define BM_CS_STATUS_RESOLVED 0x0800
-#define BM_CS_STATUS_SPEED_MASK 0xC000
-#define BM_CS_STATUS_SPEED_1000 0x8000
-
#define HV_MUX_DATA_CTRL PHY_REG(776, 16)
#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400
#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004
@@ -164,16 +156,25 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw)
* MDIC mode. No harm in trying again in this case since
* the PHY ID is unknown at this point anyway
*/
+ ret_val = phy->ops.acquire_phy(hw);
+ if (ret_val)
+ goto out;
ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
if (ret_val)
goto out;
+ phy->ops.release_phy(hw);
retry_count++;
}
out:
/* Revert to MDIO fast mode, if applicable */
- if (retry_count)
+ if (retry_count) {
+ ret_val = phy->ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+ phy->ops.release_phy(hw);
+ }
return ret_val;
}
@@ -354,94 +355,173 @@ s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
}
/**
- * e1000e_read_phy_reg_igp - Read igp PHY register
+ * __e1000e_read_phy_reg_igp - Read igp PHY register
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
+ * @locked: semaphore has already been acquired or not
*
* Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
+ * and stores the retrieved information in data. Release any acquired
* semaphores before exiting.
**/
-s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
+static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
+ bool locked)
{
- s32 ret_val;
+ s32 ret_val = 0;
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
+ if (!locked) {
+ if (!(hw->phy.ops.acquire_phy))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ goto out;
+ }
if (offset > MAX_PHY_MULTI_PAGE_REG) {
ret_val = e1000e_write_phy_reg_mdic(hw,
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- return ret_val;
- }
+ if (ret_val)
+ goto release;
}
ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
-
- hw->phy.ops.release_phy(hw);
+ data);
+release:
+ if (!locked)
+ hw->phy.ops.release_phy(hw);
+out:
return ret_val;
}
/**
+ * e1000e_read_phy_reg_igp - Read igp PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read
+ * @data: pointer to the read data
+ *
+ * Acquires semaphore then reads the PHY register at offset and stores the
+ * retrieved information in data.
+ * Release the acquired semaphore before exiting.
+ **/
+s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ return __e1000e_read_phy_reg_igp(hw, offset, data, false);
+}
+
+/**
+ * e1000e_read_phy_reg_igp_locked - Read igp PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read
+ * @data: pointer to the read data
+ *
+ * Reads the PHY register at offset and stores the retrieved information
+ * in data. Assumes semaphore already acquired.
+ **/
+s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ return __e1000e_read_phy_reg_igp(hw, offset, data, true);
+}
+
+/**
* e1000e_write_phy_reg_igp - Write igp PHY register
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write at register offset
+ * @locked: semaphore has already been acquired or not
*
* Acquires semaphore, if necessary, then writes the data to PHY register
* at the offset. Release any acquired semaphores before exiting.
**/
-s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
+static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
+ bool locked)
{
- s32 ret_val;
+ s32 ret_val = 0;
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
+ if (!locked) {
+ if (!(hw->phy.ops.acquire_phy))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ goto out;
+ }
if (offset > MAX_PHY_MULTI_PAGE_REG) {
ret_val = e1000e_write_phy_reg_mdic(hw,
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- return ret_val;
- }
+ if (ret_val)
+ goto release;
}
ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
data);
- hw->phy.ops.release_phy(hw);
+release:
+ if (!locked)
+ hw->phy.ops.release_phy(hw);
+out:
return ret_val;
}
/**
- * e1000e_read_kmrn_reg - Read kumeran register
+ * e1000e_write_phy_reg_igp - Write igp PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Acquires semaphore then writes the data to PHY register
+ * at the offset. Release any acquired semaphores before exiting.
+ **/
+s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ return __e1000e_write_phy_reg_igp(hw, offset, data, false);
+}
+
+/**
+ * e1000e_write_phy_reg_igp_locked - Write igp PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Writes the data to PHY register at the offset.
+ * Assumes semaphore already acquired.
+ **/
+s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ return __e1000e_write_phy_reg_igp(hw, offset, data, true);
+}
+
+/**
+ * __e1000_read_kmrn_reg - Read kumeran register
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
+ * @locked: semaphore has already been acquired or not
*
* Acquires semaphore, if necessary. Then reads the PHY register at offset
* using the kumeran interface. The information retrieved is stored in data.
* Release any acquired semaphores before exiting.
**/
-s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
+static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
+ bool locked)
{
u32 kmrnctrlsta;
- s32 ret_val;
+ s32 ret_val = 0;
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
+ if (!locked) {
+ if (!(hw->phy.ops.acquire_phy))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ goto out;
+ }
kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
@@ -452,41 +532,111 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
kmrnctrlsta = er32(KMRNCTRLSTA);
*data = (u16)kmrnctrlsta;
- hw->phy.ops.release_phy(hw);
+ if (!locked)
+ hw->phy.ops.release_phy(hw);
+out:
return ret_val;
}
/**
- * e1000e_write_kmrn_reg - Write kumeran register
+ * e1000e_read_kmrn_reg - Read kumeran register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read
+ * @data: pointer to the read data
+ *
+ * Acquires semaphore then reads the PHY register at offset using the
+ * kumeran interface. The information retrieved is stored in data.
+ * Release the acquired semaphore before exiting.
+ **/
+s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ return __e1000_read_kmrn_reg(hw, offset, data, false);
+}
+
+/**
+ * e1000e_read_kmrn_reg_locked - Read kumeran register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read
+ * @data: pointer to the read data
+ *
+ * Reads the PHY register at offset using the kumeran interface. The
+ * information retrieved is stored in data.
+ * Assumes semaphore already acquired.
+ **/
+s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ return __e1000_read_kmrn_reg(hw, offset, data, true);
+}
+
+/**
+ * __e1000_write_kmrn_reg - Write kumeran register
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write at register offset
+ * @locked: semaphore has already been acquired or not
*
* Acquires semaphore, if necessary. Then write the data to PHY register
* at the offset using the kumeran interface. Release any acquired semaphores
* before exiting.
**/
-s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
+static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
+ bool locked)
{
u32 kmrnctrlsta;
- s32 ret_val;
+ s32 ret_val = 0;
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
+ if (!locked) {
+ if (!(hw->phy.ops.acquire_phy))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ goto out;
+ }
kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
E1000_KMRNCTRLSTA_OFFSET) | data;
ew32(KMRNCTRLSTA, kmrnctrlsta);
udelay(2);
- hw->phy.ops.release_phy(hw);
+ if (!locked)
+ hw->phy.ops.release_phy(hw);
+
+out:
return ret_val;
}
/**
+ * e1000e_write_kmrn_reg - Write kumeran register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Acquires semaphore then writes the data to the PHY register at the offset
+ * using the kumeran interface. Release the acquired semaphore before exiting.
+ **/
+s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ return __e1000_write_kmrn_reg(hw, offset, data, false);
+}
+
+/**
+ * e1000e_write_kmrn_reg_locked - Write kumeran register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Write the data to PHY register at the offset using the kumeran interface.
+ * Assumes semaphore already acquired.
+ **/
+s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ return __e1000_write_kmrn_reg(hw, offset, data, true);
+}
+
+/**
* e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
* @hw: pointer to the HW structure
*
@@ -509,15 +659,6 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data);
- if (ret_val)
- goto out;
-
- /* Set number of link attempts before downshift */
- ret_val = phy->ops.read_phy_reg(hw, I82577_CTRL_REG, &phy_data);
- if (ret_val)
- goto out;
- phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK;
- ret_val = phy->ops.write_phy_reg(hw, I82577_CTRL_REG, phy_data);
out:
return ret_val;
@@ -2105,6 +2246,10 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
u32 page = offset >> IGP_PAGE_SHIFT;
u32 page_shift = 0;
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
@@ -2112,10 +2257,6 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
goto out;
}
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- goto out;
-
hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2135,18 +2276,15 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
/* Page is shifted left, PHY expects (page x 32) */
ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
(page << page_shift));
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
+ if (ret_val)
goto out;
- }
}
ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
data);
- hw->phy.ops.release_phy(hw);
-
out:
+ hw->phy.ops.release_phy(hw);
return ret_val;
}
@@ -2167,6 +2305,10 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
u32 page = offset >> IGP_PAGE_SHIFT;
u32 page_shift = 0;
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
@@ -2174,10 +2316,6 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
goto out;
}
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- goto out;
-
hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2197,17 +2335,14 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
/* Page is shifted left, PHY expects (page x 32) */
ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
(page << page_shift));
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
+ if (ret_val)
goto out;
- }
}
ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
data);
- hw->phy.ops.release_phy(hw);
-
out:
+ hw->phy.ops.release_phy(hw);
return ret_val;
}
@@ -2226,17 +2361,17 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
s32 ret_val;
u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
true);
- return ret_val;
+ goto out;
}
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
hw->phy.addr = 1;
if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2245,16 +2380,14 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
page);
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- return ret_val;
- }
+ if (ret_val)
+ goto out;
}
ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
data);
+out:
hw->phy.ops.release_phy(hw);
-
return ret_val;
}
@@ -2272,17 +2405,17 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
s32 ret_val;
u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
false);
- return ret_val;
+ goto out;
}
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
hw->phy.addr = 1;
if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2290,17 +2423,15 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
page);
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- return ret_val;
- }
+ if (ret_val)
+ goto out;
}
ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
data);
+out:
hw->phy.ops.release_phy(hw);
-
return ret_val;
}
@@ -2320,6 +2451,8 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
* 3) Write the address using the address opcode (0x11)
* 4) Read or write the data using the data opcode (0x12)
* 5) Restore 769_17.2 to its original value
+ *
+ * Assumes semaphore already acquired.
**/
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
u16 *data, bool read)
@@ -2327,20 +2460,12 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
s32 ret_val;
u16 reg = BM_PHY_REG_NUM(offset);
u16 phy_reg = 0;
- u8 phy_acquired = 1;
-
/* Gig must be disabled for MDIO accesses to page 800 */
if ((hw->mac.type == e1000_pchlan) &&
(!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
hw_dbg(hw, "Attempting to access page 800 while gig enabled\n");
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val) {
- phy_acquired = 0;
- goto out;
- }
-
/* All operations in this function are phy address 1 */
hw->phy.addr = 1;
@@ -2397,8 +2522,6 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
out:
- if (phy_acquired == 1)
- hw->phy.ops.release_phy(hw);
return ret_val;
}
@@ -2439,52 +2562,63 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
return 0;
}
+/**
+ * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode
+ * @hw: pointer to the HW structure
+ * @slow: true for slow mode, false for normal mode
+ *
+ * Assumes semaphore already acquired.
+ **/
s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow)
{
s32 ret_val = 0;
u16 data = 0;
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
/* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */
hw->phy.addr = 1;
ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
(BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- return ret_val;
- }
+ if (ret_val)
+ goto out;
+
ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1,
(0x2180 | (slow << 10)));
+ if (ret_val)
+ goto out;
/* dummy read when reverting to fast mode - throw away result */
if (!slow)
- e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
-
- hw->phy.ops.release_phy(hw);
+ ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
+out:
return ret_val;
}
/**
- * e1000_read_phy_reg_hv - Read HV PHY register
+ * __e1000_read_phy_reg_hv - Read HV PHY register
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
+ * @locked: semaphore has already been acquired or not
*
* Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
+ * and stores the retrieved information in data. Release any acquired
* semaphore before exiting.
**/
-s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
+static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
+ bool locked)
{
s32 ret_val;
u16 page = BM_PHY_REG_PAGE(offset);
u16 reg = BM_PHY_REG_NUM(offset);
bool in_slow_mode = false;
+ if (!locked) {
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+ }
+
/* Workaround failure in MDIO access while cable is disconnected */
if ((hw->phy.type == e1000_phy_82577) &&
!(er32(STATUS) & E1000_STATUS_LU)) {
@@ -2508,63 +2642,92 @@ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
goto out;
}
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- goto out;
-
hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
if (page == HV_INTC_FC_PAGE_START)
page = 0;
if (reg > MAX_PHY_MULTI_PAGE_REG) {
- if ((hw->phy.type != e1000_phy_82578) ||
- ((reg != I82578_ADDR_REG) &&
- (reg != I82578_ADDR_REG + 1))) {
- u32 phy_addr = hw->phy.addr;
-
- hw->phy.addr = 1;
-
- /* Page is shifted left, PHY expects (page x 32) */
- ret_val = e1000e_write_phy_reg_mdic(hw,
- IGP01E1000_PHY_PAGE_SELECT,
- (page << IGP_PAGE_SHIFT));
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- goto out;
- }
- hw->phy.addr = phy_addr;
- }
+ u32 phy_addr = hw->phy.addr;
+
+ hw->phy.addr = 1;
+
+ /* Page is shifted left, PHY expects (page x 32) */
+ ret_val = e1000e_write_phy_reg_mdic(hw,
+ IGP01E1000_PHY_PAGE_SELECT,
+ (page << IGP_PAGE_SHIFT));
+ hw->phy.addr = phy_addr;
+
+ if (ret_val)
+ goto out;
}
ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
data);
- hw->phy.ops.release_phy(hw);
-
out:
/* Revert to MDIO fast mode, if applicable */
if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
- ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+ ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
+
+ if (!locked)
+ hw->phy.ops.release_phy(hw);
return ret_val;
}
/**
- * e1000_write_phy_reg_hv - Write HV PHY register
+ * e1000_read_phy_reg_hv - Read HV PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read
+ * @data: pointer to the read data
+ *
+ * Acquires semaphore then reads the PHY register at offset and stores
+ * the retrieved information in data. Release the acquired semaphore
+ * before exiting.
+ **/
+s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ return __e1000_read_phy_reg_hv(hw, offset, data, false);
+}
+
+/**
+ * e1000_read_phy_reg_hv_locked - Read HV PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read
+ * @data: pointer to the read data
+ *
+ * Reads the PHY register at offset and stores the retrieved information
+ * in data. Assumes semaphore already acquired.
+ **/
+s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ return __e1000_read_phy_reg_hv(hw, offset, data, true);
+}
+
+/**
+ * __e1000_write_phy_reg_hv - Write HV PHY register
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write at register offset
+ * @locked: semaphore has already been acquired or not
*
* Acquires semaphore, if necessary, then writes the data to PHY register
* at the offset. Release any acquired semaphores before exiting.
**/
-s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
+static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
+ bool locked)
{
s32 ret_val;
u16 page = BM_PHY_REG_PAGE(offset);
u16 reg = BM_PHY_REG_NUM(offset);
bool in_slow_mode = false;
+ if (!locked) {
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+ }
+
/* Workaround failure in MDIO access while cable is disconnected */
if ((hw->phy.type == e1000_phy_82577) &&
!(er32(STATUS) & E1000_STATUS_LU)) {
@@ -2588,10 +2751,6 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
goto out;
}
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- goto out;
-
hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
if (page == HV_INTC_FC_PAGE_START)
@@ -2607,50 +2766,70 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
((MAX_PHY_REG_ADDRESS & reg) == 0) &&
(data & (1 << 11))) {
u16 data2 = 0x7EFF;
- hw->phy.ops.release_phy(hw);
ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3,
&data2, false);
if (ret_val)
goto out;
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- goto out;
}
if (reg > MAX_PHY_MULTI_PAGE_REG) {
- if ((hw->phy.type != e1000_phy_82578) ||
- ((reg != I82578_ADDR_REG) &&
- (reg != I82578_ADDR_REG + 1))) {
- u32 phy_addr = hw->phy.addr;
-
- hw->phy.addr = 1;
-
- /* Page is shifted left, PHY expects (page x 32) */
- ret_val = e1000e_write_phy_reg_mdic(hw,
- IGP01E1000_PHY_PAGE_SELECT,
- (page << IGP_PAGE_SHIFT));
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- goto out;
- }
- hw->phy.addr = phy_addr;
- }
+ u32 phy_addr = hw->phy.addr;
+
+ hw->phy.addr = 1;
+
+ /* Page is shifted left, PHY expects (page x 32) */
+ ret_val = e1000e_write_phy_reg_mdic(hw,
+ IGP01E1000_PHY_PAGE_SELECT,
+ (page << IGP_PAGE_SHIFT));
+ hw->phy.addr = phy_addr;
+
+ if (ret_val)
+ goto out;
}
ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
data);
- hw->phy.ops.release_phy(hw);
out:
/* Revert to MDIO fast mode, if applicable */
if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
- ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+ ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
+
+ if (!locked)
+ hw->phy.ops.release_phy(hw);
return ret_val;
}
/**
+ * e1000_write_phy_reg_hv - Write HV PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Acquires semaphore then writes the data to PHY register at the offset.
+ * Release the acquired semaphores before exiting.
+ **/
+s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ return __e1000_write_phy_reg_hv(hw, offset, data, false);
+}
+
+/**
+ * e1000_write_phy_reg_hv_locked - Write HV PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Writes the data to PHY register at the offset. Assumes semaphore
+ * already acquired.
+ **/
+s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ return __e1000_write_phy_reg_hv(hw, offset, data, true);
+}
+
+/**
* e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page
* @page: page to be accessed
**/
@@ -2671,10 +2850,9 @@ static u32 e1000_get_phy_addr_for_hv_page(u32 page)
* @data: pointer to the data to be read or written
* @read: determines if operation is read or written
*
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retreived information in data. Release any acquired
- * semaphores before exiting. Note that the procedure to read these regs
- * uses the address port and data port to read/write.
+ * Reads the PHY register at offset and stores the retreived information
+ * in data. Assumes semaphore already acquired. Note that the procedure
+ * to read these regs uses the address port and data port to read/write.
**/
static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
u16 *data, bool read)
@@ -2682,20 +2860,12 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
s32 ret_val;
u32 addr_reg = 0;
u32 data_reg = 0;
- u8 phy_acquired = 1;
/* This takes care of the difference with desktop vs mobile phy */
addr_reg = (hw->phy.type == e1000_phy_82578) ?
I82578_ADDR_REG : I82577_ADDR_REG;
data_reg = addr_reg + 1;
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val) {
- hw_dbg(hw, "Could not acquire PHY\n");
- phy_acquired = 0;
- goto out;
- }
-
/* All operations in this function are phy address 2 */
hw->phy.addr = 2;
@@ -2718,8 +2888,6 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
}
out:
- if (phy_acquired == 1)
- hw->phy.ops.release_phy(hw);
return ret_val;
}
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 96f5b2a2d2c5..f7d9ac8324cb 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -223,24 +223,25 @@ struct ethoc_bd {
u32 addr;
};
-static u32 ethoc_read(struct ethoc *dev, loff_t offset)
+static inline u32 ethoc_read(struct ethoc *dev, loff_t offset)
{
return ioread32(dev->iobase + offset);
}
-static void ethoc_write(struct ethoc *dev, loff_t offset, u32 data)
+static inline void ethoc_write(struct ethoc *dev, loff_t offset, u32 data)
{
iowrite32(data, dev->iobase + offset);
}
-static void ethoc_read_bd(struct ethoc *dev, int index, struct ethoc_bd *bd)
+static inline void ethoc_read_bd(struct ethoc *dev, int index,
+ struct ethoc_bd *bd)
{
loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
bd->stat = ethoc_read(dev, offset + 0);
bd->addr = ethoc_read(dev, offset + 4);
}
-static void ethoc_write_bd(struct ethoc *dev, int index,
+static inline void ethoc_write_bd(struct ethoc *dev, int index,
const struct ethoc_bd *bd)
{
loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
@@ -248,33 +249,33 @@ static void ethoc_write_bd(struct ethoc *dev, int index,
ethoc_write(dev, offset + 4, bd->addr);
}
-static void ethoc_enable_irq(struct ethoc *dev, u32 mask)
+static inline void ethoc_enable_irq(struct ethoc *dev, u32 mask)
{
u32 imask = ethoc_read(dev, INT_MASK);
imask |= mask;
ethoc_write(dev, INT_MASK, imask);
}
-static void ethoc_disable_irq(struct ethoc *dev, u32 mask)
+static inline void ethoc_disable_irq(struct ethoc *dev, u32 mask)
{
u32 imask = ethoc_read(dev, INT_MASK);
imask &= ~mask;
ethoc_write(dev, INT_MASK, imask);
}
-static void ethoc_ack_irq(struct ethoc *dev, u32 mask)
+static inline void ethoc_ack_irq(struct ethoc *dev, u32 mask)
{
ethoc_write(dev, INT_SOURCE, mask);
}
-static void ethoc_enable_rx_and_tx(struct ethoc *dev)
+static inline void ethoc_enable_rx_and_tx(struct ethoc *dev)
{
u32 mode = ethoc_read(dev, MODER);
mode |= MODER_RXEN | MODER_TXEN;
ethoc_write(dev, MODER, mode);
}
-static void ethoc_disable_rx_and_tx(struct ethoc *dev)
+static inline void ethoc_disable_rx_and_tx(struct ethoc *dev)
{
u32 mode = ethoc_read(dev, MODER);
mode &= ~(MODER_RXEN | MODER_TXEN);
@@ -508,7 +509,7 @@ static irqreturn_t ethoc_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
- ethoc_ack_irq(priv, INT_MASK_ALL);
+ ethoc_ack_irq(priv, pending);
if (pending & INT_MASK_BUSY) {
dev_err(&dev->dev, "packet dropped\n");
@@ -664,7 +665,8 @@ static int ethoc_open(struct net_device *dev)
return ret;
/* calculate the number of TX/RX buffers, maximum 128 supported */
- num_bd = min(128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ);
+ num_bd = min_t(unsigned int,
+ 128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ);
priv->num_tx = max(min_tx, num_bd / 4);
priv->num_rx = num_bd - priv->num_tx;
ethoc_write(priv, TX_BD_NUM, priv->num_tx);
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 29234380e6c6..16a1d58419d9 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1654,7 +1654,7 @@ static const struct net_device_ops fec_netdev_ops = {
*
* index is only used in legacy code
*/
-int __init fec_enet_init(struct net_device *dev, int index)
+static int fec_enet_init(struct net_device *dev, int index)
{
struct fec_enet_private *fep = netdev_priv(dev);
struct bufdesc *cbd_base;
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index c40113f58963..66dace6d324f 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -759,12 +759,6 @@ static void mpc52xx_fec_reset(struct net_device *dev)
mpc52xx_fec_hw_init(dev);
- if (priv->phydev) {
- phy_stop(priv->phydev);
- phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
- phy_start(priv->phydev);
- }
-
bcom_fec_rx_reset(priv->rx_dmatsk);
bcom_fec_tx_reset(priv->tx_dmatsk);
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index 31e6d62b785d..ee0f3c6d3f88 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -155,6 +155,7 @@ static struct of_device_id mpc52xx_fec_mdio_match[] = {
{ .compatible = "mpc5200b-fec-phy", },
{}
};
+MODULE_DEVICE_TABLE(of, mpc52xx_fec_mdio_match);
struct of_platform_driver mpc52xx_fec_mdio_driver = {
.name = "mpc5200b-fec-phy",
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index e1da4666f204..3116601dbfea 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -5821,10 +5821,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev->dev_addr);
dev_printk(KERN_ERR, &pci_dev->dev,
"Please complain to your hardware vendor. Switching to a random MAC.\n");
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x00;
- dev->dev_addr[2] = 0x6c;
- get_random_bytes(&dev->dev_addr[3], 3);
+ random_ether_addr(dev->dev_addr);
}
dprintk(KERN_DEBUG "%s: MAC Address %pM\n",
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 2bc2d2b20644..ec2f5034457f 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -1110,6 +1110,7 @@ static struct of_device_id fs_enet_match[] = {
#endif
{}
};
+MODULE_DEVICE_TABLE(of, fs_enet_match);
static struct of_platform_driver fs_enet_driver = {
.name = "fs_enet",
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index 93b481b0e3c7..24ff9f43a62b 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -221,6 +221,7 @@ static struct of_device_id fs_enet_mdio_bb_match[] = {
},
{},
};
+MODULE_DEVICE_TABLE(of, fs_enet_mdio_bb_match);
static struct of_platform_driver fs_enet_bb_mdio_driver = {
.name = "fsl-bb-mdio",
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index a2d69c1cd07e..96eba4280c5c 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -219,6 +219,7 @@ static struct of_device_id fs_enet_mdio_fec_match[] = {
#endif
{},
};
+MODULE_DEVICE_TABLE(of, fs_enet_mdio_fec_match);
static struct of_platform_driver fs_enet_fec_mdio_driver = {
.name = "fsl-fec-mdio",
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c
index d167090248e2..efbf67689eca 100644
--- a/drivers/net/fsl_pq_mdio.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -407,6 +407,7 @@ static struct of_device_id fsl_pq_mdio_match[] = {
},
{},
};
+MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match);
static struct of_platform_driver fsl_pq_mdio_driver = {
.name = "fsl-pq_mdio",
@@ -426,3 +427,4 @@ void fsl_pq_mdio_exit(void)
of_unregister_platform_driver(&fsl_pq_mdio_driver);
}
module_exit(fsl_pq_mdio_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 1e5289ffef6f..5bf31f1509c9 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2325,9 +2325,6 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
return IRQ_HANDLED;
}
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:fsl-gianfar");
-
static struct of_device_id gfar_match[] =
{
{
@@ -2336,6 +2333,7 @@ static struct of_device_id gfar_match[] =
},
{},
};
+MODULE_DEVICE_TABLE(of, gfar_match);
/* Structure for a device driver */
static struct of_platform_driver gfar_driver = {
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 89c82c5e63e4..3fae87559791 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -24,6 +24,7 @@
*
*/
+#include <linux/module.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
@@ -443,7 +444,7 @@ static u32 __emac_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_s
ret |= EMAC_MR1_TFS_2K;
break;
default:
- printk(KERN_WARNING "%s: Unknown Rx FIFO size %d\n",
+ printk(KERN_WARNING "%s: Unknown Tx FIFO size %d\n",
dev->ndev->name, tx_size);
}
@@ -470,6 +471,9 @@ static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_
DBG2(dev, "__emac4_calc_base_mr1" NL);
switch(tx_size) {
+ case 16384:
+ ret |= EMAC4_MR1_TFS_16K;
+ break;
case 4096:
ret |= EMAC4_MR1_TFS_4K;
break;
@@ -477,7 +481,7 @@ static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_
ret |= EMAC4_MR1_TFS_2K;
break;
default:
- printk(KERN_WARNING "%s: Unknown Rx FIFO size %d\n",
+ printk(KERN_WARNING "%s: Unknown Tx FIFO size %d\n",
dev->ndev->name, tx_size);
}
@@ -2985,6 +2989,7 @@ static struct of_device_id emac_match[] =
},
{},
};
+MODULE_DEVICE_TABLE(of, emac_match);
static struct of_platform_driver emac_driver = {
.name = "emac",
diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h
index 0afc2cf5c52b..8a61b597a169 100644
--- a/drivers/net/ibm_newemac/emac.h
+++ b/drivers/net/ibm_newemac/emac.h
@@ -153,6 +153,7 @@ struct emac_regs {
#define EMAC4_MR1_RFS_16K 0x00280000
#define EMAC4_MR1_TFS_2K 0x00020000
#define EMAC4_MR1_TFS_4K 0x00030000
+#define EMAC4_MR1_TFS_16K 0x00050000
#define EMAC4_MR1_TR 0x00008000
#define EMAC4_MR1_MWSW_001 0x00001000
#define EMAC4_MR1_JPSM 0x00000800
@@ -262,8 +263,8 @@ struct emac_regs {
/* EMACx_TRTR */
-#define EMAC_TRTR_SHIFT_EMAC4 27
-#define EMAC_TRTR_SHIFT 24
+#define EMAC_TRTR_SHIFT_EMAC4 24
+#define EMAC_TRTR_SHIFT 27
/* EMAC specific TX descriptor control fields (write access) */
#define EMAC_TX_CTRL_GFCS 0x0200
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 801f088c134f..030913f8bd26 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -98,12 +98,13 @@ static void ri_tasklet(unsigned long dev)
stats->tx_packets++;
stats->tx_bytes +=skb->len;
- skb->dev = __dev_get_by_index(&init_net, skb->iif);
+ skb->dev = dev_get_by_index(&init_net, skb->iif);
if (!skb->dev) {
dev_kfree_skb(skb);
stats->tx_dropped++;
break;
}
+ dev_put(skb->dev);
skb->iif = _dev->ifindex;
if (from & AT_EGRESS) {
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index deaea8fa1032..b243ed3b0c36 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -732,7 +732,7 @@ static int igb_set_ringparam(struct net_device *netdev,
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct igb_ring *temp_ring;
- int i, err;
+ int i, err = 0;
u32 new_rx_count, new_tx_count;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
@@ -752,18 +752,30 @@ static int igb_set_ringparam(struct net_device *netdev,
return 0;
}
+ while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
+ msleep(1);
+
+ if (!netif_running(adapter->netdev)) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i].count = new_tx_count;
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i].count = new_rx_count;
+ adapter->tx_ring_count = new_tx_count;
+ adapter->rx_ring_count = new_rx_count;
+ goto clear_reset;
+ }
+
if (adapter->num_tx_queues > adapter->num_rx_queues)
temp_ring = vmalloc(adapter->num_tx_queues * sizeof(struct igb_ring));
else
temp_ring = vmalloc(adapter->num_rx_queues * sizeof(struct igb_ring));
- if (!temp_ring)
- return -ENOMEM;
- while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- msleep(1);
+ if (!temp_ring) {
+ err = -ENOMEM;
+ goto clear_reset;
+ }
- if (netif_running(adapter->netdev))
- igb_down(adapter);
+ igb_down(adapter);
/*
* We can't just free everything and then setup again,
@@ -820,14 +832,11 @@ static int igb_set_ringparam(struct net_device *netdev,
adapter->rx_ring_count = new_rx_count;
}
-
- err = 0;
err_setup:
- if (netif_running(adapter->netdev))
- igb_up(adapter);
-
- clear_bit(__IGB_RESETTING, &adapter->state);
+ igb_up(adapter);
vfree(temp_ring);
+clear_reset:
+ clear_bit(__IGB_RESETTING, &adapter->state);
return err;
}
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
index ee17a097d1ca..c68265bd0d1a 100644
--- a/drivers/net/igbvf/ethtool.c
+++ b/drivers/net/igbvf/ethtool.c
@@ -279,7 +279,7 @@ static int igbvf_set_ringparam(struct net_device *netdev,
{
struct igbvf_adapter *adapter = netdev_priv(netdev);
struct igbvf_ring *temp_ring;
- int err;
+ int err = 0;
u32 new_rx_count, new_tx_count;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
@@ -299,15 +299,22 @@ static int igbvf_set_ringparam(struct net_device *netdev,
return 0;
}
- temp_ring = vmalloc(sizeof(struct igbvf_ring));
- if (!temp_ring)
- return -ENOMEM;
-
while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
msleep(1);
- if (netif_running(adapter->netdev))
- igbvf_down(adapter);
+ if (!netif_running(adapter->netdev)) {
+ adapter->tx_ring->count = new_tx_count;
+ adapter->rx_ring->count = new_rx_count;
+ goto clear_reset;
+ }
+
+ temp_ring = vmalloc(sizeof(struct igbvf_ring));
+ if (!temp_ring) {
+ err = -ENOMEM;
+ goto clear_reset;
+ }
+
+ igbvf_down(adapter);
/*
* We can't just free everything and then setup again,
@@ -339,14 +346,11 @@ static int igbvf_set_ringparam(struct net_device *netdev,
memcpy(adapter->rx_ring, temp_ring,sizeof(struct igbvf_ring));
}
-
- err = 0;
err_setup:
- if (netif_running(adapter->netdev))
- igbvf_up(adapter);
-
- clear_bit(__IGBVF_RESETTING, &adapter->state);
+ igbvf_up(adapter);
vfree(temp_ring);
+clear_reset:
+ clear_bit(__IGBVF_RESETTING, &adapter->state);
return err;
}
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 38bf7cf2256d..c412e8026173 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -232,8 +232,11 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
/*
* Ensure that the ports for this device are setup correctly.
*/
- if (si->pdata->startup)
- si->pdata->startup(si->dev);
+ if (si->pdata->startup) {
+ ret = si->pdata->startup(si->dev);
+ if (ret)
+ return ret;
+ }
/*
* Configure PPC for IRDA - we want to drive TXD2 low.
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index fa314cb005a4..856c18c207f3 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -798,7 +798,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_ring *temp_tx_ring, *temp_rx_ring;
- int i, err;
+ int i, err = 0;
u32 new_rx_count, new_tx_count;
bool need_update = false;
@@ -822,6 +822,16 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
msleep(1);
+ if (!netif_running(adapter->netdev)) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i].count = new_tx_count;
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i].count = new_rx_count;
+ adapter->tx_ring_count = new_tx_count;
+ adapter->rx_ring_count = new_rx_count;
+ goto err_setup;
+ }
+
temp_tx_ring = kcalloc(adapter->num_tx_queues,
sizeof(struct ixgbe_ring), GFP_KERNEL);
if (!temp_tx_ring) {
@@ -879,8 +889,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
/* if rings need to be updated, here's the place to do it in one shot */
if (need_update) {
- if (netif_running(netdev))
- ixgbe_down(adapter);
+ ixgbe_down(adapter);
/* tx */
if (new_tx_count != adapter->tx_ring_count) {
@@ -897,13 +906,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
temp_rx_ring = NULL;
adapter->rx_ring_count = new_rx_count;
}
- }
-
- /* success! */
- err = 0;
- if (netif_running(netdev))
ixgbe_up(adapter);
-
+ }
err_setup:
clear_bit(__IXGBE_RESETTING, &adapter->state);
return err;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index cbb143ca1eb8..a456578b8578 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -44,6 +44,7 @@
#include "ixgbe.h"
#include "ixgbe_common.h"
+#include "ixgbe_dcb_82599.h"
char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
@@ -226,6 +227,56 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
/* tx_buffer_info must be completely set up in the transmit path */
}
+/**
+ * ixgbe_tx_is_paused - check if the tx ring is paused
+ * @adapter: the ixgbe adapter
+ * @tx_ring: the corresponding tx_ring
+ *
+ * If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the
+ * corresponding TC of this tx_ring when checking TFCS.
+ *
+ * Returns : true if paused
+ */
+static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *tx_ring)
+{
+ u32 txoff = IXGBE_TFCS_TXOFF;
+
+#ifdef CONFIG_IXGBE_DCB
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ int tc;
+ int reg_idx = tx_ring->reg_idx;
+ int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ tc = reg_idx >> 2;
+ txoff = IXGBE_TFCS_TXOFF0;
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ tc = 0;
+ txoff = IXGBE_TFCS_TXOFF;
+ if (dcb_i == 8) {
+ /* TC0, TC1 */
+ tc = reg_idx >> 5;
+ if (tc == 2) /* TC2, TC3 */
+ tc += (reg_idx - 64) >> 4;
+ else if (tc == 3) /* TC4, TC5, TC6, TC7 */
+ tc += 1 + ((reg_idx - 96) >> 3);
+ } else if (dcb_i == 4) {
+ /* TC0, TC1 */
+ tc = reg_idx >> 6;
+ if (tc == 1) {
+ tc += (reg_idx - 64) >> 5;
+ if (tc == 2) /* TC2, TC3 */
+ tc += (reg_idx - 96) >> 4;
+ }
+ }
+ }
+ txoff <<= tc;
+ }
+#endif
+ return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff;
+}
+
static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring,
unsigned int eop)
@@ -237,7 +288,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
adapter->detect_tx_hung = false;
if (tx_ring->tx_buffer_info[eop].time_stamp &&
time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
- !(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) {
+ !ixgbe_tx_is_paused(adapter, tx_ring)) {
/* detected Tx unit hang */
union ixgbe_adv_tx_desc *tx_desc;
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
@@ -412,19 +463,23 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
u32 txctrl;
int cpu = get_cpu();
int q = tx_ring - adapter->tx_ring;
+ struct ixgbe_hw *hw = &adapter->hw;
if (tx_ring->cpu != cpu) {
- txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q));
if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(q));
txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(q), txctrl);
} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q));
txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
- IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+ IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+ txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl);
}
- txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl);
tx_ring->cpu = cpu;
}
put_cpu();
@@ -1913,11 +1968,25 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
break;
}
}
+
if (hw->mac.type == ixgbe_mac_82599EB) {
+ u32 rttdcs;
+
+ /* disable the arbiter while setting MTQC */
+ rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+ rttdcs |= IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+
/* We enable 8 traffic classes, DCB only */
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
IXGBE_WRITE_REG(hw, IXGBE_MTQC, (IXGBE_MTQC_RT_ENA |
IXGBE_MTQC_8TC_8TQ));
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
+
+ /* re-eable the arbiter */
+ rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
}
}
@@ -2471,7 +2540,10 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
ixgbe_restore_vlan(adapter);
#ifdef CONFIG_IXGBE_DCB
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- netif_set_gso_max_size(netdev, 32768);
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ netif_set_gso_max_size(netdev, 32768);
+ else
+ netif_set_gso_max_size(netdev, 65536);
ixgbe_configure_dcb(adapter);
} else {
netif_set_gso_max_size(netdev, 65536);
@@ -5922,6 +5994,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
} else {
pci_set_master(pdev);
pci_restore_state(pdev);
+ pci_save_state(pdev);
pci_wake_from_d3(pdev, false);
diff --git a/drivers/net/ixp2000/enp2611.c b/drivers/net/ixp2000/enp2611.c
index b02a981c87a8..34a6cfd17930 100644
--- a/drivers/net/ixp2000/enp2611.c
+++ b/drivers/net/ixp2000/enp2611.c
@@ -119,24 +119,9 @@ static struct ixp2400_msf_parameters enp2611_msf_parameters =
}
};
-struct enp2611_ixpdev_priv
-{
- struct ixpdev_priv ixpdev_priv;
- struct net_device_stats stats;
-};
-
static struct net_device *nds[3];
static struct timer_list link_check_timer;
-static struct net_device_stats *enp2611_get_stats(struct net_device *dev)
-{
- struct enp2611_ixpdev_priv *ip = netdev_priv(dev);
-
- pm3386_get_stats(ip->ixpdev_priv.channel, &(ip->stats));
-
- return &(ip->stats);
-}
-
/* @@@ Poll the SFP moddef0 line too. */
/* @@@ Try to use the pm3386 DOOL interrupt as well. */
static void enp2611_check_link_status(unsigned long __dummy)
@@ -203,14 +188,13 @@ static int __init enp2611_init_module(void)
ports = pm3386_port_count();
for (i = 0; i < ports; i++) {
- nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv));
+ nds[i] = ixpdev_alloc(i, sizeof(struct ixpdev_priv));
if (nds[i] == NULL) {
while (--i >= 0)
free_netdev(nds[i]);
return -ENOMEM;
}
- nds[i]->get_stats = enp2611_get_stats;
pm3386_init_port(i);
pm3386_get_mac(i, nds[i]->dev_addr);
}
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index 127243461a51..9aee0cc922c9 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -21,6 +21,7 @@
#include "ixp2400_tx.ucode"
#include "ixpdev_priv.h"
#include "ixpdev.h"
+#include "pm3386.h"
#define DRV_MODULE_VERSION "0.2"
@@ -271,6 +272,15 @@ static int ixpdev_close(struct net_device *dev)
return 0;
}
+static struct net_device_stats *ixpdev_get_stats(struct net_device *dev)
+{
+ struct ixpdev_priv *ip = netdev_priv(dev);
+
+ pm3386_get_stats(ip->channel, &(dev->stats));
+
+ return &(dev->stats);
+}
+
static const struct net_device_ops ixpdev_netdev_ops = {
.ndo_open = ixpdev_open,
.ndo_stop = ixpdev_close,
@@ -278,6 +288,7 @@ static const struct net_device_ops ixpdev_netdev_ops = {
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
+ .ndo_get_stats = ixpdev_get_stats,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ixpdev_poll_controller,
#endif
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c
index 237835864357..a23f739d222f 100644
--- a/drivers/net/ks8851.c
+++ b/drivers/net/ks8851.c
@@ -171,6 +171,36 @@ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val)
}
/**
+ * ks8851_wrreg8 - write 8bit register value to chip
+ * @ks: The chip state
+ * @reg: The register address
+ * @val: The value to write
+ *
+ * Issue a write to put the value @val into the register specified in @reg.
+ */
+static void ks8851_wrreg8(struct ks8851_net *ks, unsigned reg, unsigned val)
+{
+ struct spi_transfer *xfer = &ks->spi_xfer1;
+ struct spi_message *msg = &ks->spi_msg1;
+ __le16 txb[2];
+ int ret;
+ int bit;
+
+ bit = 1 << (reg & 3);
+
+ txb[0] = cpu_to_le16(MK_OP(bit, reg) | KS_SPIOP_WR);
+ txb[1] = val;
+
+ xfer->tx_buf = txb;
+ xfer->rx_buf = NULL;
+ xfer->len = 3;
+
+ ret = spi_sync(ks->spidev, msg);
+ if (ret < 0)
+ ks_err(ks, "spi_sync() failed\n");
+}
+
+/**
* ks8851_rx_1msg - select whether to use one or two messages for spi read
* @ks: The device structure
*
@@ -322,13 +352,12 @@ static void ks8851_soft_reset(struct ks8851_net *ks, unsigned op)
static int ks8851_write_mac_addr(struct net_device *dev)
{
struct ks8851_net *ks = netdev_priv(dev);
- u16 *mcp = (u16 *)dev->dev_addr;
+ int i;
mutex_lock(&ks->lock);
- ks8851_wrreg16(ks, KS_MARL, mcp[0]);
- ks8851_wrreg16(ks, KS_MARM, mcp[1]);
- ks8851_wrreg16(ks, KS_MARH, mcp[2]);
+ for (i = 0; i < ETH_ALEN; i++)
+ ks8851_wrreg8(ks, KS_MAR(i), dev->dev_addr[i]);
mutex_unlock(&ks->lock);
@@ -951,7 +980,7 @@ static void ks8851_set_rx_mode(struct net_device *dev)
mcptr = mcptr->next;
}
- rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXAE | RXCR1_RXPAFMA;
+ rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA;
} else {
/* just accept broadcast / unicast */
rxctrl.rxcr1 = RXCR1_RXPAFMA;
@@ -1239,6 +1268,9 @@ static int __devinit ks8851_probe(struct spi_device *spi)
ndev->netdev_ops = &ks8851_netdev_ops;
ndev->irq = spi->irq;
+ /* issue a global soft reset to reset the device. */
+ ks8851_soft_reset(ks, GRR_GSR);
+
/* simple check for a valid chip being connected to the bus */
if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) {
diff --git a/drivers/net/ks8851.h b/drivers/net/ks8851.h
index 85abe147afbf..f52c312cc356 100644
--- a/drivers/net/ks8851.h
+++ b/drivers/net/ks8851.h
@@ -16,6 +16,7 @@
#define CCR_32PIN (1 << 0)
/* MAC address registers */
+#define KS_MAR(_m) 0x15 - (_m)
#define KS_MARL 0x10
#define KS_MARM 0x12
#define KS_MARH 0x14
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c
index 0be14d702beb..c146304d8d6c 100644
--- a/drivers/net/ks8851_mll.c
+++ b/drivers/net/ks8851_mll.c
@@ -568,6 +568,16 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len)
iowrite16(*wptr++, ks->hw_addr);
}
+static void ks_disable_int(struct ks_net *ks)
+{
+ ks_wrreg16(ks, KS_IER, 0x0000);
+} /* ks_disable_int */
+
+static void ks_enable_int(struct ks_net *ks)
+{
+ ks_wrreg16(ks, KS_IER, ks->rc_ier);
+} /* ks_enable_int */
+
/**
* ks_tx_fifo_space - return the available hardware buffer size.
* @ks: The chip information
@@ -681,6 +691,47 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op)
}
+void ks_enable_qmu(struct ks_net *ks)
+{
+ u16 w;
+
+ w = ks_rdreg16(ks, KS_TXCR);
+ /* Enables QMU Transmit (TXCR). */
+ ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);
+
+ /*
+ * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
+ * Enable
+ */
+
+ w = ks_rdreg16(ks, KS_RXQCR);
+ ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);
+
+ /* Enables QMU Receive (RXCR1). */
+ w = ks_rdreg16(ks, KS_RXCR1);
+ ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
+ ks->enabled = true;
+} /* ks_enable_qmu */
+
+static void ks_disable_qmu(struct ks_net *ks)
+{
+ u16 w;
+
+ w = ks_rdreg16(ks, KS_TXCR);
+
+ /* Disables QMU Transmit (TXCR). */
+ w &= ~TXCR_TXE;
+ ks_wrreg16(ks, KS_TXCR, w);
+
+ /* Disables QMU Receive (RXCR1). */
+ w = ks_rdreg16(ks, KS_RXCR1);
+ w &= ~RXCR1_RXE ;
+ ks_wrreg16(ks, KS_RXCR1, w);
+
+ ks->enabled = false;
+
+} /* ks_disable_qmu */
+
/**
* ks_read_qmu - read 1 pkt data from the QMU.
* @ks: The chip information
@@ -752,7 +803,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
(frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
skb_reserve(skb, 2);
/* read data block including CRC 4 bytes */
- ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4);
+ ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len);
skb_put(skb, frame_hdr->len);
skb->dev = netdev;
skb->protocol = eth_type_trans(skb, netdev);
@@ -861,7 +912,7 @@ static int ks_net_open(struct net_device *netdev)
ks_dbg(ks, "%s - entry\n", __func__);
/* reset the HW */
- err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks);
+ err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev);
if (err) {
printk(KERN_ERR "Failed to request IRQ: %d: %d\n",
@@ -869,6 +920,15 @@ static int ks_net_open(struct net_device *netdev)
return err;
}
+ /* wake up powermode to normal mode */
+ ks_set_powermode(ks, PMECR_PM_NORMAL);
+ mdelay(1); /* wait for normal mode to take effect */
+
+ ks_wrreg16(ks, KS_ISR, 0xffff);
+ ks_enable_int(ks);
+ ks_enable_qmu(ks);
+ netif_start_queue(ks->netdev);
+
if (netif_msg_ifup(ks))
ks_dbg(ks, "network device %s up\n", netdev->name);
@@ -892,19 +952,14 @@ static int ks_net_stop(struct net_device *netdev)
netif_stop_queue(netdev);
- kfree(ks->frame_head_info);
-
mutex_lock(&ks->lock);
/* turn off the IRQs and ack any outstanding */
ks_wrreg16(ks, KS_IER, 0x0000);
ks_wrreg16(ks, KS_ISR, 0xffff);
- /* shutdown RX process */
- ks_wrreg16(ks, KS_RXCR1, 0x0000);
-
- /* shutdown TX process */
- ks_wrreg16(ks, KS_TXCR, 0x0000);
+ /* shutdown RX/TX QMU */
+ ks_disable_qmu(ks);
/* set powermode to soft power down to save power */
ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
@@ -929,17 +984,8 @@ static int ks_net_stop(struct net_device *netdev)
*/
static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
{
- unsigned fid = ks->fid;
-
- fid = ks->fid;
- ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK;
-
- /* reduce the tx interrupt occurrances. */
- if (!fid)
- fid |= TXFR_TXIC; /* irq on completion */
-
/* start header at txb[0] to align txw entries */
- ks->txh.txw[0] = cpu_to_le16(fid);
+ ks->txh.txw[0] = 0;
ks->txh.txw[1] = cpu_to_le16(len);
/* 1. set sudo-DMA mode */
@@ -957,16 +1003,6 @@ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
;
}
-static void ks_disable_int(struct ks_net *ks)
-{
- ks_wrreg16(ks, KS_IER, 0x0000);
-} /* ks_disable_int */
-
-static void ks_enable_int(struct ks_net *ks)
-{
- ks_wrreg16(ks, KS_IER, ks->rc_ier);
-} /* ks_enable_int */
-
/**
* ks_start_xmit - transmit packet
* @skb : The buffer to transmit
@@ -1410,25 +1446,6 @@ static int ks_read_selftest(struct ks_net *ks)
return ret;
}
-static void ks_disable(struct ks_net *ks)
-{
- u16 w;
-
- w = ks_rdreg16(ks, KS_TXCR);
-
- /* Disables QMU Transmit (TXCR). */
- w &= ~TXCR_TXE;
- ks_wrreg16(ks, KS_TXCR, w);
-
- /* Disables QMU Receive (RXCR1). */
- w = ks_rdreg16(ks, KS_RXCR1);
- w &= ~RXCR1_RXE ;
- ks_wrreg16(ks, KS_RXCR1, w);
-
- ks->enabled = false;
-
-} /* ks_disable */
-
static void ks_setup(struct ks_net *ks)
{
u16 w;
@@ -1463,7 +1480,7 @@ static void ks_setup(struct ks_net *ks)
w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
ks_wrreg16(ks, KS_TXCR, w);
- w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE;
+ w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC;
if (ks->promiscuous) /* bPromiscuous */
w |= (RXCR1_RXAE | RXCR1_RXINVF);
@@ -1486,28 +1503,6 @@ static void ks_setup_int(struct ks_net *ks)
ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI);
} /* ks_setup_int */
-void ks_enable(struct ks_net *ks)
-{
- u16 w;
-
- w = ks_rdreg16(ks, KS_TXCR);
- /* Enables QMU Transmit (TXCR). */
- ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);
-
- /*
- * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
- * Enable
- */
-
- w = ks_rdreg16(ks, KS_RXQCR);
- ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);
-
- /* Enables QMU Receive (RXCR1). */
- w = ks_rdreg16(ks, KS_RXCR1);
- ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
- ks->enabled = true;
-} /* ks_enable */
-
static int ks_hw_init(struct ks_net *ks)
{
#define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES)
@@ -1612,11 +1607,9 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
ks_soft_reset(ks, GRR_GSR);
ks_hw_init(ks);
- ks_disable(ks);
+ ks_disable_qmu(ks);
ks_setup(ks);
ks_setup_int(ks);
- ks_enable_int(ks);
- ks_enable(ks);
memcpy(netdev->dev_addr, ks->mac_addr, 6);
data = ks_rdreg16(ks, KS_OBCR);
@@ -1658,6 +1651,7 @@ static int __devexit ks8851_remove(struct platform_device *pdev)
struct ks_net *ks = netdev_priv(netdev);
struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ kfree(ks->frame_head_info);
unregister_netdev(netdev);
iounmap(ks->hw_addr);
free_netdev(netdev);
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 61eabcac734c..b3d7d8d77f46 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -223,69 +223,73 @@ static int __devinit macsonic_init(struct net_device *dev)
return 0;
}
-static int __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev)
+#define INVALID_MAC(mac) (memcmp(mac, "\x08\x00\x07", 3) && \
+ memcmp(mac, "\x00\xA0\x40", 3) && \
+ memcmp(mac, "\x00\x80\x19", 3) && \
+ memcmp(mac, "\x00\x05\x02", 3))
+
+static void __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev)
{
struct sonic_local *lp = netdev_priv(dev);
const int prom_addr = ONBOARD_SONIC_PROM_BASE;
- int i;
+ unsigned short val;
- /* On NuBus boards we can sometimes look in the ROM resources.
- No such luck for comm-slot/onboard. */
- for(i = 0; i < 6; i++)
- dev->dev_addr[i] = SONIC_READ_PROM(i);
+ /*
+ * On NuBus boards we can sometimes look in the ROM resources.
+ * No such luck for comm-slot/onboard.
+ * On the PowerBook 520, the PROM base address is a mystery.
+ */
+ if (hwreg_present((void *)prom_addr)) {
+ int i;
+
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = SONIC_READ_PROM(i);
+ if (!INVALID_MAC(dev->dev_addr))
+ return;
- /* Most of the time, the address is bit-reversed. The NetBSD
- source has a rather long and detailed historical account of
- why this is so. */
- if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
- memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
- memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
- memcmp(dev->dev_addr, "\x00\x05\x02", 3))
+ /*
+ * Most of the time, the address is bit-reversed. The NetBSD
+ * source has a rather long and detailed historical account of
+ * why this is so.
+ */
bit_reverse_addr(dev->dev_addr);
- else
- return 0;
-
- /* If we still have what seems to be a bogus address, we'll
- look in the CAM. The top entry should be ours. */
- /* Danger! This only works if MacOS has already initialized
- the card... */
- if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
- memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
- memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
- memcmp(dev->dev_addr, "\x00\x05\x02", 3))
- {
- unsigned short val;
-
- printk(KERN_INFO "macsonic: PROM seems to be wrong, trying CAM entry 15\n");
-
- SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
- SONIC_WRITE(SONIC_CEP, 15);
-
- val = SONIC_READ(SONIC_CAP2);
- dev->dev_addr[5] = val >> 8;
- dev->dev_addr[4] = val & 0xff;
- val = SONIC_READ(SONIC_CAP1);
- dev->dev_addr[3] = val >> 8;
- dev->dev_addr[2] = val & 0xff;
- val = SONIC_READ(SONIC_CAP0);
- dev->dev_addr[1] = val >> 8;
- dev->dev_addr[0] = val & 0xff;
-
- printk(KERN_INFO "HW Address from CAM 15: %pM\n",
- dev->dev_addr);
- } else return 0;
-
- if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
- memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
- memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
- memcmp(dev->dev_addr, "\x00\x05\x02", 3))
- {
+ if (!INVALID_MAC(dev->dev_addr))
+ return;
+
/*
- * Still nonsense ... messed up someplace!
+ * If we still have what seems to be a bogus address, we'll
+ * look in the CAM. The top entry should be ours.
*/
- printk(KERN_ERR "macsonic: ERROR (INVALID MAC)\n");
- return -EIO;
- } else return 0;
+ printk(KERN_WARNING "macsonic: MAC address in PROM seems "
+ "to be invalid, trying CAM\n");
+ } else {
+ printk(KERN_WARNING "macsonic: cannot read MAC address from "
+ "PROM, trying CAM\n");
+ }
+
+ /* This only works if MacOS has already initialized the card. */
+
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
+ SONIC_WRITE(SONIC_CEP, 15);
+
+ val = SONIC_READ(SONIC_CAP2);
+ dev->dev_addr[5] = val >> 8;
+ dev->dev_addr[4] = val & 0xff;
+ val = SONIC_READ(SONIC_CAP1);
+ dev->dev_addr[3] = val >> 8;
+ dev->dev_addr[2] = val & 0xff;
+ val = SONIC_READ(SONIC_CAP0);
+ dev->dev_addr[1] = val >> 8;
+ dev->dev_addr[0] = val & 0xff;
+
+ if (!INVALID_MAC(dev->dev_addr))
+ return;
+
+ /* Still nonsense ... messed up someplace! */
+
+ printk(KERN_WARNING "macsonic: MAC address in CAM entry 15 "
+ "seems invalid, will use a random MAC\n");
+ random_ether_addr(dev->dev_addr);
}
static int __devinit mac_onboard_sonic_probe(struct net_device *dev)
@@ -402,8 +406,7 @@ static int __devinit mac_onboard_sonic_probe(struct net_device *dev)
SONIC_WRITE(SONIC_ISR, 0x7fff);
/* Now look for the MAC address. */
- if (mac_onboard_sonic_ethernet_addr(dev) != 0)
- return -ENODEV;
+ mac_onboard_sonic_ethernet_addr(dev);
/* Shared init code */
return macsonic_init(dev);
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 3aabfd9dd212..2490aa39804c 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -360,6 +360,7 @@ static int macvlan_init(struct net_device *dev)
dev->state = (dev->state & ~MACVLAN_STATE_MASK) |
(lowerdev->state & MACVLAN_STATE_MASK);
dev->features = lowerdev->features & MACVLAN_FEATURES;
+ dev->gso_max_size = lowerdev->gso_max_size;
dev->iflink = lowerdev->ifindex;
dev->hard_header_len = lowerdev->hard_header_len;
@@ -596,6 +597,7 @@ static int macvlan_device_event(struct notifier_block *unused,
case NETDEV_FEAT_CHANGE:
list_for_each_entry(vlan, &port->vlans, list) {
vlan->dev->features = dev->features & MACVLAN_FEATURES;
+ vlan->dev->gso_max_size = dev->gso_max_size;
netdev_features_change(vlan->dev);
}
break;
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 5dd7225b178e..291a505fd4fc 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -1282,6 +1282,7 @@ static struct pci_device_id mlx4_pci_table[] = {
{ PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */
{ PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
{ PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/
+ { PCI_VDEVICE(MELLANOX, 0x6746) }, /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */
{ PCI_VDEVICE(MELLANOX, 0x676e) }, /* MT26478 ConnectX2 40GigE PCIe gen2 */
{ 0, }
};
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 6930c87f362e..f3624517cb0e 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -75,7 +75,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.5.0-1.432"
+#define MYRI10GE_VERSION_STR "1.5.1-1.451"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -1624,10 +1624,21 @@ myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
return 0;
}
}
- if (*ptr == 'R' || *ptr == 'Q') {
- /* We've found either an XFP or quad ribbon fiber */
+ if (*ptr == '2')
+ ptr++;
+ if (*ptr == 'R' || *ptr == 'Q' || *ptr == 'S') {
+ /* We've found either an XFP, quad ribbon fiber, or SFP+ */
cmd->port = PORT_FIBRE;
+ cmd->supported |= SUPPORTED_FIBRE;
+ cmd->advertising |= ADVERTISED_FIBRE;
+ } else {
+ cmd->port = PORT_OTHER;
}
+ if (*ptr == 'R' || *ptr == 'S')
+ cmd->transceiver = XCVR_EXTERNAL;
+ else
+ cmd->transceiver = XCVR_INTERNAL;
+
return 0;
}
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 7384f59df615..e1237b802872 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1163,6 +1163,8 @@ struct netxen_adapter {
u32 int_vec_bit;
u32 heartbit;
+ u8 mac_addr[ETH_ALEN];
+
struct netxen_adapter_stats stats;
struct netxen_recv_context recv_ctx;
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 7a7177421d7c..17bb3818d84e 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -419,6 +419,7 @@ enum {
#define NETXEN_CRB_ROMUSB \
NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_ROMUSB)
#define NETXEN_CRB_I2Q NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2Q)
+#define NETXEN_CRB_I2C0 NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2C0)
#define NETXEN_CRB_SMB NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SMB)
#define NETXEN_CRB_MAX NETXEN_PCI_CRB_WINDOW(64)
@@ -544,6 +545,8 @@ enum {
#define NETXEN_NIU_TEST_MUX_CTL (NETXEN_CRB_NIU + 0x00094)
#define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098)
#define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc)
+#define NETXEN_NIU_FRAME_COUNT_SELECT (NETXEN_CRB_NIU + 0x000ac)
+#define NETXEN_NIU_FRAME_COUNT (NETXEN_CRB_NIU + 0x000b0)
#define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128)
#define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c)
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 32314000dfcd..52a3798d8d94 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -383,24 +383,51 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
{
- __u32 reg;
+ u32 mac_cfg;
+ u32 cnt = 0;
+ __u32 reg = 0x0200;
u32 port = adapter->physical_port;
+ u16 board_type = adapter->ahw.board_type;
if (port > NETXEN_NIU_MAX_XG_PORTS)
return -EINVAL;
- reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
- if (mode == NETXEN_NIU_PROMISC_MODE)
- reg = (reg | 0x2000UL);
- else
- reg = (reg & ~0x2000UL);
+ mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port));
+ mac_cfg &= ~0x4;
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg);
- if (mode == NETXEN_NIU_ALLMULTI_MODE)
- reg = (reg | 0x1000UL);
- else
- reg = (reg & ~0x1000UL);
+ if ((board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) ||
+ (board_type == NETXEN_BRDTYPE_P2_SB31_10G_HMEZ))
+ reg = (0x20 << port);
+
+ NXWR32(adapter, NETXEN_NIU_FRAME_COUNT_SELECT, reg);
+
+ mdelay(10);
+
+ while (NXRD32(adapter, NETXEN_NIU_FRAME_COUNT) && ++cnt < 20)
+ mdelay(10);
+
+ if (cnt < 20) {
+
+ reg = NXRD32(adapter,
+ NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
- NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+ if (mode == NETXEN_NIU_PROMISC_MODE)
+ reg = (reg | 0x2000UL);
+ else
+ reg = (reg & ~0x2000UL);
+
+ if (mode == NETXEN_NIU_ALLMULTI_MODE)
+ reg = (reg | 0x1000UL);
+ else
+ reg = (reg & ~0x1000UL);
+
+ NXWR32(adapter,
+ NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+ }
+
+ mac_cfg |= 0x4;
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg);
return 0;
}
@@ -436,7 +463,7 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
{
u32 val = 0;
u16 port = adapter->physical_port;
- u8 *addr = adapter->netdev->dev_addr;
+ u8 *addr = adapter->mac_addr;
if (adapter->mc_enabled)
return 0;
@@ -465,7 +492,7 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
{
u32 val = 0;
u16 port = adapter->physical_port;
- u8 *addr = adapter->netdev->dev_addr;
+ u8 *addr = adapter->mac_addr;
if (!adapter->mc_enabled)
return 0;
@@ -660,7 +687,7 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
list_splice_tail_init(&adapter->mac_list, &del_list);
- nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list);
+ nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list);
nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);
if (netdev->flags & IFF_PROMISC) {
@@ -1901,22 +1928,16 @@ netxen_setup_hwops(struct netxen_adapter *adapter)
int netxen_nic_get_board_info(struct netxen_adapter *adapter)
{
- int offset, board_type, magic, header_version;
+ int offset, board_type, magic;
struct pci_dev *pdev = adapter->pdev;
offset = NX_FW_MAGIC_OFFSET;
if (netxen_rom_fast_read(adapter, offset, &magic))
return -EIO;
- offset = NX_HDR_VERSION_OFFSET;
- if (netxen_rom_fast_read(adapter, offset, &header_version))
- return -EIO;
-
- if (magic != NETXEN_BDINFO_MAGIC ||
- header_version != NETXEN_BDINFO_VERSION) {
- dev_err(&pdev->dev,
- "invalid board config, magic=%08x, version=%08x\n",
- magic, header_version);
+ if (magic != NETXEN_BDINFO_MAGIC) {
+ dev_err(&pdev->dev, "invalid board config, magic=%08x\n",
+ magic);
return -EIO;
}
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 91c2bc61c8eb..8a0904368e08 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -531,6 +531,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
continue;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ if (off == (NETXEN_CRB_I2C0 + 0x1c))
+ continue;
/* do not reset PCI */
if (off == (ROMUSB_GLB + 0xbc))
continue;
@@ -542,6 +544,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
continue;
if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */
continue;
+ if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET)
+ continue;
if (off == (NETXEN_CRB_PEG_NET_1 + 0x18))
buf[i].data = 0x1020;
/* skip the function enable register */
@@ -553,12 +557,6 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
continue;
}
- if (off == NETXEN_ADDR_ERROR) {
- printk(KERN_ERR "%s: Err: Unknown addr: 0x%08x\n",
- netxen_nic_driver_name, buf[i].addr);
- continue;
- }
-
init_delay = 1;
/* After writing this register, HW needs time for CRB */
/* to quiet down (else crb_window returns 0xffffffff) */
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 9b9eab107704..3bf78dbfbf0f 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -437,6 +437,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
netdev->dev_addr[i] = *(p + 5 - i);
memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+ memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len);
/* set station address */
@@ -459,6 +460,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
netxen_napi_disable(adapter);
}
+ memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len);
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
adapter->macaddr_set(adapter, addr->sa_data);
@@ -595,7 +597,8 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
void __iomem *mem_ptr2 = NULL;
void __iomem *db_ptr = NULL;
- unsigned long mem_base, mem_len, db_base, db_len = 0, pci_len0 = 0;
+ resource_size_t mem_base, db_base;
+ unsigned long mem_len, db_len = 0, pci_len0 = 0;
struct pci_dev *pdev = adapter->pdev;
int pci_func = adapter->ahw.pci_func;
@@ -955,7 +958,7 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
return err;
}
if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
- adapter->macaddr_set(adapter, netdev->dev_addr);
+ adapter->macaddr_set(adapter, adapter->mac_addr);
adapter->set_multi(netdev);
adapter->set_mtu(adapter, netdev->mtu);
@@ -1918,6 +1921,7 @@ static void netxen_tx_timeout_task(struct work_struct *work)
request_reset:
adapter->need_fw_reset = 1;
+ clear_bit(__NX_RESETTING, &adapter->state);
}
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index f9364d0678f2..d6c7ac68f6ea 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -3545,7 +3545,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,
rp->rcr_index = index;
skb_reserve(skb, NET_IP_ALIGN);
- __pskb_pull_tail(skb, min(len, NIU_RXPULL_MAX));
+ __pskb_pull_tail(skb, min(len, VLAN_ETH_HLEN));
rp->rx_packets++;
rp->rx_bytes += skb->len;
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index ee8ad3e180dd..17a27225cc98 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -118,14 +118,6 @@ INT_MODULE_PARM(full_duplex, 0);
/* Autodetect link polarity reversal? */
INT_MODULE_PARM(auto_polarity, 1);
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"3c574_cs.c 1.65ac1 2003/04/07 Donald Becker/David Hinds, becker@scyld.com.\n";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -251,6 +243,7 @@ static void el3_tx_timeout(struct net_device *dev);
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static const struct ethtool_ops netdev_ethtool_ops;
static void set_rx_mode(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
static void tc574_detach(struct pcmcia_device *p_dev);
@@ -266,7 +259,7 @@ static const struct net_device_ops el3_netdev_ops = {
.ndo_tx_timeout = el3_tx_timeout,
.ndo_get_stats = el3_get_stats,
.ndo_do_ioctl = el3_ioctl,
- .ndo_set_multicast_list = set_rx_mode,
+ .ndo_set_multicast_list = set_multicast_list,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
@@ -277,7 +270,7 @@ static int tc574_probe(struct pcmcia_device *link)
struct el3_private *lp;
struct net_device *dev;
- DEBUG(0, "3c574_attach()\n");
+ dev_dbg(&link->dev, "3c574_attach()\n");
/* Create the PC card device object. */
dev = alloc_etherdev(sizeof(struct el3_private));
@@ -290,10 +283,8 @@ static int tc574_probe(struct pcmcia_device *link)
spin_lock_init(&lp->window_lock);
link->io.NumPorts1 = 32;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = &el3_interrupt;
- link->irq.Instance = dev;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
@@ -318,7 +309,7 @@ static void tc574_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "3c574_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "3c574_detach()\n");
if (link->dev_node)
unregister_netdev(dev);
@@ -334,26 +325,23 @@ static void tc574_detach(struct pcmcia_device *link)
ethernet device available to the system.
*/
-#define CS_CHECK(fn, ret) \
- do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
static int tc574_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
- tuple_t tuple;
- __le16 buf[32];
- int last_fn, last_ret, i, j;
+ int ret, i, j;
unsigned int ioaddr;
__be16 *phys_addr;
char *cardname;
__u32 config;
+ u8 *buf;
+ size_t len;
phys_addr = (__be16 *)dev->dev_addr;
- DEBUG(0, "3c574_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "3c574_config()\n");
link->io.IOAddrLines = 16;
for (i = j = 0; j < 0x400; j += 0x20) {
@@ -362,12 +350,16 @@ static int tc574_config(struct pcmcia_device *link)
if (i == 0)
break;
}
- if (i != 0) {
- cs_error(link, RequestIO, i);
+ if (i != 0)
+ goto failed;
+
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
@@ -377,16 +369,14 @@ static int tc574_config(struct pcmcia_device *link)
/* The 3c574 normally uses an EEPROM for configuration info, including
the hardware address. The future products may include a modem chip
and put the address in the CIS. */
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = 0x88;
- if (pcmcia_get_first_tuple(link, &tuple) == 0) {
- pcmcia_get_tuple_data(link, &tuple);
+
+ len = pcmcia_get_tuple(link, 0x88, &buf);
+ if (buf && len >= 6) {
for (i = 0; i < 3; i++)
- phys_addr[i] = htons(le16_to_cpu(buf[i]));
+ phys_addr[i] = htons(le16_to_cpu(buf[i * 2]));
+ kfree(buf);
} else {
+ kfree(buf); /* 0 < len < 6 */
EL3WINDOW(0);
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
@@ -434,7 +424,8 @@ static int tc574_config(struct pcmcia_device *link)
mii_status = mdio_read(ioaddr, phy & 0x1f, 1);
if (mii_status != 0xffff) {
lp->phys = phy & 0x1f;
- DEBUG(0, " MII transceiver at index %d, status %x.\n",
+ dev_dbg(&link->dev, " MII transceiver at "
+ "index %d, status %x.\n",
phy, mii_status);
if ((mii_status & 0x0040) == 0)
mii_preamble_required = 1;
@@ -456,7 +447,7 @@ static int tc574_config(struct pcmcia_device *link)
}
link->dev_node = &lp->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
@@ -477,8 +468,6 @@ static int tc574_config(struct pcmcia_device *link)
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
tc574_release(link);
return -ENODEV;
@@ -737,7 +726,7 @@ static int el3_open(struct net_device *dev)
lp->media.expires = jiffies + HZ;
add_timer(&lp->media);
- DEBUG(2, "%s: opened, status %4.4x.\n",
+ dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
dev->name, inw(dev->base_addr + EL3_STATUS));
return 0;
@@ -771,7 +760,7 @@ static void pop_tx_status(struct net_device *dev)
if (tx_status & 0x30)
tc574_wait_for_completion(dev, TxReset);
if (tx_status & 0x38) {
- DEBUG(1, "%s: transmit error: status 0x%02x\n",
+ pr_debug("%s: transmit error: status 0x%02x\n",
dev->name, tx_status);
outw(TxEnable, ioaddr + EL3_CMD);
dev->stats.tx_aborted_errors++;
@@ -787,7 +776,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
struct el3_private *lp = netdev_priv(dev);
unsigned long flags;
- DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
+ pr_debug("%s: el3_start_xmit(length = %ld) called, "
"status %4.4x.\n", dev->name, (long)skb->len,
inw(ioaddr + EL3_STATUS));
@@ -826,7 +815,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
return IRQ_NONE;
ioaddr = dev->base_addr;
- DEBUG(3, "%s: interrupt, status %4.4x.\n",
+ pr_debug("%s: interrupt, status %4.4x.\n",
dev->name, inw(ioaddr + EL3_STATUS));
spin_lock(&lp->window_lock);
@@ -835,7 +824,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
(IntLatch | RxComplete | RxEarly | StatsFull)) {
if (!netif_device_present(dev) ||
((status & 0xe000) != 0x2000)) {
- DEBUG(1, "%s: Interrupt from dead card\n", dev->name);
+ pr_debug("%s: Interrupt from dead card\n", dev->name);
break;
}
@@ -845,7 +834,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
work_budget = el3_rx(dev, work_budget);
if (status & TxAvailable) {
- DEBUG(3, " TX room bit was handled.\n");
+ pr_debug(" TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue(dev);
@@ -885,7 +874,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
}
if (--work_budget < 0) {
- DEBUG(0, "%s: Too much work in interrupt, "
+ pr_debug("%s: Too much work in interrupt, "
"status %4.4x.\n", dev->name, status);
/* Clear all interrupts */
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
@@ -895,7 +884,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
}
- DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
+ pr_debug("%s: exiting interrupt, status %4.4x.\n",
dev->name, inw(ioaddr + EL3_STATUS));
spin_unlock(&lp->window_lock);
@@ -1002,7 +991,7 @@ static void update_stats(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
u8 rx, tx, up;
- DEBUG(2, "%s: updating the statistics.\n", dev->name);
+ pr_debug("%s: updating the statistics.\n", dev->name);
if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */
return;
@@ -1038,7 +1027,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
unsigned int ioaddr = dev->base_addr;
short rx_status;
- DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
+ pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) &&
worklimit > 0) {
@@ -1060,7 +1049,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
skb = dev_alloc_skb(pkt_len+5);
- DEBUG(3, " Receiving packet size %d status %4.4x.\n",
+ pr_debug(" Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
if (skb != NULL) {
skb_reserve(skb, 2);
@@ -1071,7 +1060,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
} else {
- DEBUG(1, "%s: couldn't allocate a sk_buff of"
+ pr_debug("%s: couldn't allocate a sk_buff of"
" size %d.\n", dev->name, pkt_len);
dev->stats.rx_dropped++;
}
@@ -1100,7 +1089,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
struct mii_ioctl_data *data = if_mii(rq);
int phy = lp->phys & 0x1f;
- DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
+ pr_debug("%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
data->phy_id, data->reg_num, data->val_in, data->val_out);
@@ -1161,13 +1150,23 @@ static void set_rx_mode(struct net_device *dev)
outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
}
+static void set_multicast_list(struct net_device *dev)
+{
+ struct el3_private *lp = netdev_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&lp->window_lock, flags);
+ set_rx_mode(dev);
+ spin_unlock_irqrestore(&lp->window_lock, flags);
+}
+
static int el3_close(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
struct el3_private *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+ dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
if (pcmcia_dev_present(link)) {
unsigned long flags;
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 569fb06793cf..6f8d7e2e5922 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -130,14 +130,6 @@ MODULE_LICENSE("GPL");
/* Special hook for setting if_port when module is loaded */
INT_MODULE_PARM(if_port, 0);
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -189,7 +181,7 @@ static int tc589_probe(struct pcmcia_device *link)
struct el3_private *lp;
struct net_device *dev;
- DEBUG(0, "3c589_attach()\n");
+ dev_dbg(&link->dev, "3c589_attach()\n");
/* Create new ethernet device */
dev = alloc_etherdev(sizeof(struct el3_private));
@@ -202,10 +194,8 @@ static int tc589_probe(struct pcmcia_device *link)
spin_lock_init(&lp->lock);
link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = &el3_interrupt;
- link->irq.Instance = dev;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
@@ -231,7 +221,7 @@ static void tc589_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "3c589_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "3c589_detach\n");
if (link->dev_node)
unregister_netdev(dev);
@@ -249,29 +239,20 @@ static void tc589_detach(struct pcmcia_device *link)
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int tc589_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
- tuple_t tuple;
- __le16 buf[32];
__be16 *phys_addr;
- int last_fn, last_ret, i, j, multi = 0, fifo;
+ int ret, i, j, multi = 0, fifo;
unsigned int ioaddr;
char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
+ u8 *buf;
+ size_t len;
- DEBUG(0, "3c589_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "3c589_config\n");
phys_addr = (__be16 *)dev->dev_addr;
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- tuple.Attributes = TUPLE_RETURN_COMMON;
-
/* Is this a 3c562? */
if (link->manf_id != MANFID_3COM)
printk(KERN_INFO "3c589_cs: hmmm, is this really a "
@@ -287,12 +268,16 @@ static int tc589_config(struct pcmcia_device *link)
if (i == 0)
break;
}
- if (i != 0) {
- cs_error(link, RequestIO, i);
+ if (i != 0)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
@@ -301,12 +286,13 @@ static int tc589_config(struct pcmcia_device *link)
/* The 3c589 has an extra EEPROM for configuration info, including
the hardware address. The 3c562 puts the address in the CIS. */
- tuple.DesiredTuple = 0x88;
- if (pcmcia_get_first_tuple(link, &tuple) == 0) {
- pcmcia_get_tuple_data(link, &tuple);
- for (i = 0; i < 3; i++)
- phys_addr[i] = htons(le16_to_cpu(buf[i]));
+ len = pcmcia_get_tuple(link, 0x88, &buf);
+ if (buf && len >= 6) {
+ for (i = 0; i < 3; i++)
+ phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
+ kfree(buf);
} else {
+ kfree(buf); /* 0 < len < 6 */
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i));
if (phys_addr[0] == htons(0x6060)) {
@@ -328,7 +314,7 @@ static int tc589_config(struct pcmcia_device *link)
printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
link->dev_node = &lp->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
@@ -347,8 +333,6 @@ static int tc589_config(struct pcmcia_device *link)
if_names[dev->if_port]);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
tc589_release(link);
return -ENODEV;
@@ -511,24 +495,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
}
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- pc_debug = level;
-}
-#endif /* PCMCIA_DEBUG */
-
static const struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
};
static int el3_config(struct net_device *dev, struct ifmap *map)
@@ -563,7 +531,7 @@ static int el3_open(struct net_device *dev)
lp->media.expires = jiffies + HZ;
add_timer(&lp->media);
- DEBUG(1, "%s: opened, status %4.4x.\n",
+ dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
dev->name, inw(dev->base_addr + EL3_STATUS));
return 0;
@@ -596,7 +564,7 @@ static void pop_tx_status(struct net_device *dev)
if (tx_status & 0x30)
tc589_wait_for_completion(dev, TxReset);
if (tx_status & 0x38) {
- DEBUG(1, "%s: transmit error: status 0x%02x\n",
+ pr_debug("%s: transmit error: status 0x%02x\n",
dev->name, tx_status);
outw(TxEnable, ioaddr + EL3_CMD);
dev->stats.tx_aborted_errors++;
@@ -612,7 +580,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
struct el3_private *priv = netdev_priv(dev);
unsigned long flags;
- DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
+ pr_debug("%s: el3_start_xmit(length = %ld) called, "
"status %4.4x.\n", dev->name, (long)skb->len,
inw(ioaddr + EL3_STATUS));
@@ -654,14 +622,14 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
ioaddr = dev->base_addr;
- DEBUG(3, "%s: interrupt, status %4.4x.\n",
+ pr_debug("%s: interrupt, status %4.4x.\n",
dev->name, inw(ioaddr + EL3_STATUS));
spin_lock(&lp->lock);
while ((status = inw(ioaddr + EL3_STATUS)) &
(IntLatch | RxComplete | StatsFull)) {
if ((status & 0xe000) != 0x2000) {
- DEBUG(1, "%s: interrupt from dead card\n", dev->name);
+ pr_debug("%s: interrupt from dead card\n", dev->name);
handled = 0;
break;
}
@@ -670,7 +638,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
el3_rx(dev);
if (status & TxAvailable) {
- DEBUG(3, " TX room bit was handled.\n");
+ pr_debug(" TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue(dev);
@@ -722,7 +690,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
lp->last_irq = jiffies;
spin_unlock(&lp->lock);
- DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
+ pr_debug("%s: exiting interrupt, status %4.4x.\n",
dev->name, inw(ioaddr + EL3_STATUS));
return IRQ_RETVAL(handled);
}
@@ -833,7 +801,7 @@ static void update_stats(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
- DEBUG(2, "%s: updating the statistics.\n", dev->name);
+ pr_debug("%s: updating the statistics.\n", dev->name);
/* Turn off statistics updates while reading. */
outw(StatsDisable, ioaddr + EL3_CMD);
/* Switch to the stats window, and read everything. */
@@ -861,7 +829,7 @@ static int el3_rx(struct net_device *dev)
int worklimit = 32;
short rx_status;
- DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
+ pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) &&
worklimit > 0) {
@@ -883,7 +851,7 @@ static int el3_rx(struct net_device *dev)
skb = dev_alloc_skb(pkt_len+5);
- DEBUG(3, " Receiving packet size %d status %4.4x.\n",
+ pr_debug(" Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
if (skb != NULL) {
skb_reserve(skb, 2);
@@ -894,7 +862,7 @@ static int el3_rx(struct net_device *dev)
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
} else {
- DEBUG(1, "%s: couldn't allocate a sk_buff of"
+ pr_debug("%s: couldn't allocate a sk_buff of"
" size %d.\n", dev->name, pkt_len);
dev->stats.rx_dropped++;
}
@@ -935,7 +903,7 @@ static int el3_close(struct net_device *dev)
struct pcmcia_device *link = lp->p_dev;
unsigned int ioaddr = dev->base_addr;
- DEBUG(1, "%s: shutting down ethercard.\n", dev->name);
+ dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
if (pcmcia_dev_present(link)) {
/* Turn off statistics ASAP. We update dev->stats below. */
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 3131a59a8d32..800597b82d18 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -75,16 +75,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
MODULE_LICENSE("GPL");
-#ifdef PCMCIA_DEBUG
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
-
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"axnet_cs.c 1.28 2002/06/29 06:27:37 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -167,7 +157,7 @@ static int axnet_probe(struct pcmcia_device *link)
struct net_device *dev;
struct ei_device *ei_local;
- DEBUG(0, "axnet_attach()\n");
+ dev_dbg(&link->dev, "axnet_attach()\n");
dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
if (!dev)
@@ -180,7 +170,6 @@ static int axnet_probe(struct pcmcia_device *link)
info->p_dev = link;
link->priv = dev;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -205,7 +194,7 @@ static void axnet_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "axnet_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link);
if (link->dev_node)
unregister_netdev(dev);
@@ -272,9 +261,6 @@ static int get_prom(struct pcmcia_device *link)
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int try_io_port(struct pcmcia_device *link)
{
int j, ret;
@@ -341,26 +327,29 @@ static int axnet_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
axnet_dev_t *info = PRIV(dev);
- int i, j, j2, last_ret, last_fn;
+ int i, j, j2, ret;
- DEBUG(0, "axnet_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "axnet_config(0x%p)\n", link);
/* don't trust the CIS on this; Linksys got it wrong */
link->conf.Present = 0x63;
- last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
- if (last_ret != 0) {
- cs_error(link, RequestIO, last_ret);
+ ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
+ if (ret != 0)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
if (link->io.NumPorts2 == 8) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
}
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
+
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
@@ -410,7 +399,7 @@ static int axnet_config(struct pcmcia_device *link)
info->phy_id = (i < 32) ? i : -1;
link->dev_node = &info->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
@@ -426,14 +415,12 @@ static int axnet_config(struct pcmcia_device *link)
dev->base_addr, dev->irq,
dev->dev_addr);
if (info->phy_id != -1) {
- DEBUG(0, " MII transceiver at index %d, status %x.\n", info->phy_id, j);
+ dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", info->phy_id, j);
} else {
printk(KERN_NOTICE " No MII transceivers found!\n");
}
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
axnet_release(link);
return -ENODEV;
@@ -543,7 +530,7 @@ static int axnet_open(struct net_device *dev)
struct pcmcia_device *link = info->p_dev;
unsigned int nic_base = dev->base_addr;
- DEBUG(2, "axnet_open('%s')\n", dev->name);
+ dev_dbg(&link->dev, "axnet_open('%s')\n", dev->name);
if (!pcmcia_dev_present(link))
return -ENODEV;
@@ -572,7 +559,7 @@ static int axnet_close(struct net_device *dev)
axnet_dev_t *info = PRIV(dev);
struct pcmcia_device *link = info->p_dev;
- DEBUG(2, "axnet_close('%s')\n", dev->name);
+ dev_dbg(&link->dev, "axnet_close('%s')\n", dev->name);
ax_close(dev);
free_irq(dev->irq, dev);
@@ -741,10 +728,8 @@ static void block_input(struct net_device *dev, int count,
int xfer_count = count;
char *buf = skb->data;
-#ifdef PCMCIA_DEBUG
if ((ei_debug > 4) && (count != 4))
- printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
-#endif
+ pr_debug("%s: [bi=%d]\n", dev->name, count+4);
outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD);
@@ -762,10 +747,7 @@ static void block_output(struct net_device *dev, int count,
{
unsigned int nic_base = dev->base_addr;
-#ifdef PCMCIA_DEBUG
- if (ei_debug > 4)
- printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
-#endif
+ pr_debug("%s: [bo=%d]\n", dev->name, count);
/* Round the count up for word writes. Do we need to do this?
What effect will an odd byte count have on the 8390?
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index 7b5c77b7bd27..21d9c9d815d1 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -53,11 +53,7 @@
#define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
-#ifdef PCMCIA_DEBUG
-
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+#ifdef DEBUG
static void regdump(struct net_device *dev)
{
@@ -92,7 +88,6 @@ static void regdump(struct net_device *dev)
#else
-#define DEBUG(n, args...) do { } while (0)
static inline void regdump(struct net_device *dev) { }
#endif
@@ -144,7 +139,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
struct net_device *dev;
struct arcnet_local *lp;
- DEBUG(0, "com20020_attach()\n");
+ dev_dbg(&p_dev->dev, "com20020_attach()\n");
/* Create new network device */
info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
@@ -169,11 +164,10 @@ static int com20020_probe(struct pcmcia_device *p_dev)
p_dev->io.NumPorts1 = 16;
p_dev->io.IOAddrLines = 16;
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
- p_dev->irq.Instance = info->dev = dev;
+ info->dev = dev;
p_dev->priv = info;
return com20020_config(p_dev);
@@ -198,12 +192,12 @@ static void com20020_detach(struct pcmcia_device *link)
struct com20020_dev_t *info = link->priv;
struct net_device *dev = info->dev;
- DEBUG(1,"detach...\n");
+ dev_dbg(&link->dev, "detach...\n");
- DEBUG(0, "com20020_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "com20020_detach\n");
if (link->dev_node) {
- DEBUG(1,"unregister...\n");
+ dev_dbg(&link->dev, "unregister...\n");
unregister_netdev(dev);
@@ -218,16 +212,16 @@ static void com20020_detach(struct pcmcia_device *link)
com20020_release(link);
/* Unlink device structure, free bits */
- DEBUG(1,"unlinking...\n");
+ dev_dbg(&link->dev, "unlinking...\n");
if (link->priv)
{
dev = info->dev;
if (dev)
{
- DEBUG(1,"kfree...\n");
+ dev_dbg(&link->dev, "kfree...\n");
free_netdev(dev);
}
- DEBUG(1,"kfree2...\n");
+ dev_dbg(&link->dev, "kfree2...\n");
kfree(info);
}
@@ -241,25 +235,22 @@ static void com20020_detach(struct pcmcia_device *link)
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int com20020_config(struct pcmcia_device *link)
{
struct arcnet_local *lp;
com20020_dev_t *info;
struct net_device *dev;
- int i, last_ret, last_fn;
+ int i, ret;
int ioaddr;
info = link->priv;
dev = info->dev;
- DEBUG(1,"config...\n");
+ dev_dbg(&link->dev, "config...\n");
- DEBUG(0, "com20020_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "com20020_config\n");
- DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
+ dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1);
i = -ENODEV;
if (!link->io.BasePort1)
{
@@ -276,26 +267,27 @@ static int com20020_config(struct pcmcia_device *link)
if (i != 0)
{
- DEBUG(1,"arcnet: requestIO failed totally!\n");
+ dev_dbg(&link->dev, "requestIO failed totally!\n");
goto failed;
}
ioaddr = dev->base_addr = link->io.BasePort1;
- DEBUG(1,"arcnet: got ioaddr %Xh\n", ioaddr);
+ dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
- DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",
- link->irq.AssignedIRQ,
- link->irq.IRQInfo1, link->irq.IRQInfo2);
+ dev_dbg(&link->dev, "request IRQ %d\n",
+ link->irq.AssignedIRQ);
i = pcmcia_request_irq(link, &link->irq);
if (i != 0)
{
- DEBUG(1,"arcnet: requestIRQ failed totally!\n");
+ dev_dbg(&link->dev, "requestIRQ failed totally!\n");
goto failed;
}
dev->irq = link->irq.AssignedIRQ;
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
if (com20020_check(dev))
{
@@ -308,26 +300,25 @@ static int com20020_config(struct pcmcia_device *link)
lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
link->dev_node = &info->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
i = com20020_found(dev, 0); /* calls register_netdev */
if (i != 0) {
- DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
+ dev_printk(KERN_NOTICE, &link->dev,
+ "com20020_cs: com20020_found() failed\n");
link->dev_node = NULL;
goto failed;
}
strcpy(info->node.dev_name, dev->name);
- DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n",
+ dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
dev->name, dev->base_addr, dev->irq);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
- DEBUG(1,"com20020_config failed...\n");
+ dev_dbg(&link->dev, "com20020_config failed...\n");
com20020_release(link);
return -ENODEV;
} /* com20020_config */
@@ -342,7 +333,7 @@ failed:
static void com20020_release(struct pcmcia_device *link)
{
- DEBUG(0, "com20020_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "com20020_release\n");
pcmcia_disable_device(link);
}
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 7e01fbdb87e0..6e3e1ced6db4 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -72,13 +72,6 @@ MODULE_LICENSE("GPL");
/* 0:4KB*2 TX buffer else:8KB*2 TX buffer */
INT_MODULE_PARM(sram_config, 0);
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
/*
@@ -245,7 +238,7 @@ static int fmvj18x_probe(struct pcmcia_device *link)
local_info_t *lp;
struct net_device *dev;
- DEBUG(0, "fmvj18x_attach()\n");
+ dev_dbg(&link->dev, "fmvj18x_attach()\n");
/* Make up a FMVJ18x specific data structure */
dev = alloc_etherdev(sizeof(local_info_t));
@@ -262,10 +255,8 @@ static int fmvj18x_probe(struct pcmcia_device *link)
link->io.IOAddrLines = 5;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = &fjn_interrupt;
- link->irq.Instance = dev;
/* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -285,7 +276,7 @@ static void fmvj18x_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "fmvj18x_detach\n");
if (link->dev_node)
unregister_netdev(dev);
@@ -297,9 +288,6 @@ static void fmvj18x_detach(struct pcmcia_device *link)
/*====================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int mfc_try_io_port(struct pcmcia_device *link)
{
int i, ret;
@@ -341,33 +329,38 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
return ret; /* RequestIO failed */
}
+static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ return 0; /* strange, but that's what the code did already before... */
+}
+
static int fmvj18x_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
local_info_t *lp = netdev_priv(dev);
- tuple_t tuple;
- cisparse_t parse;
- u_short buf[32];
- int i, last_fn = 0, last_ret = 0, ret;
+ int i, ret;
unsigned int ioaddr;
cardtype_t cardtype;
char *card_name = "unknown";
- u_char *node_id;
+ u8 *buf;
+ size_t len;
+ u_char buggybuf[32];
+
+ dev_dbg(&link->dev, "fmvj18x_config\n");
- DEBUG(0, "fmvj18x_config(0x%p)\n", link);
+ len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+ kfree(buf);
- tuple.TupleData = (u_char *)buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_FUNCE;
- tuple.TupleOffset = 0;
- if (pcmcia_get_first_tuple(link, &tuple) == 0) {
+ if (len) {
/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
- link->conf.ConfigIndex = parse.cftable_entry.index;
+ ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
+ if (ret != 0)
+ goto failed;
+
switch (link->manf_id) {
case MANFID_TDK:
cardtype = TDK;
@@ -433,17 +426,24 @@ static int fmvj18x_config(struct pcmcia_device *link)
if (link->io.NumPorts2 != 0) {
link->irq.Attributes =
- IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
+ IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
ret = mfc_try_io_port(link);
- if (ret != 0) goto cs_failed;
+ if (ret != 0) goto failed;
} else if (cardtype == UNGERMANN) {
ret = ungermann_try_io_port(link);
- if (ret != 0) goto cs_failed;
+ if (ret != 0) goto failed;
} else {
- CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
+ ret = pcmcia_request_io(link, &link->io);
+ if (ret)
+ goto failed;
}
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
+
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
@@ -474,21 +474,21 @@ static int fmvj18x_config(struct pcmcia_device *link)
case CONTEC:
case NEC:
case KME:
- tuple.DesiredTuple = CISTPL_FUNCE;
- tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- tuple.TupleOffset = 0;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
if (cardtype == MBH10304) {
- /* MBH10304's CIS_FUNCE is corrupted */
- node_id = &(tuple.TupleData[5]);
card_name = "FMV-J182";
- } else {
- while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
- CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
+
+ len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+ if (len < 11) {
+ kfree(buf);
+ goto failed;
}
- node_id = &(tuple.TupleData[2]);
+ /* Read MACID from CIS */
+ for (i = 5; i < 11; i++)
+ dev->dev_addr[i] = buf[i];
+ kfree(buf);
+ } else {
+ if (pcmcia_get_mac_from_cis(link, dev))
+ goto failed;
if( cardtype == TDK ) {
card_name = "TDK LAK-CD021";
} else if( cardtype == LA501 ) {
@@ -501,9 +501,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
card_name = "C-NET(PC)C";
}
}
- /* Read MACID from CIS */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = node_id[i];
break;
case UNGERMANN:
/* Read MACID from register */
@@ -513,12 +510,12 @@ static int fmvj18x_config(struct pcmcia_device *link)
break;
case XXX10304:
/* Read MACID from Buggy CIS */
- if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
+ if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
goto failed;
}
for (i = 0 ; i < 6; i++) {
- dev->dev_addr[i] = tuple.TupleData[i];
+ dev->dev_addr[i] = buggybuf[i];
}
card_name = "FMV-J182";
break;
@@ -533,7 +530,7 @@ static int fmvj18x_config(struct pcmcia_device *link)
lp->cardtype = cardtype;
link->dev_node = &lp->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
@@ -551,9 +548,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
return 0;
-cs_failed:
- /* All Card Services errors end up here */
- cs_error(link, last_fn, last_ret);
failed:
fmvj18x_release(link);
return -ENODEV;
@@ -571,16 +565,14 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = 0; req.Size = 0;
req.AccessSpeed = 0;
- i = pcmcia_request_window(&link, &req, &link->win);
- if (i != 0) {
- cs_error(link, RequestWindow, i);
+ i = pcmcia_request_window(link, &req, &link->win);
+ if (i != 0)
return -1;
- }
base = ioremap(req.Base, req.Size);
mem.Page = 0;
mem.CardOffset = 0;
- pcmcia_map_mem_page(link->win, &mem);
+ pcmcia_map_mem_page(link, link->win, &mem);
/*
* MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
@@ -605,9 +597,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
}
iounmap(base);
- j = pcmcia_release_window(link->win);
- if (j != 0)
- cs_error(link, ReleaseWindow, j);
+ j = pcmcia_release_window(link, link->win);
return (i != 0x200) ? 0 : -1;
} /* fmvj18x_get_hwinfo */
@@ -626,11 +616,9 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = 0; req.Size = 0;
req.AccessSpeed = 0;
- i = pcmcia_request_window(&link, &req, &link->win);
- if (i != 0) {
- cs_error(link, RequestWindow, i);
+ i = pcmcia_request_window(link, &req, &link->win);
+ if (i != 0)
return -1;
- }
lp->base = ioremap(req.Base, req.Size);
if (lp->base == NULL) {
@@ -640,11 +628,10 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
mem.Page = 0;
mem.CardOffset = 0;
- i = pcmcia_map_mem_page(link->win, &mem);
+ i = pcmcia_map_mem_page(link, link->win, &mem);
if (i != 0) {
iounmap(lp->base);
lp->base = NULL;
- cs_error(link, MapMemPage, i);
return -1;
}
@@ -671,15 +658,13 @@ static void fmvj18x_release(struct pcmcia_device *link)
u_char __iomem *tmp;
int j;
- DEBUG(0, "fmvj18x_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "fmvj18x_release\n");
if (lp->base != NULL) {
tmp = lp->base;
lp->base = NULL; /* set NULL before iounmap */
iounmap(tmp);
- j = pcmcia_release_window(link->win);
- if (j != 0)
- cs_error(link, ReleaseWindow, j);
+ j = pcmcia_release_window(link, link->win);
}
pcmcia_disable_device(link);
@@ -788,8 +773,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
outb(tx_stat, ioaddr + TX_STATUS);
outb(rx_stat, ioaddr + RX_STATUS);
- DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
- DEBUG(4, " tx_status %02x.\n", tx_stat);
+ pr_debug("%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
+ pr_debug(" tx_status %02x.\n", tx_stat);
if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
/* there is packet(s) in rx buffer */
@@ -809,8 +794,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
}
netif_wake_queue(dev);
}
- DEBUG(4, "%s: exiting interrupt,\n", dev->name);
- DEBUG(4, " tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
+ pr_debug("%s: exiting interrupt,\n", dev->name);
+ pr_debug(" tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
outb(D_TX_INTR, ioaddr + TX_INTR);
outb(D_RX_INTR, ioaddr + RX_INTR);
@@ -882,7 +867,7 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
- DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
+ pr_debug("%s: Transmitting a packet of length %lu.\n",
dev->name, (unsigned long)skb->len);
dev->stats.tx_bytes += skb->len;
@@ -937,7 +922,7 @@ static void fjn_reset(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
int i;
- DEBUG(4, "fjn_reset(%s) called.\n",dev->name);
+ pr_debug("fjn_reset(%s) called.\n",dev->name);
/* Reset controller */
if( sram_config == 0 )
@@ -1015,13 +1000,13 @@ static void fjn_rx(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
int boguscount = 10; /* 5 -> 10: by agy 19940922 */
- DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",
+ pr_debug("%s: in rx_packet(), rx_status %02x.\n",
dev->name, inb(ioaddr + RX_STATUS));
while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
u_short status = inw(ioaddr + DATAPORT);
- DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n",
+ pr_debug("%s: Rxing packet mode %02x status %04x.\n",
dev->name, inb(ioaddr + RX_MODE), status);
#ifndef final_version
if (status == 0) {
@@ -1061,16 +1046,14 @@ static void fjn_rx(struct net_device *dev)
(pkt_len + 1) >> 1);
skb->protocol = eth_type_trans(skb, dev);
-#ifdef PCMCIA_DEBUG
- if (pc_debug > 5) {
+ {
int i;
- printk(KERN_DEBUG "%s: Rxed packet of length %d: ",
- dev->name, pkt_len);
+ pr_debug("%s: Rxed packet of length %d: ",
+ dev->name, pkt_len);
for (i = 0; i < 14; i++)
- printk(" %02x", skb->data[i]);
- printk(".\n");
+ pr_debug(" %02x", skb->data[i]);
+ pr_debug(".\n");
}
-#endif
netif_rx(skb);
dev->stats.rx_packets++;
@@ -1094,7 +1077,7 @@ static void fjn_rx(struct net_device *dev)
}
if (i > 0)
- DEBUG(5, "%s: Exint Rx packet with mode %02x after "
+ pr_debug("%s: Exint Rx packet with mode %02x after "
"%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);
}
*/
@@ -1112,24 +1095,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
}
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- pc_debug = level;
-}
-#endif /* PCMCIA_DEBUG */
-
static const struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
};
static int fjn_config(struct net_device *dev, struct ifmap *map){
@@ -1141,7 +1108,7 @@ static int fjn_open(struct net_device *dev)
struct local_info_t *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- DEBUG(4, "fjn_open('%s').\n", dev->name);
+ pr_debug("fjn_open('%s').\n", dev->name);
if (!pcmcia_dev_present(link))
return -ENODEV;
@@ -1167,7 +1134,7 @@ static int fjn_close(struct net_device *dev)
struct pcmcia_device *link = lp->p_dev;
unsigned int ioaddr = dev->base_addr;
- DEBUG(4, "fjn_close('%s').\n", dev->name);
+ pr_debug("fjn_close('%s').\n", dev->name);
lp->open_time = 0;
netif_stop_queue(dev);
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index 06618af1a468..37f4a6fdc3ef 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -69,17 +69,6 @@
#define PCMCIA
#include "../tokenring/ibmtr.c"
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"ibmtr_cs.c 1.10 1996/01/06 05:19:00 (Steve Kipisz)\n"
-" 2.2.7 1999/05/03 12:00:00 (Mike Phillips)\n"
-" 2.4.2 2001/30/28 Midnight (Burt Silverman)\n";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -130,6 +119,12 @@ static const struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
};
+static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
+ ibmtr_dev_t *info = dev_id;
+ struct net_device *dev = info->dev;
+ return tok_interrupt(irq, dev);
+};
+
/*======================================================================
ibmtr_attach() creates an "instance" of the driver, allocating
@@ -143,7 +138,7 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
ibmtr_dev_t *info;
struct net_device *dev;
- DEBUG(0, "ibmtr_attach()\n");
+ dev_dbg(&link->dev, "ibmtr_attach()\n");
/* Create new token-ring device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -161,14 +156,13 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 4;
link->io.IOAddrLines = 16;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->irq.Handler = &tok_interrupt;
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.Handler = ibmtr_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
- link->irq.Instance = info->dev = dev;
+ info->dev = dev;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
@@ -190,7 +184,7 @@ static void ibmtr_detach(struct pcmcia_device *link)
struct net_device *dev = info->dev;
struct tok_info *ti = netdev_priv(dev);
- DEBUG(0, "ibmtr_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "ibmtr_detach\n");
/*
* When the card removal interrupt hits tok_interrupt(),
@@ -217,9 +211,6 @@ static void ibmtr_detach(struct pcmcia_device *link)
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int __devinit ibmtr_config(struct pcmcia_device *link)
{
ibmtr_dev_t *info = link->priv;
@@ -227,9 +218,9 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
struct tok_info *ti = netdev_priv(dev);
win_req_t req;
memreq_t mem;
- int i, last_ret, last_fn;
+ int i, ret;
- DEBUG(0, "ibmtr_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "ibmtr_config\n");
link->conf.ConfigIndex = 0x61;
@@ -241,11 +232,15 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
if (i != 0) {
/* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
link->io.BasePort1 = 0xA24;
- CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
+ ret = pcmcia_request_io(link, &link->io);
+ if (ret)
+ goto failed;
}
dev->base_addr = link->io.BasePort1;
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
dev->irq = link->irq.AssignedIRQ;
ti->irq = link->irq.AssignedIRQ;
ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
@@ -256,11 +251,15 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
req.Base = 0;
req.Size = 0x2000;
req.AccessSpeed = 250;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+ ret = pcmcia_request_window(link, &req, &link->win);
+ if (ret)
+ goto failed;
mem.CardOffset = mmiobase;
mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+ ret = pcmcia_map_mem_page(link, link->win, &mem);
+ if (ret)
+ goto failed;
ti->mmio = ioremap(req.Base, req.Size);
/* Allocate the SRAM memory window */
@@ -269,17 +268,23 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
req.Base = 0;
req.Size = sramsize * 1024;
req.AccessSpeed = 250;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle));
+ ret = pcmcia_request_window(link, &req, &info->sram_win_handle);
+ if (ret)
+ goto failed;
mem.CardOffset = srambase;
mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
+ ret = pcmcia_map_mem_page(link, info->sram_win_handle, &mem);
+ if (ret)
+ goto failed;
ti->sram_base = mem.CardOffset >> 12;
ti->sram_virt = ioremap(req.Base, req.Size);
ti->sram_phys = req.Base;
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/* Set up the Token-Ring Controller Configuration Register and
turn on the card. Check the "Local Area Network Credit Card
@@ -287,7 +292,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
ibmtr_hw_setup(dev, mmiobase);
link->dev_node = &info->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
i = ibmtr_probe_card(dev);
if (i != 0) {
@@ -305,8 +310,6 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
dev->dev_addr);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
ibmtr_release(link);
return -ENODEV;
@@ -325,12 +328,12 @@ static void ibmtr_release(struct pcmcia_device *link)
ibmtr_dev_t *info = link->priv;
struct net_device *dev = info->dev;
- DEBUG(0, "ibmtr_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "ibmtr_release\n");
if (link->win) {
struct tok_info *ti = netdev_priv(dev);
iounmap(ti->mmio);
- pcmcia_release_window(info->sram_win_handle);
+ pcmcia_release_window(link, info->sram_win_handle);
}
pcmcia_disable_device(link);
}
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 5ed6339c52bc..dae5ef6b2609 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -381,13 +381,6 @@ typedef struct _mace_private {
Private Global Variables
---------------------------------------------------------------------------- */
-#ifdef PCMCIA_DEBUG
-static char rcsid[] =
-"nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao";
-static char *version =
-DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
-#endif
-
static const char *if_names[]={
"Auto", "10baseT", "BNC",
};
@@ -406,12 +399,6 @@ MODULE_LICENSE("GPL");
/* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
INT_MODULE_PARM(if_port, 0);
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
/* ----------------------------------------------------------------------------
Function Prototypes
@@ -462,8 +449,7 @@ static int nmclan_probe(struct pcmcia_device *link)
mace_private *lp;
struct net_device *dev;
- DEBUG(0, "nmclan_attach()\n");
- DEBUG(1, "%s\n", rcsid);
+ dev_dbg(&link->dev, "nmclan_attach()\n");
/* Create new ethernet device */
dev = alloc_etherdev(sizeof(mace_private));
@@ -477,10 +463,8 @@ static int nmclan_probe(struct pcmcia_device *link)
link->io.NumPorts1 = 32;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 5;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.Handler = &mace_interrupt;
- link->irq.Instance = dev;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
@@ -507,7 +491,7 @@ static void nmclan_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "nmclan_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "nmclan_detach\n");
if (link->dev_node)
unregister_netdev(dev);
@@ -654,37 +638,40 @@ nmclan_config
ethernet device available to the system.
---------------------------------------------------------------------------- */
-#define CS_CHECK(fn, ret) \
- do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int nmclan_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
mace_private *lp = netdev_priv(dev);
- tuple_t tuple;
- u_char buf[64];
- int i, last_ret, last_fn;
+ u8 *buf;
+ size_t len;
+ int i, ret;
unsigned int ioaddr;
- DEBUG(0, "nmclan_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "nmclan_config\n");
+
+ ret = pcmcia_request_io(link, &link->io);
+ if (ret)
+ goto failed;
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
- CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
ioaddr = dev->base_addr;
/* Read the ethernet address from the CIS. */
- tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.Attributes = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
+ len = pcmcia_get_tuple(link, 0x80, &buf);
+ if (!buf || len < ETHER_ADDR_LEN) {
+ kfree(buf);
+ goto failed;
+ }
+ memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
+ kfree(buf);
/* Verify configuration by reading the MACE ID. */
{
@@ -693,7 +680,7 @@ static int nmclan_config(struct pcmcia_device *link)
sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
- DEBUG(0, "nmclan_cs configured: mace id=%x %x\n",
+ dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
sig[0], sig[1]);
} else {
printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
@@ -712,7 +699,7 @@ static int nmclan_config(struct pcmcia_device *link)
printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
link->dev_node = &lp->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
i = register_netdev(dev);
if (i != 0) {
@@ -729,8 +716,6 @@ static int nmclan_config(struct pcmcia_device *link)
dev->dev_addr);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
nmclan_release(link);
return -ENODEV;
@@ -744,7 +729,7 @@ nmclan_release
---------------------------------------------------------------------------- */
static void nmclan_release(struct pcmcia_device *link)
{
- DEBUG(0, "nmclan_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "nmclan_release\n");
pcmcia_disable_device(link);
}
@@ -795,7 +780,7 @@ static void nmclan_reset(struct net_device *dev)
/* Reset Xilinx */
reg.Action = CS_WRITE;
reg.Offset = CISREG_COR;
- DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
+ dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
OrigCorValue);
reg.Value = COR_SOFT_RESET;
pcmcia_access_configuration_register(link, &reg);
@@ -872,7 +857,7 @@ static int mace_close(struct net_device *dev)
mace_private *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+ dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
/* Mask off all interrupts from the MACE chip. */
outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
@@ -891,24 +876,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
}
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- pc_debug = level;
-}
-#endif /* PCMCIA_DEBUG */
-
static const struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
};
/* ----------------------------------------------------------------------------
@@ -946,7 +915,7 @@ static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
netif_stop_queue(dev);
- DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n",
+ pr_debug("%s: mace_start_xmit(length = %ld) called.\n",
dev->name, (long)skb->len);
#if (!TX_INTERRUPTABLE)
@@ -1008,7 +977,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
int IntrCnt = MACE_MAX_IR_ITERATIONS;
if (dev == NULL) {
- DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n",
+ pr_debug("mace_interrupt(): irq 0x%X for unknown device.\n",
irq);
return IRQ_NONE;
}
@@ -1031,7 +1000,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
}
if (!netif_device_present(dev)) {
- DEBUG(2, "%s: interrupt from dead card\n", dev->name);
+ pr_debug("%s: interrupt from dead card\n", dev->name);
return IRQ_NONE;
}
@@ -1039,7 +1008,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
/* WARNING: MACE_IR is a READ/CLEAR port! */
status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
- DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
+ pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
if (status & MACE_IR_RCVINT) {
mace_rx(dev, MACE_MAX_RX_ITERATIONS);
@@ -1158,7 +1127,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
) {
rx_status = inw(ioaddr + AM2150_RCV);
- DEBUG(3, "%s: in mace_rx(), framecnt 0x%X, rx_status"
+ pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status"
" 0x%X.\n", dev->name, rx_framecnt, rx_status);
if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
@@ -1185,7 +1154,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
/* rcv collision count */
- DEBUG(3, " receiving packet size 0x%X rx_status"
+ pr_debug(" receiving packet size 0x%X rx_status"
" 0x%X.\n", pkt_len, rx_status);
skb = dev_alloc_skb(pkt_len+2);
@@ -1204,7 +1173,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
continue;
} else {
- DEBUG(1, "%s: couldn't allocate a sk_buff of size"
+ pr_debug("%s: couldn't allocate a sk_buff of size"
" %d.\n", dev->name, pkt_len);
lp->linux_stats.rx_dropped++;
}
@@ -1220,28 +1189,28 @@ pr_linux_stats
---------------------------------------------------------------------------- */
static void pr_linux_stats(struct net_device_stats *pstats)
{
- DEBUG(2, "pr_linux_stats\n");
- DEBUG(2, " rx_packets=%-7ld tx_packets=%ld\n",
+ pr_debug("pr_linux_stats\n");
+ pr_debug(" rx_packets=%-7ld tx_packets=%ld\n",
(long)pstats->rx_packets, (long)pstats->tx_packets);
- DEBUG(2, " rx_errors=%-7ld tx_errors=%ld\n",
+ pr_debug(" rx_errors=%-7ld tx_errors=%ld\n",
(long)pstats->rx_errors, (long)pstats->tx_errors);
- DEBUG(2, " rx_dropped=%-7ld tx_dropped=%ld\n",
+ pr_debug(" rx_dropped=%-7ld tx_dropped=%ld\n",
(long)pstats->rx_dropped, (long)pstats->tx_dropped);
- DEBUG(2, " multicast=%-7ld collisions=%ld\n",
+ pr_debug(" multicast=%-7ld collisions=%ld\n",
(long)pstats->multicast, (long)pstats->collisions);
- DEBUG(2, " rx_length_errors=%-7ld rx_over_errors=%ld\n",
+ pr_debug(" rx_length_errors=%-7ld rx_over_errors=%ld\n",
(long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
- DEBUG(2, " rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
+ pr_debug(" rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
(long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
- DEBUG(2, " rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
+ pr_debug(" rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
(long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
- DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
+ pr_debug(" tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
(long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
- DEBUG(2, " tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
+ pr_debug(" tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
(long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
- DEBUG(2, " tx_window_errors=%ld\n",
+ pr_debug(" tx_window_errors=%ld\n",
(long)pstats->tx_window_errors);
} /* pr_linux_stats */
@@ -1250,48 +1219,48 @@ pr_mace_stats
---------------------------------------------------------------------------- */
static void pr_mace_stats(mace_statistics *pstats)
{
- DEBUG(2, "pr_mace_stats\n");
+ pr_debug("pr_mace_stats\n");
- DEBUG(2, " xmtsv=%-7d uflo=%d\n",
+ pr_debug(" xmtsv=%-7d uflo=%d\n",
pstats->xmtsv, pstats->uflo);
- DEBUG(2, " lcol=%-7d more=%d\n",
+ pr_debug(" lcol=%-7d more=%d\n",
pstats->lcol, pstats->more);
- DEBUG(2, " one=%-7d defer=%d\n",
+ pr_debug(" one=%-7d defer=%d\n",
pstats->one, pstats->defer);
- DEBUG(2, " lcar=%-7d rtry=%d\n",
+ pr_debug(" lcar=%-7d rtry=%d\n",
pstats->lcar, pstats->rtry);
/* MACE_XMTRC */
- DEBUG(2, " exdef=%-7d xmtrc=%d\n",
+ pr_debug(" exdef=%-7d xmtrc=%d\n",
pstats->exdef, pstats->xmtrc);
/* RFS1--Receive Status (RCVSTS) */
- DEBUG(2, " oflo=%-7d clsn=%d\n",
+ pr_debug(" oflo=%-7d clsn=%d\n",
pstats->oflo, pstats->clsn);
- DEBUG(2, " fram=%-7d fcs=%d\n",
+ pr_debug(" fram=%-7d fcs=%d\n",
pstats->fram, pstats->fcs);
/* RFS2--Runt Packet Count (RNTPC) */
/* RFS3--Receive Collision Count (RCVCC) */
- DEBUG(2, " rfs_rntpc=%-7d rfs_rcvcc=%d\n",
+ pr_debug(" rfs_rntpc=%-7d rfs_rcvcc=%d\n",
pstats->rfs_rntpc, pstats->rfs_rcvcc);
/* MACE_IR */
- DEBUG(2, " jab=%-7d babl=%d\n",
+ pr_debug(" jab=%-7d babl=%d\n",
pstats->jab, pstats->babl);
- DEBUG(2, " cerr=%-7d rcvcco=%d\n",
+ pr_debug(" cerr=%-7d rcvcco=%d\n",
pstats->cerr, pstats->rcvcco);
- DEBUG(2, " rntpco=%-7d mpco=%d\n",
+ pr_debug(" rntpco=%-7d mpco=%d\n",
pstats->rntpco, pstats->mpco);
/* MACE_MPC */
- DEBUG(2, " mpc=%d\n", pstats->mpc);
+ pr_debug(" mpc=%d\n", pstats->mpc);
/* MACE_RNTPC */
- DEBUG(2, " rntpc=%d\n", pstats->rntpc);
+ pr_debug(" rntpc=%d\n", pstats->rntpc);
/* MACE_RCVCC */
- DEBUG(2, " rcvcc=%d\n", pstats->rcvcc);
+ pr_debug(" rcvcc=%d\n", pstats->rcvcc);
} /* pr_mace_stats */
@@ -1360,7 +1329,7 @@ static struct net_device_stats *mace_get_stats(struct net_device *dev)
update_stats(dev->base_addr, dev);
- DEBUG(1, "%s: updating the statistics.\n", dev->name);
+ pr_debug("%s: updating the statistics.\n", dev->name);
pr_linux_stats(&lp->linux_stats);
pr_mace_stats(&lp->mace_stats);
@@ -1427,7 +1396,7 @@ static void BuildLAF(int *ladrf, int *adr)
ladrf[byte] |= (1 << (hashcode & 7));
#ifdef PCMCIA_DEBUG
- if (pc_debug > 2)
+ if (0)
printk(KERN_DEBUG " adr =%pM\n", adr);
printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
for (i = 0; i < 8; i++)
@@ -1454,12 +1423,12 @@ static void restore_multicast_list(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
int i;
- DEBUG(2, "%s: restoring Rx mode to %d addresses.\n",
+ pr_debug("%s: restoring Rx mode to %d addresses.\n",
dev->name, num_addrs);
if (num_addrs > 0) {
- DEBUG(1, "Attempt to restore multicast list detected.\n");
+ pr_debug("Attempt to restore multicast list detected.\n");
mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
/* Poll ADDRCHG bit */
@@ -1511,11 +1480,11 @@ static void set_multicast_list(struct net_device *dev)
struct dev_mc_list *dmi = dev->mc_list;
#ifdef PCMCIA_DEBUG
- if (pc_debug > 1) {
+ {
static int old;
if (dev->mc_count != old) {
old = dev->mc_count;
- DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+ pr_debug("%s: setting Rx mode to %d addresses.\n",
dev->name, old);
}
}
@@ -1546,7 +1515,7 @@ static void restore_multicast_list(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
mace_private *lp = netdev_priv(dev);
- DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name,
+ pr_debug("%s: restoring Rx mode to %d addresses.\n", dev->name,
lp->multicast_num_addrs);
if (dev->flags & IFF_PROMISC) {
@@ -1567,11 +1536,11 @@ static void set_multicast_list(struct net_device *dev)
mace_private *lp = netdev_priv(dev);
#ifdef PCMCIA_DEBUG
- if (pc_debug > 1) {
+ {
static int old;
if (dev->mc_count != old) {
old = dev->mc_count;
- DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+ pr_debug("%s: setting Rx mode to %d addresses.\n",
dev->name, old);
}
}
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index bd3447f04902..cbe462ed221f 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -71,15 +71,6 @@
static const char *if_names[] = { "auto", "10baseT", "10base2"};
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -265,7 +256,7 @@ static int pcnet_probe(struct pcmcia_device *link)
pcnet_dev_t *info;
struct net_device *dev;
- DEBUG(0, "pcnet_attach()\n");
+ dev_dbg(&link->dev, "pcnet_attach()\n");
/* Create new ethernet device */
dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
@@ -275,7 +266,6 @@ static int pcnet_probe(struct pcmcia_device *link)
link->priv = dev;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -297,7 +287,7 @@ static void pcnet_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "pcnet_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "pcnet_detach\n");
if (link->dev_node)
unregister_netdev(dev);
@@ -326,17 +316,15 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = 0; req.Size = 0;
req.AccessSpeed = 0;
- i = pcmcia_request_window(&link, &req, &link->win);
- if (i != 0) {
- cs_error(link, RequestWindow, i);
+ i = pcmcia_request_window(link, &req, &link->win);
+ if (i != 0)
return NULL;
- }
virt = ioremap(req.Base, req.Size);
mem.Page = 0;
for (i = 0; i < NR_INFO; i++) {
mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
- pcmcia_map_mem_page(link->win, &mem);
+ pcmcia_map_mem_page(link, link->win, &mem);
base = &virt[hw_info[i].offset & (req.Size-1)];
if ((readb(base+0) == hw_info[i].a0) &&
(readb(base+2) == hw_info[i].a1) &&
@@ -348,9 +336,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
}
iounmap(virt);
- j = pcmcia_release_window(link->win);
- if (j != 0)
- cs_error(link, ReleaseWindow, j);
+ j = pcmcia_release_window(link, link->win);
return (i < NR_INFO) ? hw_info+i : NULL;
} /* get_hwinfo */
@@ -495,9 +481,6 @@ static hw_info_t *get_hwired(struct pcmcia_device *link)
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int try_io_port(struct pcmcia_device *link)
{
int j, ret;
@@ -567,19 +550,19 @@ static int pcnet_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
pcnet_dev_t *info = PRIV(dev);
- int last_ret, last_fn, start_pg, stop_pg, cm_offset;
+ int ret, start_pg, stop_pg, cm_offset;
int has_shmem = 0;
hw_info_t *local_hw_info;
- DEBUG(0, "pcnet_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "pcnet_config\n");
- last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
- if (last_ret) {
- cs_error(link, RequestIO, last_ret);
+ ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
+ if (ret)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
if (link->io.NumPorts2 == 8) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -589,7 +572,9 @@ static int pcnet_config(struct pcmcia_device *link)
(link->card_id == PRODID_IBM_HOME_AND_AWAY))
link->conf.ConfigIndex |= 0x10;
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
if (info->flags & HAS_MISC_REG) {
@@ -660,7 +645,7 @@ static int pcnet_config(struct pcmcia_device *link)
mii_phy_probe(dev);
link->dev_node = &info->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
@@ -687,8 +672,6 @@ static int pcnet_config(struct pcmcia_device *link)
printk(" hw_addr %pM\n", dev->dev_addr);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
pcnet_release(link);
return -ENODEV;
@@ -706,7 +689,7 @@ static void pcnet_release(struct pcmcia_device *link)
{
pcnet_dev_t *info = PRIV(link->priv);
- DEBUG(0, "pcnet_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "pcnet_release\n");
if (info->flags & USE_SHMEM)
iounmap(info->base);
@@ -960,7 +943,7 @@ static void mii_phy_probe(struct net_device *dev)
phyid = tmp << 16;
phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
phyid &= MII_PHYID_REV_MASK;
- DEBUG(0, "%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
+ pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
if (phyid == AM79C9XX_HOME_PHY) {
info->pna_phy = i;
} else if (phyid != AM79C9XX_ETH_PHY) {
@@ -976,7 +959,7 @@ static int pcnet_open(struct net_device *dev)
struct pcmcia_device *link = info->p_dev;
unsigned int nic_base = dev->base_addr;
- DEBUG(2, "pcnet_open('%s')\n", dev->name);
+ dev_dbg(&link->dev, "pcnet_open('%s')\n", dev->name);
if (!pcmcia_dev_present(link))
return -ENODEV;
@@ -1008,7 +991,7 @@ static int pcnet_close(struct net_device *dev)
pcnet_dev_t *info = PRIV(dev);
struct pcmcia_device *link = info->p_dev;
- DEBUG(2, "pcnet_close('%s')\n", dev->name);
+ dev_dbg(&link->dev, "pcnet_close('%s')\n", dev->name);
ei_close(dev);
free_irq(dev->irq, dev);
@@ -1251,10 +1234,8 @@ static void dma_block_input(struct net_device *dev, int count,
int xfer_count = count;
char *buf = skb->data;
-#ifdef PCMCIA_DEBUG
if ((ei_debug > 4) && (count != 4))
- printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
-#endif
+ pr_debug("%s: [bi=%d]\n", dev->name, count+4);
if (ei_status.dmaing) {
printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
"[DMAstat:%1x][irqlock:%1x]\n",
@@ -1495,7 +1476,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
pcnet_dev_t *info = PRIV(dev);
win_req_t req;
memreq_t mem;
- int i, window_size, offset, last_ret, last_fn;
+ int i, window_size, offset, ret;
window_size = (stop_pg - start_pg) << 8;
if (window_size > 32 * 1024)
@@ -1509,13 +1490,17 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
req.Attributes |= WIN_USE_WAIT;
req.Base = 0; req.Size = window_size;
req.AccessSpeed = mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+ ret = pcmcia_request_window(link, &req, &link->win);
+ if (ret)
+ goto failed;
mem.CardOffset = (start_pg << 8) + cm_offset;
offset = mem.CardOffset % window_size;
mem.CardOffset -= offset;
mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+ ret = pcmcia_map_mem_page(link, link->win, &mem);
+ if (ret)
+ goto failed;
/* Try scribbling on the buffer */
info->base = ioremap(req.Base, window_size);
@@ -1527,8 +1512,8 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
pcnet_reset_8390(dev);
if (i != (TX_PAGES<<8)) {
iounmap(info->base);
- pcmcia_release_window(link->win);
- info->base = NULL; link->win = NULL;
+ pcmcia_release_window(link, link->win);
+ info->base = NULL; link->win = 0;
goto failed;
}
@@ -1549,8 +1534,6 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
info->flags |= USE_SHMEM;
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
return 1;
}
@@ -1760,7 +1743,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"),
PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b),
PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0",
@@ -1788,7 +1771,6 @@ static int __init init_pcnet_cs(void)
static void __exit exit_pcnet_cs(void)
{
- DEBUG(0, "pcnet_cs: unloading\n");
pcmcia_unregister_driver(&pcnet_driver);
}
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 7bde2cd34c7e..9e0da370912e 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -79,14 +79,6 @@ MODULE_FIRMWARE(FIRMWARE_NAME);
*/
INT_MODULE_PARM(if_port, 0);
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-static const char *version =
-"smc91c92_cs.c 1.123 2006/11/09 Donald Becker, becker@scyld.com.\n";
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
#define DRV_NAME "smc91c92_cs"
#define DRV_VERSION "1.123"
@@ -126,12 +118,6 @@ struct smc_private {
int rx_ovrn;
};
-struct smc_cfg_mem {
- tuple_t tuple;
- cisparse_t parse;
- u_char buf[255];
-};
-
/* Special definitions for Megahertz multifunction cards */
#define MEGAHERTZ_ISR 0x0380
@@ -329,7 +315,7 @@ static int smc91c92_probe(struct pcmcia_device *link)
struct smc_private *smc;
struct net_device *dev;
- DEBUG(0, "smc91c92_attach()\n");
+ dev_dbg(&link->dev, "smc91c92_attach()\n");
/* Create new ethernet device */
dev = alloc_etherdev(sizeof(struct smc_private));
@@ -343,10 +329,8 @@ static int smc91c92_probe(struct pcmcia_device *link)
link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 4;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = &smc_interrupt;
- link->irq.Instance = dev;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -377,7 +361,7 @@ static void smc91c92_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "smc91c92_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "smc91c92_detach\n");
if (link->dev_node)
unregister_netdev(dev);
@@ -408,34 +392,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
return 0;
}
-/*====================================================================*/
-
-static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
- cisparse_t *parse)
-{
- int i;
-
- i = pcmcia_get_first_tuple(handle, tuple);
- if (i != 0)
- return i;
- i = pcmcia_get_tuple_data(handle, tuple);
- if (i != 0)
- return i;
- return pcmcia_parse_tuple(tuple, parse);
-}
-
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
- cisparse_t *parse)
-{
- int i;
-
- if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
- (i = pcmcia_get_tuple_data(handle, tuple)) != 0)
- return i;
- return pcmcia_parse_tuple(tuple, parse);
-}
-
-/*======================================================================
+/*====================================================================
Configuration stuff for Megahertz cards
@@ -490,19 +447,14 @@ static int mhz_mfc_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
- struct smc_cfg_mem *cfg_mem;
win_req_t req;
memreq_t mem;
int i;
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -ENOMEM;
-
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
link->irq.Attributes =
- IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
+ IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
link->io.IOAddrLines = 16;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 8;
@@ -510,91 +462,80 @@ static int mhz_mfc_config(struct pcmcia_device *link)
/* The Megahertz combo cards have modem-like CIS entries, so
we have to explicitly try a bunch of port combinations. */
if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
- goto free_cfg_mem;
+ return -ENODEV;
+
dev->base_addr = link->io.BasePort1;
/* Allocate a memory window, for accessing the ISR */
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = req.Size = 0;
req.AccessSpeed = 0;
- i = pcmcia_request_window(&link, &req, &link->win);
+ i = pcmcia_request_window(link, &req, &link->win);
if (i != 0)
- goto free_cfg_mem;
+ return -ENODEV;
+
smc->base = ioremap(req.Base, req.Size);
mem.CardOffset = mem.Page = 0;
if (smc->manfid == MANFID_MOTOROLA)
mem.CardOffset = link->conf.ConfigBase;
- i = pcmcia_map_mem_page(link->win, &mem);
+ i = pcmcia_map_mem_page(link, link->win, &mem);
if ((i == 0)
&& (smc->manfid == MANFID_MEGAHERTZ)
&& (smc->cardid == PRODID_MEGAHERTZ_EM3288))
mhz_3288_power(link);
-free_cfg_mem:
- kfree(cfg_mem);
- return -ENODEV;
+ return 0;
}
-static int mhz_setup(struct pcmcia_device *link)
+static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
{
- struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- cisparse_t *parse;
- u_char *buf, *station_addr;
- int rc;
+ struct net_device *dev = priv;
+ cisparse_t parse;
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -1;
+ if (pcmcia_parse_tuple(tuple, &parse))
+ return -EINVAL;
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- buf = cfg_mem->buf;
+ if ((parse.version_1.ns > 3) &&
+ (cvt_ascii_address(dev,
+ (parse.version_1.str + parse.version_1.ofs[3]))))
+ return 0;
- tuple->Attributes = tuple->TupleOffset = 0;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
+ return -EINVAL;
+};
+
+static int mhz_setup(struct pcmcia_device *link)
+{
+ struct net_device *dev = link->priv;
+ size_t len;
+ u8 *buf;
+ int rc;
/* Read the station address from the CIS. It is stored as the last
(fourth) string in the Version 1 Version/ID tuple. */
- tuple->DesiredTuple = CISTPL_VERS_1;
- if (first_tuple(link, tuple, parse) != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
+ if ((link->prod_id[3]) &&
+ (cvt_ascii_address(dev, link->prod_id[3]) == 0))
+ return 0;
+
+ /* Workarounds for broken cards start here. */
/* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
- if (next_tuple(link, tuple, parse) != 0)
- 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;
- }
- }
+ if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
+ return 0;
/* Another possibility: for the EM3288, in a special tuple */
- tuple->DesiredTuple = 0x81;
- if (pcmcia_get_first_tuple(link, tuple) != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- if (pcmcia_get_tuple_data(link, tuple) != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- buf[12] = '\0';
- if (cvt_ascii_address(dev, buf) == 0) {
- rc = 0;
- goto free_cfg_mem;
- }
rc = -1;
-free_cfg_mem:
- kfree(cfg_mem);
- return rc;
-}
+ len = pcmcia_get_tuple(link, 0x81, &buf);
+ if (buf && len >= 13) {
+ buf[12] = '\0';
+ if (cvt_ascii_address(dev, buf))
+ rc = 0;
+ }
+ kfree(buf);
+
+ return rc;
+};
/*======================================================================
@@ -684,58 +625,21 @@ static int smc_config(struct pcmcia_device *link)
return i;
}
+
static int smc_setup(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- cisparse_t *parse;
- cistpl_lan_node_id_t *node_id;
- u_char *buf, *station_addr;
- int i, rc;
-
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -ENOMEM;
-
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- buf = cfg_mem->buf;
-
- tuple->Attributes = tuple->TupleOffset = 0;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
/* Check for a LAN function extension tuple */
- tuple->DesiredTuple = CISTPL_FUNCE;
- i = first_tuple(link, tuple, parse);
- while (i == 0) {
- if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
- break;
- i = next_tuple(link, tuple, parse);
- }
- if (i == 0) {
- node_id = (cistpl_lan_node_id_t *)parse->funce.data;
- if (node_id->nb == 6) {
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = node_id->id[i];
- rc = 0;
- goto free_cfg_mem;
- }
- }
+ if (!pcmcia_get_mac_from_cis(link, dev))
+ return 0;
+
/* Try the third string in the Version 1 Version/ID tuple. */
if (link->prod_id[2]) {
- station_addr = link->prod_id[2];
- if (cvt_ascii_address(dev, station_addr) == 0) {
- rc = 0;
- goto free_cfg_mem;
- }
+ if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
+ return 0;
}
-
- rc = -1;
-free_cfg_mem:
- kfree(cfg_mem);
- return rc;
+ return -1;
}
/*====================================================================*/
@@ -749,7 +653,7 @@ static int osi_config(struct pcmcia_device *link)
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
link->irq.Attributes =
- IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
+ IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
link->io.NumPorts1 = 64;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 8;
@@ -794,41 +698,31 @@ static int osi_load_firmware(struct pcmcia_device *link)
return err;
}
-static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
{
- struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- u_char *buf;
- int i, rc;
+ struct net_device *dev = priv;
+ int i;
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -1;
+ if (tuple->TupleDataLen < 8)
+ return -EINVAL;
+ if (tuple->TupleData[0] != 0x04)
+ return -EINVAL;
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = tuple->TupleData[i+2];
+ return 0;
+};
- tuple = &cfg_mem->tuple;
- buf = cfg_mem->buf;
- tuple->Attributes = TUPLE_RETURN_COMMON;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
- tuple->TupleOffset = 0;
+static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+{
+ struct net_device *dev = link->priv;
+ int rc;
/* Read the station address from tuple 0x90, subtuple 0x04 */
- tuple->DesiredTuple = 0x90;
- i = pcmcia_get_first_tuple(link, tuple);
- while (i == 0) {
- i = pcmcia_get_tuple_data(link, tuple);
- if ((i != 0) || (buf[0] == 0x04))
- break;
- i = pcmcia_get_next_tuple(link, tuple);
- }
- if (i != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = buf[i+2];
+ if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
+ return -1;
if (((manfid == MANFID_OSITECH) &&
(cardid == PRODID_OSITECH_SEVEN)) ||
@@ -836,20 +730,17 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
(cardid == PRODID_PSION_NET100))) {
rc = osi_load_firmware(link);
if (rc)
- goto free_cfg_mem;
+ return rc;
} else if (manfid == MANFID_OSITECH) {
/* Make sure both functions are powered up */
set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
/* Now, turn on the interrupt for both card functions */
set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
- DEBUG(2, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
+ dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
inw(link->io.BasePort1 + OSITECH_AUI_PWR),
inw(link->io.BasePort1 + OSITECH_RESET_ISR));
}
- rc = 0;
-free_cfg_mem:
- kfree(cfg_mem);
- return rc;
+ return 0;
}
static int smc91c92_suspend(struct pcmcia_device *link)
@@ -959,12 +850,6 @@ static int check_sig(struct pcmcia_device *link)
======================================================================*/
-#define CS_EXIT_TEST(ret, svc, label) \
-if (ret != 0) { \
- cs_error(link, svc, ret); \
- goto label; \
-}
-
static int smc91c92_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
@@ -974,7 +859,7 @@ static int smc91c92_config(struct pcmcia_device *link)
unsigned int ioaddr;
u_long mir;
- DEBUG(0, "smc91c92_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "smc91c92_config\n");
smc->manfid = link->manf_id;
smc->cardid = link->card_id;
@@ -990,12 +875,15 @@ static int smc91c92_config(struct pcmcia_device *link)
} else {
i = smc_config(link);
}
- CS_EXIT_TEST(i, RequestIO, config_failed);
+ if (i)
+ goto config_failed;
i = pcmcia_request_irq(link, &link->irq);
- CS_EXIT_TEST(i, RequestIRQ, config_failed);
+ if (i)
+ goto config_failed;
i = pcmcia_request_configuration(link, &link->conf);
- CS_EXIT_TEST(i, RequestConfiguration, config_failed);
+ if (i)
+ goto config_failed;
if (smc->manfid == MANFID_MOTOROLA)
mot_config(link);
@@ -1074,7 +962,7 @@ static int smc91c92_config(struct pcmcia_device *link)
}
link->dev_node = &smc->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
@@ -1100,7 +988,7 @@ static int smc91c92_config(struct pcmcia_device *link)
if (smc->cfg & CFG_MII_SELECT) {
if (smc->mii_if.phy_id != -1) {
- DEBUG(0, " MII transceiver at index %d, status %x.\n",
+ dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n",
smc->mii_if.phy_id, j);
} else {
printk(KERN_NOTICE " No MII transceivers found!\n");
@@ -1110,7 +998,7 @@ static int smc91c92_config(struct pcmcia_device *link)
config_undo:
unregister_netdev(dev);
-config_failed: /* CS_EXIT_TEST() calls jump to here... */
+config_failed:
smc91c92_release(link);
return -ENODEV;
} /* smc91c92_config */
@@ -1125,7 +1013,7 @@ config_failed: /* CS_EXIT_TEST() calls jump to here... */
static void smc91c92_release(struct pcmcia_device *link)
{
- DEBUG(0, "smc91c92_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "smc91c92_release\n");
if (link->win) {
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
@@ -1222,10 +1110,10 @@ static int smc_open(struct net_device *dev)
struct smc_private *smc = netdev_priv(dev);
struct pcmcia_device *link = smc->p_dev;
-#ifdef PCMCIA_DEBUG
- DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
+ dev_dbg(&link->dev, "%s: smc_open(%p), ID/Window %4.4x.\n",
dev->name, dev, inw(dev->base_addr + BANK_SELECT));
- if (pc_debug > 1) smc_dump(dev);
+#ifdef PCMCIA_DEBUG
+ smc_dump(dev);
#endif
/* Check that the PCMCIA card is still here. */
@@ -1260,7 +1148,7 @@ static int smc_close(struct net_device *dev)
struct pcmcia_device *link = smc->p_dev;
unsigned int ioaddr = dev->base_addr;
- DEBUG(0, "%s: smc_close(), status %4.4x.\n",
+ dev_dbg(&link->dev, "%s: smc_close(), status %4.4x.\n",
dev->name, inw(ioaddr + BANK_SELECT));
netif_stop_queue(dev);
@@ -1327,7 +1215,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
u_char *buf = skb->data;
u_int length = skb->len; /* The chip will pad to ethernet min. */
- DEBUG(2, "%s: Trying to xmit packet of length %d.\n",
+ pr_debug("%s: Trying to xmit packet of length %d.\n",
dev->name, length);
/* send the packet length: +6 for status word, length, and ctl */
@@ -1382,7 +1270,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
netif_stop_queue(dev);
- DEBUG(2, "%s: smc_start_xmit(length = %d) called,"
+ pr_debug("%s: smc_start_xmit(length = %d) called,"
" status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
if (smc->saved_skb) {
@@ -1429,7 +1317,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
}
/* Otherwise defer until the Tx-space-allocated interrupt. */
- DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
+ pr_debug("%s: memory allocation deferred.\n", dev->name);
outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
spin_unlock_irqrestore(&smc->lock, flags);
@@ -1494,7 +1382,7 @@ static void smc_eph_irq(struct net_device *dev)
SMC_SELECT_BANK(0);
ephs = inw(ioaddr + EPH);
- DEBUG(2, "%s: Ethernet protocol handler interrupt, status"
+ pr_debug("%s: Ethernet protocol handler interrupt, status"
" %4.4x.\n", dev->name, ephs);
/* Could be a counter roll-over warning: update stats. */
card_stats = inw(ioaddr + COUNTER);
@@ -1534,7 +1422,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
ioaddr = dev->base_addr;
- DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
+ pr_debug("%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
irq, ioaddr);
spin_lock(&smc->lock);
@@ -1543,7 +1431,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
if ((saved_bank & 0xff00) != 0x3300) {
/* The device does not exist -- the card could be off-line, or
maybe it has been ejected. */
- DEBUG(1, "%s: SMC91c92 interrupt %d for non-existent"
+ pr_debug("%s: SMC91c92 interrupt %d for non-existent"
"/ejected device.\n", dev->name, irq);
handled = 0;
goto irq_done;
@@ -1557,7 +1445,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
do { /* read the status flag, and mask it */
status = inw(ioaddr + INTERRUPT) & 0xff;
- DEBUG(3, "%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
+ pr_debug("%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
status, mask);
if ((status & mask) == 0) {
if (bogus_cnt == INTR_WORK)
@@ -1602,7 +1490,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
smc_eph_irq(dev);
} while (--bogus_cnt);
- DEBUG(3, " Restoring saved registers mask %2.2x bank %4.4x"
+ pr_debug(" Restoring saved registers mask %2.2x bank %4.4x"
" pointer %4.4x.\n", mask, saved_bank, saved_pointer);
/* restore state register */
@@ -1610,7 +1498,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
outw(saved_pointer, ioaddr + POINTER);
SMC_SELECT_BANK(saved_bank);
- DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
+ pr_debug("%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
irq_done:
@@ -1661,7 +1549,7 @@ static void smc_rx(struct net_device *dev)
rx_status = inw(ioaddr + DATA_1);
packet_length = inw(ioaddr + DATA_1) & 0x07ff;
- DEBUG(2, "%s: Receive status %4.4x length %d.\n",
+ pr_debug("%s: Receive status %4.4x length %d.\n",
dev->name, rx_status, packet_length);
if (!(rx_status & RS_ERRORS)) {
@@ -1672,7 +1560,7 @@ static void smc_rx(struct net_device *dev)
skb = dev_alloc_skb(packet_length+2);
if (skb == NULL) {
- DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
+ pr_debug("%s: Low memory, packet dropped.\n", dev->name);
dev->stats.rx_dropped++;
outw(MC_RELEASE, ioaddr + MMU_CMD);
return;
@@ -1832,7 +1720,7 @@ static void smc_reset(struct net_device *dev)
struct smc_private *smc = netdev_priv(dev);
int i;
- DEBUG(0, "%s: smc91c92 reset called.\n", dev->name);
+ pr_debug("%s: smc91c92 reset called.\n", dev->name);
/* The first interaction must be a write to bring the chip out
of sleep mode. */
@@ -2149,18 +2037,6 @@ static u32 smc_get_link(struct net_device *dev)
return ret;
}
-#ifdef PCMCIA_DEBUG
-static u32 smc_get_msglevel(struct net_device *dev)
-{
- return pc_debug;
-}
-
-static void smc_set_msglevel(struct net_device *dev, u32 val)
-{
- pc_debug = val;
-}
-#endif
-
static int smc_nway_reset(struct net_device *dev)
{
struct smc_private *smc = netdev_priv(dev);
@@ -2184,10 +2060,6 @@ static const struct ethtool_ops ethtool_ops = {
.get_settings = smc_get_settings,
.set_settings = smc_set_settings,
.get_link = smc_get_link,
-#ifdef PCMCIA_DEBUG
- .get_msglevel = smc_get_msglevel,
- .set_msglevel = smc_set_msglevel,
-#endif
.nway_reset = smc_nway_reset,
};
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index cf8423102538..fe504b7f369f 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -211,20 +211,6 @@ enum xirc_cmd { /* Commands */
static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
-/****************
- * All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- * you do not define PCMCIA_DEBUG at all, all the debug code will be
- * left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- * be present but disabled -- but it can then be enabled for specific
- * modules at load time with a 'pc_debug=#' option to insmod.
- */
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KDBG_XIRC args)
-#else
-#define DEBUG(n, args...)
-#endif
#define KDBG_XIRC KERN_DEBUG "xirc2ps_cs: "
#define KERR_XIRC KERN_ERR "xirc2ps_cs: "
@@ -359,7 +345,7 @@ static void xirc_tx_timeout(struct net_device *dev);
static void xirc2ps_tx_timeout_task(struct work_struct *work);
static void set_addresses(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
-static int set_card_type(struct pcmcia_device *link, const void *s);
+static int set_card_type(struct pcmcia_device *link);
static int do_config(struct net_device *dev, struct ifmap *map);
static int do_open(struct net_device *dev);
static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -371,28 +357,6 @@ static void do_powerdown(struct net_device *dev);
static int do_stop(struct net_device *dev);
/*=============== Helper functions =========================*/
-static int
-first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
- int err;
-
- if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
- (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
- err = pcmcia_parse_tuple(tuple, parse);
- return err;
-}
-
-static int
-next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
- int err;
-
- if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
- (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
- err = pcmcia_parse_tuple(tuple, parse);
- return err;
-}
-
#define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR)
#define GetByte(reg) ((unsigned)inb(ioaddr + (reg)))
#define GetWord(reg) ((unsigned)inw(ioaddr + (reg)))
@@ -400,7 +364,7 @@ next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
#define PutWord(reg,value) outw((value), ioaddr+(reg))
/*====== Functions used for debugging =================================*/
-#if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */
+#if 0 /* reading regs may change system status */
static void
PrintRegisters(struct net_device *dev)
{
@@ -432,7 +396,7 @@ PrintRegisters(struct net_device *dev)
}
}
}
-#endif /* PCMCIA_DEBUG */
+#endif /* 0 */
/*============== MII Management functions ===============*/
@@ -576,7 +540,7 @@ xirc2ps_probe(struct pcmcia_device *link)
struct net_device *dev;
local_info_t *local;
- DEBUG(0, "attach()\n");
+ dev_dbg(&link->dev, "attach()\n");
/* Allocate the device structure */
dev = alloc_etherdev(sizeof(local_info_t));
@@ -592,7 +556,6 @@ xirc2ps_probe(struct pcmcia_device *link)
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
link->irq.Handler = xirc2ps_interrupt;
- link->irq.Instance = dev;
/* Fill in card specific entries */
dev->netdev_ops = &netdev_ops;
@@ -615,7 +578,7 @@ xirc2ps_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "detach\n");
if (link->dev_node)
unregister_netdev(dev);
@@ -644,17 +607,25 @@ xirc2ps_detach(struct pcmcia_device *link)
*
*/
static int
-set_card_type(struct pcmcia_device *link, const void *s)
+set_card_type(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
local_info_t *local = netdev_priv(dev);
- #ifdef PCMCIA_DEBUG
- unsigned cisrev = ((const unsigned char *)s)[2];
- #endif
- unsigned mediaid= ((const unsigned char *)s)[3];
- unsigned prodid = ((const unsigned char *)s)[4];
+ u8 *buf;
+ unsigned int cisrev, mediaid, prodid;
+ size_t len;
+
+ len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf);
+ if (len < 5) {
+ dev_err(&link->dev, "invalid CIS -- sorry\n");
+ return 0;
+ }
- DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n",
+ cisrev = buf[2];
+ mediaid = buf[3];
+ prodid = buf[4];
+
+ dev_dbg(&link->dev, "cisrev=%02x mediaid=%02x prodid=%02x\n",
cisrev, mediaid, prodid);
local->mohawk = 0;
@@ -761,6 +732,26 @@ xirc2ps_config_check(struct pcmcia_device *p_dev,
}
+
+static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
+{
+ struct net_device *dev = priv;
+ int i;
+
+ if (tuple->TupleDataLen != 13)
+ return -EINVAL;
+ if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
+ (tuple->TupleData[2] != 6))
+ return -EINVAL;
+ /* another try (James Lehmer's CE2 version 4.1)*/
+ for (i = 2; i < 6; i++)
+ dev->dev_addr[i] = tuple->TupleData[i+2];
+ return 0;
+};
+
+
/****************
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
* is received, to configure the PCMCIA socket, and to make the
@@ -772,33 +763,21 @@ xirc2ps_config(struct pcmcia_device * link)
struct net_device *dev = link->priv;
local_info_t *local = netdev_priv(dev);
unsigned int ioaddr;
- tuple_t tuple;
- cisparse_t parse;
- int err, i;
- u_char buf[64];
- cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
+ int err;
+ u8 *buf;
+ size_t len;
local->dingo_ccr = NULL;
- DEBUG(0, "config(0x%p)\n", link);
-
- /*
- * This reads the card's CONFIG tuple to find its configuration
- * registers.
- */
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
+ dev_dbg(&link->dev, "config\n");
/* Is this a valid card */
- tuple.DesiredTuple = CISTPL_MANFID;
- if ((err=first_tuple(link, &tuple, &parse))) {
+ if (link->has_manf_id == 0) {
printk(KNOT_XIRC "manfid not found in CIS\n");
goto failure;
}
- switch(parse.manfid.manf) {
+ switch (link->manf_id) {
case MANFID_XIRCOM:
local->manf_str = "Xircom";
break;
@@ -817,65 +796,44 @@ xirc2ps_config(struct pcmcia_device * link)
break;
default:
printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
- (unsigned)parse.manfid.manf);
+ (unsigned)link->manf_id);
goto failure;
}
- DEBUG(0, "found %s card\n", local->manf_str);
+ dev_dbg(&link->dev, "found %s card\n", local->manf_str);
- if (!set_card_type(link, buf)) {
+ if (!set_card_type(link)) {
printk(KNOT_XIRC "this card is not supported\n");
goto failure;
}
/* get the ethernet address from the CIS */
- tuple.DesiredTuple = CISTPL_FUNCE;
- for (err = first_tuple(link, &tuple, &parse); !err;
- err = next_tuple(link, &tuple, &parse)) {
- /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:
- * the first one with a length of zero the second correct -
- * so I skip all entries with length 0 */
- if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID
- && ((cistpl_lan_node_id_t *)parse.funce.data)->nb)
- break;
- }
- if (err) { /* not found: try to get the node-id from tuple 0x89 */
- tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */
- if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 &&
- (err = pcmcia_get_tuple_data(link, &tuple)) == 0) {
- if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
- memcpy(&parse, buf, 8);
- else
- err = -1;
- }
- }
- if (err) { /* another try (James Lehmer's CE2 version 4.1)*/
- tuple.DesiredTuple = CISTPL_FUNCE;
- for (err = first_tuple(link, &tuple, &parse); !err;
- err = next_tuple(link, &tuple, &parse)) {
- if (parse.funce.type == 0x02 && parse.funce.data[0] == 1
- && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
- buf[1] = 4;
- memcpy(&parse, buf+1, 8);
- break;
+ err = pcmcia_get_mac_from_cis(link, dev);
+
+ /* not found: try to get the node-id from tuple 0x89 */
+ if (err) {
+ len = pcmcia_get_tuple(link, 0x89, &buf);
+ /* data layout looks like tuple 0x22 */
+ if (buf && len == 8) {
+ if (*buf == CISTPL_FUNCE_LAN_NODE_ID) {
+ int i;
+ for (i = 2; i < 6; i++)
+ dev->dev_addr[i] = buf[i+2];
+ } else
+ err = -1;
}
- }
+ kfree(buf);
}
+
+ if (err)
+ err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
+
if (err) {
printk(KNOT_XIRC "node-id not found in CIS\n");
goto failure;
}
- node_id = (cistpl_lan_node_id_t *)parse.funce.data;
- if (node_id->nb != 6) {
- printk(KNOT_XIRC "malformed node-id in CIS\n");
- goto failure;
- }
- for (i=0; i < 6; i++)
- dev->dev_addr[i] = node_id->id[i];
link->io.IOAddrLines =10;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- link->irq.Attributes = IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
if (local->modem) {
int pass;
@@ -916,10 +874,8 @@ xirc2ps_config(struct pcmcia_device * link)
goto port_found;
}
link->io.BasePort1 = 0; /* let CS decide */
- if ((err=pcmcia_request_io(link, &link->io))) {
- cs_error(link, RequestIO, err);
+ if ((err=pcmcia_request_io(link, &link->io)))
goto config_error;
- }
}
port_found:
if (err)
@@ -929,19 +885,15 @@ xirc2ps_config(struct pcmcia_device * link)
* Now allocate an interrupt line. Note that this does not
* actually assign a handler to the interrupt.
*/
- if ((err=pcmcia_request_irq(link, &link->irq))) {
- cs_error(link, RequestIRQ, err);
+ if ((err=pcmcia_request_irq(link, &link->irq)))
goto config_error;
- }
/****************
* This actually configures the PCMCIA socket -- setting up
* the I/O windows and the interrupt mapping.
*/
- if ((err=pcmcia_request_configuration(link, &link->conf))) {
- cs_error(link, RequestConfiguration, err);
+ if ((err=pcmcia_request_configuration(link, &link->conf)))
goto config_error;
- }
if (local->dingo) {
conf_reg_t reg;
@@ -956,17 +908,13 @@ xirc2ps_config(struct pcmcia_device * link)
reg.Action = CS_WRITE;
reg.Offset = CISREG_IOBASE_0;
reg.Value = link->io.BasePort2 & 0xff;
- if ((err = pcmcia_access_configuration_register(link, &reg))) {
- cs_error(link, AccessConfigurationRegister, err);
+ if ((err = pcmcia_access_configuration_register(link, &reg)))
goto config_error;
- }
reg.Action = CS_WRITE;
reg.Offset = CISREG_IOBASE_1;
reg.Value = (link->io.BasePort2 >> 8) & 0xff;
- if ((err = pcmcia_access_configuration_register(link, &reg))) {
- cs_error(link, AccessConfigurationRegister, err);
+ if ((err = pcmcia_access_configuration_register(link, &reg)))
goto config_error;
- }
/* There is no config entry for the Ethernet part which
* is at 0x0800. So we allocate a window into the attribute
@@ -975,17 +923,14 @@ xirc2ps_config(struct pcmcia_device * link)
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = req.Size = 0;
req.AccessSpeed = 0;
- if ((err = pcmcia_request_window(&link, &req, &link->win))) {
- cs_error(link, RequestWindow, err);
+ if ((err = pcmcia_request_window(link, &req, &link->win)))
goto config_error;
- }
+
local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
mem.CardOffset = 0x0;
mem.Page = 0;
- if ((err = pcmcia_map_mem_page(link->win, &mem))) {
- cs_error(link, MapMemPage, err);
+ if ((err = pcmcia_map_mem_page(link, link->win, &mem)))
goto config_error;
- }
/* Setup the CCRs; there are no infos in the CIS about the Ethernet
* part.
@@ -1044,7 +989,7 @@ xirc2ps_config(struct pcmcia_device * link)
do_reset(dev, 1); /* a kludge to make the cem56 work */
link->dev_node = &local->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if ((err=register_netdev(dev))) {
printk(KNOT_XIRC "register_netdev() failed\n");
@@ -1077,7 +1022,7 @@ xirc2ps_config(struct pcmcia_device * link)
static void
xirc2ps_release(struct pcmcia_device *link)
{
- DEBUG(0, "release(0x%p)\n", link);
+ dev_dbg(&link->dev, "release\n");
if (link->win) {
struct net_device *dev = link->priv;
@@ -1144,7 +1089,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
PutByte(XIRCREG_CR, 0);
}
- DEBUG(6, "%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
+ pr_debug("%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
saved_page = GetByte(XIRCREG_PR);
/* Read the ISR to see whats the cause for the interrupt.
@@ -1154,7 +1099,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
bytes_rcvd = 0;
loop_entry:
if (int_status == 0xff) { /* card may be ejected */
- DEBUG(3, "%s: interrupt %d for dead card\n", dev->name, irq);
+ pr_debug("%s: interrupt %d for dead card\n", dev->name, irq);
goto leave;
}
eth_status = GetByte(XIRCREG_ESR);
@@ -1167,7 +1112,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
PutByte(XIRCREG40_TXST0, 0);
PutByte(XIRCREG40_TXST1, 0);
- DEBUG(3, "%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
+ pr_debug("%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
dev->name, int_status, eth_status, rx_status, tx_status);
/***** receive section ******/
@@ -1178,14 +1123,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
/* too many bytes received during this int, drop the rest of the
* packets */
dev->stats.rx_dropped++;
- DEBUG(2, "%s: RX drop, too much done\n", dev->name);
+ pr_debug("%s: RX drop, too much done\n", dev->name);
} else if (rsr & PktRxOk) {
struct sk_buff *skb;
pktlen = GetWord(XIRCREG0_RBC);
bytes_rcvd += pktlen;
- DEBUG(5, "rsr=%#02x packet_length=%u\n", rsr, pktlen);
+ pr_debug("rsr=%#02x packet_length=%u\n", rsr, pktlen);
skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
if (!skb) {
@@ -1253,19 +1198,19 @@ xirc2ps_interrupt(int irq, void *dev_id)
dev->stats.multicast++;
}
} else { /* bad packet */
- DEBUG(5, "rsr=%#02x\n", rsr);
+ pr_debug("rsr=%#02x\n", rsr);
}
if (rsr & PktTooLong) {
dev->stats.rx_frame_errors++;
- DEBUG(3, "%s: Packet too long\n", dev->name);
+ pr_debug("%s: Packet too long\n", dev->name);
}
if (rsr & CRCErr) {
dev->stats.rx_crc_errors++;
- DEBUG(3, "%s: CRC error\n", dev->name);
+ pr_debug("%s: CRC error\n", dev->name);
}
if (rsr & AlignErr) {
dev->stats.rx_fifo_errors++; /* okay ? */
- DEBUG(3, "%s: Alignment error\n", dev->name);
+ pr_debug("%s: Alignment error\n", dev->name);
}
/* clear the received/dropped/error packet */
@@ -1277,7 +1222,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
if (rx_status & 0x10) { /* Receive overrun */
dev->stats.rx_over_errors++;
PutByte(XIRCREG_CR, ClearRxOvrun);
- DEBUG(3, "receive overrun cleared\n");
+ pr_debug("receive overrun cleared\n");
}
/***** transmit section ******/
@@ -1290,13 +1235,13 @@ xirc2ps_interrupt(int irq, void *dev_id)
if (nn < n) /* rollover */
dev->stats.tx_packets += 256 - n;
else if (n == nn) { /* happens sometimes - don't know why */
- DEBUG(0, "PTR not changed?\n");
+ pr_debug("PTR not changed?\n");
} else
dev->stats.tx_packets += lp->last_ptr_value - n;
netif_wake_queue(dev);
}
if (tx_status & 0x0002) { /* Execessive collissions */
- DEBUG(0, "tx restarted due to execssive collissions\n");
+ pr_debug("tx restarted due to execssive collissions\n");
PutByte(XIRCREG_CR, RestartTx); /* restart transmitter process */
}
if (tx_status & 0x0040)
@@ -1315,14 +1260,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
maxrx_bytes = 2000;
else if (maxrx_bytes > 22000)
maxrx_bytes = 22000;
- DEBUG(1, "set maxrx=%u (rcvd=%u ticks=%lu)\n",
+ pr_debug("set maxrx=%u (rcvd=%u ticks=%lu)\n",
maxrx_bytes, bytes_rcvd, duration);
} else if (!duration && maxrx_bytes < 22000) {
/* now much faster */
maxrx_bytes += 2000;
if (maxrx_bytes > 22000)
maxrx_bytes = 22000;
- DEBUG(1, "set maxrx=%u\n", maxrx_bytes);
+ pr_debug("set maxrx=%u\n", maxrx_bytes);
}
}
@@ -1372,7 +1317,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned freespace;
unsigned pktlen = skb->len;
- DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n",
+ pr_debug("do_start_xmit(skb=%p, dev=%p) len=%u\n",
skb, dev, pktlen);
@@ -1398,7 +1343,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
freespace &= 0x7fff;
/* TRS doesn't work - (indeed it is eliminated with sil-rev 1) */
okay = pktlen +2 < freespace;
- DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n",
+ pr_debug("%s: avail. tx space=%u%s\n",
dev->name, freespace, okay ? " (okay)":" (not enough)");
if (!okay) { /* not enough space */
return NETDEV_TX_BUSY; /* upper layer may decide to requeue this packet */
@@ -1500,7 +1445,7 @@ do_config(struct net_device *dev, struct ifmap *map)
{
local_info_t *local = netdev_priv(dev);
- DEBUG(0, "do_config(%p)\n", dev);
+ pr_debug("do_config(%p)\n", dev);
if (map->port != 255 && map->port != dev->if_port) {
if (map->port > 4)
return -EINVAL;
@@ -1527,7 +1472,7 @@ do_open(struct net_device *dev)
local_info_t *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- DEBUG(0, "do_open(%p)\n", dev);
+ dev_dbg(&link->dev, "do_open(%p)\n", dev);
/* Check that the PCMCIA card is still here. */
/* Physical device present signature. */
@@ -1561,7 +1506,7 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
unsigned int ioaddr = dev->base_addr;
struct mii_ioctl_data *data = if_mii(rq);
- DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
+ pr_debug("%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
data->phy_id, data->reg_num, data->val_in, data->val_out);
@@ -1610,7 +1555,7 @@ do_reset(struct net_device *dev, int full)
unsigned int ioaddr = dev->base_addr;
unsigned value;
- DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
+ pr_debug("%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
hardreset(dev);
PutByte(XIRCREG_CR, SoftReset); /* set */
@@ -1648,8 +1593,8 @@ do_reset(struct net_device *dev, int full)
}
msleep(40); /* wait 40 msec to let it complete */
- #ifdef PCMCIA_DEBUG
- if (pc_debug) {
+ #if 0
+ {
SelectPage(0);
value = GetByte(XIRCREG_ESR); /* read the ESR */
printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);
@@ -1666,7 +1611,7 @@ do_reset(struct net_device *dev, int full)
value |= DisableLinkPulse;
PutByte(XIRCREG1_ECR, value);
#endif
- DEBUG(0, "%s: ECR is: %#02x\n", dev->name, value);
+ pr_debug("%s: ECR is: %#02x\n", dev->name, value);
SelectPage(0x42);
PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */
@@ -1844,7 +1789,7 @@ do_powerdown(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
- DEBUG(0, "do_powerdown(%p)\n", dev);
+ pr_debug("do_powerdown(%p)\n", dev);
SelectPage(4);
PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */
@@ -1858,7 +1803,7 @@ do_stop(struct net_device *dev)
local_info_t *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- DEBUG(0, "do_stop(%p)\n", dev);
+ dev_dbg(&link->dev, "do_stop(%p)\n", dev);
if (!link)
return -ENODEV;
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 250e10f2c35b..35897134a5dd 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -139,7 +139,7 @@ out:
return NULL;
}
-static void __devinit mdio_gpio_bus_deinit(struct device *dev)
+static void mdio_gpio_bus_deinit(struct device *dev)
{
struct mii_bus *bus = dev_get_drvdata(dev);
struct mdio_gpio_info *bitbang = bus->priv;
@@ -238,6 +238,7 @@ static struct of_device_id mdio_ofgpio_match[] = {
},
{},
};
+MODULE_DEVICE_TABLE(of, mdio_ofgpio_match);
static struct of_platform_driver mdio_ofgpio_driver = {
.name = "mdio-gpio",
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 9bf2a6be9031..965adb6174c3 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1944,8 +1944,15 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
}
/* Pull completed packets off the queue and receive them. */
- while ((skb = ppp_mp_reconstruct(ppp)))
- ppp_receive_nonmp_frame(ppp, skb);
+ while ((skb = ppp_mp_reconstruct(ppp))) {
+ if (pskb_may_pull(skb, 2))
+ ppp_receive_nonmp_frame(ppp, skb);
+ else {
+ ++ppp->dev->stats.rx_length_errors;
+ kfree_skb(skb);
+ ppp_receive_error(ppp);
+ }
+ }
return;
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 7cbf6f9b51de..2559991eea6a 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -111,9 +111,6 @@ struct pppoe_net {
rwlock_t hash_lock;
};
-/* to eliminate a race btw pppoe_flush_dev and pppoe_release */
-static DEFINE_SPINLOCK(flush_lock);
-
/*
* PPPoE could be in the following stages:
* 1) Discovery stage (to obtain remote MAC and Session ID)
@@ -303,45 +300,48 @@ static void pppoe_flush_dev(struct net_device *dev)
write_lock_bh(&pn->hash_lock);
for (i = 0; i < PPPOE_HASH_SIZE; i++) {
struct pppox_sock *po = pn->hash_table[i];
+ struct sock *sk;
- while (po != NULL) {
- struct sock *sk;
- if (po->pppoe_dev != dev) {
+ while (po) {
+ while (po && po->pppoe_dev != dev) {
po = po->next;
- continue;
}
+
+ if (!po)
+ break;
+
sk = sk_pppox(po);
- spin_lock(&flush_lock);
- po->pppoe_dev = NULL;
- spin_unlock(&flush_lock);
- dev_put(dev);
/* We always grab the socket lock, followed by the
- * hash_lock, in that order. Since we should
- * hold the sock lock while doing any unbinding,
- * we need to release the lock we're holding.
- * Hold a reference to the sock so it doesn't disappear
- * as we're jumping between locks.
+ * hash_lock, in that order. Since we should hold the
+ * sock lock while doing any unbinding, we need to
+ * release the lock we're holding. Hold a reference to
+ * the sock so it doesn't disappear as we're jumping
+ * between locks.
*/
sock_hold(sk);
-
write_unlock_bh(&pn->hash_lock);
lock_sock(sk);
- if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+ if (po->pppoe_dev == dev
+ && sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
pppox_unbind_sock(sk);
sk->sk_state = PPPOX_ZOMBIE;
sk->sk_state_change(sk);
+ po->pppoe_dev = NULL;
+ dev_put(dev);
}
release_sock(sk);
sock_put(sk);
- /* Restart scan at the beginning of this hash chain.
- * While the lock was dropped the chain contents may
- * have changed.
+ /* Restart the process from the start of the current
+ * hash chain. We dropped locks so the world may have
+ * change from underneath us.
*/
+
+ BUG_ON(pppoe_pernet(dev_net(dev)) == NULL);
write_lock_bh(&pn->hash_lock);
po = pn->hash_table[i];
}
@@ -388,11 +388,16 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
struct pppox_sock *po = pppox_sk(sk);
struct pppox_sock *relay_po;
+ /* Backlog receive. Semantics of backlog rcv preclude any code from
+ * executing in lock_sock()/release_sock() bounds; meaning sk->sk_state
+ * can't change.
+ */
+
if (sk->sk_state & PPPOX_BOUND) {
ppp_input(&po->chan, skb);
} else if (sk->sk_state & PPPOX_RELAY) {
- relay_po = get_item_by_addr(dev_net(po->pppoe_dev),
- &po->pppoe_relay);
+ relay_po = get_item_by_addr(sock_net(sk),
+ &po->pppoe_relay);
if (relay_po == NULL)
goto abort_kfree;
@@ -447,6 +452,10 @@ static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev,
goto drop;
pn = pppoe_pernet(dev_net(dev));
+
+ /* Note that get_item does a sock_hold(), so sk_pppox(po)
+ * is known to be safe.
+ */
po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
if (!po)
goto drop;
@@ -561,6 +570,7 @@ static int pppoe_release(struct socket *sock)
struct sock *sk = sock->sk;
struct pppox_sock *po;
struct pppoe_net *pn;
+ struct net *net = NULL;
if (!sk)
return 0;
@@ -571,44 +581,28 @@ static int pppoe_release(struct socket *sock)
return -EBADF;
}
+ po = pppox_sk(sk);
+
+ if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+ dev_put(po->pppoe_dev);
+ po->pppoe_dev = NULL;
+ }
+
pppox_unbind_sock(sk);
/* Signal the death of the socket. */
sk->sk_state = PPPOX_DEAD;
- /*
- * pppoe_flush_dev could lead to a race with
- * this routine so we use flush_lock to eliminate
- * such a case (we only need per-net specific data)
- */
- spin_lock(&flush_lock);
- po = pppox_sk(sk);
- if (!po->pppoe_dev) {
- spin_unlock(&flush_lock);
- goto out;
- }
- pn = pppoe_pernet(dev_net(po->pppoe_dev));
- spin_unlock(&flush_lock);
+ net = sock_net(sk);
+ pn = pppoe_pernet(net);
/*
* protect "po" from concurrent updates
* on pppoe_flush_dev
*/
- write_lock_bh(&pn->hash_lock);
+ delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote,
+ po->pppoe_ifindex);
- po = pppox_sk(sk);
- if (stage_session(po->pppoe_pa.sid))
- __delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote,
- po->pppoe_ifindex);
-
- if (po->pppoe_dev) {
- dev_put(po->pppoe_dev);
- po->pppoe_dev = NULL;
- }
-
- write_unlock_bh(&pn->hash_lock);
-
-out:
sock_orphan(sk);
sock->sk = NULL;
@@ -625,8 +619,9 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
struct sock *sk = sock->sk;
struct sockaddr_pppox *sp = (struct sockaddr_pppox *)uservaddr;
struct pppox_sock *po = pppox_sk(sk);
- struct net_device *dev;
+ struct net_device *dev = NULL;
struct pppoe_net *pn;
+ struct net *net = NULL;
int error;
lock_sock(sk);
@@ -652,12 +647,14 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
/* Delete the old binding */
if (stage_session(po->pppoe_pa.sid)) {
pppox_unbind_sock(sk);
+ pn = pppoe_pernet(sock_net(sk));
+ delete_item(pn, po->pppoe_pa.sid,
+ po->pppoe_pa.remote, po->pppoe_ifindex);
if (po->pppoe_dev) {
- pn = pppoe_pernet(dev_net(po->pppoe_dev));
- delete_item(pn, po->pppoe_pa.sid,
- po->pppoe_pa.remote, po->pppoe_ifindex);
dev_put(po->pppoe_dev);
+ po->pppoe_dev = NULL;
}
+
memset(sk_pppox(po) + 1, 0,
sizeof(struct pppox_sock) - sizeof(struct sock));
sk->sk_state = PPPOX_NONE;
@@ -666,16 +663,15 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
/* Re-bind in session stage only */
if (stage_session(sp->sa_addr.pppoe.sid)) {
error = -ENODEV;
- dev = dev_get_by_name(sock_net(sk), sp->sa_addr.pppoe.dev);
+ net = sock_net(sk);
+ dev = dev_get_by_name(net, sp->sa_addr.pppoe.dev);
if (!dev)
- goto end;
+ goto err_put;
po->pppoe_dev = dev;
po->pppoe_ifindex = dev->ifindex;
- pn = pppoe_pernet(dev_net(dev));
- write_lock_bh(&pn->hash_lock);
+ pn = pppoe_pernet(net);
if (!(dev->flags & IFF_UP)) {
- write_unlock_bh(&pn->hash_lock);
goto err_put;
}
@@ -683,6 +679,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
&sp->sa_addr.pppoe,
sizeof(struct pppoe_addr));
+ write_lock_bh(&pn->hash_lock);
error = __set_item(pn, po);
write_unlock_bh(&pn->hash_lock);
if (error < 0)
@@ -696,8 +693,11 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.ops = &pppoe_chan_ops;
error = ppp_register_net_channel(dev_net(dev), &po->chan);
- if (error)
+ if (error) {
+ delete_item(pn, po->pppoe_pa.sid,
+ po->pppoe_pa.remote, po->pppoe_ifindex);
goto err_put;
+ }
sk->sk_state = PPPOX_CONNECTED;
}
@@ -915,6 +915,14 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
struct pppoe_hdr *ph;
int data_len = skb->len;
+ /* The higher-level PPP code (ppp_unregister_channel()) ensures the PPP
+ * xmit operations conclude prior to an unregistration call. Thus
+ * sk->sk_state cannot change, so we don't need to do lock_sock().
+ * But, we also can't do a lock_sock since that introduces a potential
+ * deadlock as we'd reverse the lock ordering used when calling
+ * ppp_unregister_channel().
+ */
+
if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
goto abort;
@@ -944,7 +952,6 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
po->pppoe_pa.remote, NULL, data_len);
dev_queue_xmit(skb);
-
return 1;
abort:
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 3ec6e85587a2..c2383adcd527 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -95,6 +95,7 @@ enum {
/* Misc. stuff */
MAILBOX_COUNT = 16,
+ MAILBOX_TIMEOUT = 5,
PROC_ADDR_RDY = (1 << 31),
PROC_ADDR_R = (1 << 30),
@@ -803,6 +804,12 @@ enum {
MB_CMD_SET_PORT_CFG = 0x00000122,
MB_CMD_GET_PORT_CFG = 0x00000123,
MB_CMD_GET_LINK_STS = 0x00000124,
+ MB_CMD_SET_MGMNT_TFK_CTL = 0x00000160, /* Set Mgmnt Traffic Control */
+ MB_SET_MPI_TFK_STOP = (1 << 0),
+ MB_SET_MPI_TFK_RESUME = (1 << 1),
+ MB_CMD_GET_MGMNT_TFK_CTL = 0x00000161, /* Get Mgmnt Traffic Control */
+ MB_GET_MPI_TFK_STOPPED = (1 << 0),
+ MB_GET_MPI_TFK_FIFO_EMPTY = (1 << 1),
/* Mailbox Command Status. */
MB_CMD_STS_GOOD = 0x00004000, /* Success. */
@@ -1168,7 +1175,7 @@ struct ricb {
#define RSS_RI6 0x40
#define RSS_RT6 0x80
__le16 mask;
- __le32 hash_cq_id[256];
+ u8 hash_cq_id[1024];
__le32 ipv6_hash_key[10];
__le32 ipv4_hash_key[4];
} __attribute((packed));
@@ -1606,6 +1613,8 @@ int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
int ql_mb_about_fw(struct ql_adapter *qdev);
void ql_link_on(struct ql_adapter *qdev);
void ql_link_off(struct ql_adapter *qdev);
+int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control);
+int ql_wait_fifo_empty(struct ql_adapter *qdev);
#if 1
#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 61680715cde0..a2fc70a0d0cc 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -320,6 +320,37 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
switch (type) {
case MAC_ADDR_TYPE_MULTI_MAC:
+ {
+ u32 upper = (addr[0] << 8) | addr[1];
+ u32 lower = (addr[2] << 24) | (addr[3] << 16) |
+ (addr[4] << 8) | (addr[5]);
+
+ status =
+ ql_wait_reg_rdy(qdev,
+ MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ if (status)
+ goto exit;
+ ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
+ (index << MAC_ADDR_IDX_SHIFT) |
+ type | MAC_ADDR_E);
+ ql_write32(qdev, MAC_ADDR_DATA, lower);
+ status =
+ ql_wait_reg_rdy(qdev,
+ MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ if (status)
+ goto exit;
+ ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
+ (index << MAC_ADDR_IDX_SHIFT) |
+ type | MAC_ADDR_E);
+
+ ql_write32(qdev, MAC_ADDR_DATA, upper);
+ status =
+ ql_wait_reg_rdy(qdev,
+ MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ if (status)
+ goto exit;
+ break;
+ }
case MAC_ADDR_TYPE_CAM_MAC:
{
u32 cam_output;
@@ -365,16 +396,14 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
and possibly the function id. Right now we hardcode
the route field to NIC core.
*/
- if (type == MAC_ADDR_TYPE_CAM_MAC) {
- cam_output = (CAM_OUT_ROUTE_NIC |
- (qdev->
- func << CAM_OUT_FUNC_SHIFT) |
- (0 << CAM_OUT_CQ_ID_SHIFT));
- if (qdev->vlgrp)
- cam_output |= CAM_OUT_RV;
- /* route to NIC core */
- ql_write32(qdev, MAC_ADDR_DATA, cam_output);
- }
+ cam_output = (CAM_OUT_ROUTE_NIC |
+ (qdev->
+ func << CAM_OUT_FUNC_SHIFT) |
+ (0 << CAM_OUT_CQ_ID_SHIFT));
+ if (qdev->vlgrp)
+ cam_output |= CAM_OUT_RV;
+ /* route to NIC core */
+ ql_write32(qdev, MAC_ADDR_DATA, cam_output);
break;
}
case MAC_ADDR_TYPE_VLAN:
@@ -546,14 +575,14 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
}
case RT_IDX_MCAST: /* Pass up All Multicast frames. */
{
- value = RT_IDX_DST_CAM_Q | /* dest */
+ value = RT_IDX_DST_DFLT_Q | /* dest */
RT_IDX_TYPE_NICQ | /* type */
(RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */
break;
}
case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */
{
- value = RT_IDX_DST_CAM_Q | /* dest */
+ value = RT_IDX_DST_DFLT_Q | /* dest */
RT_IDX_TYPE_NICQ | /* type */
(RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */
break;
@@ -3077,6 +3106,12 @@ err_irq:
static int ql_start_rss(struct ql_adapter *qdev)
{
+ u8 init_hash_seed[] = {0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
+ 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f,
+ 0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b,
+ 0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80,
+ 0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b,
+ 0xbe, 0xac, 0x01, 0xfa};
struct ricb *ricb = &qdev->ricb;
int status = 0;
int i;
@@ -3086,21 +3121,17 @@ static int ql_start_rss(struct ql_adapter *qdev)
ricb->base_cq = RSS_L4K;
ricb->flags =
- (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RI4 | RSS_RI6 | RSS_RT4 |
- RSS_RT6);
- ricb->mask = cpu_to_le16(qdev->rss_ring_count - 1);
+ (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RT4 | RSS_RT6);
+ ricb->mask = cpu_to_le16((u16)(0x3ff));
/*
* Fill out the Indirection Table.
*/
- for (i = 0; i < 256; i++)
- hash_id[i] = i & (qdev->rss_ring_count - 1);
+ for (i = 0; i < 1024; i++)
+ hash_id[i] = (i & (qdev->rss_ring_count - 1));
- /*
- * Random values for the IPv6 and IPv4 Hash Keys.
- */
- get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40);
- get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16);
+ memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40);
+ memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16);
QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
@@ -3239,6 +3270,13 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP |
min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE));
+ /* Set RX packet routing to use port/pci function on which the
+ * packet arrived on in addition to usual frame routing.
+ * This is helpful on bonding where both interfaces can have
+ * the same MAC address.
+ */
+ ql_write32(qdev, RST_FO, RST_FO_RR_MASK | RST_FO_RR_RCV_FUNC_CQ);
+
/* Start up the rx queues. */
for (i = 0; i < qdev->rx_ring_count; i++) {
status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]);
@@ -3311,6 +3349,13 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
end_jiffies = jiffies +
max((unsigned long)1, usecs_to_jiffies(30));
+
+ /* Stop management traffic. */
+ ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP);
+
+ /* Wait for the NIC and MGMNT FIFOs to empty. */
+ ql_wait_fifo_empty(qdev);
+
ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
do {
@@ -3326,6 +3371,8 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
status = -ETIMEDOUT;
}
+ /* Resume management traffic. */
+ ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_RESUME);
return status;
}
@@ -3704,6 +3751,12 @@ static void ql_asic_reset_work(struct work_struct *work)
status = ql_adapter_up(qdev);
if (status)
goto error;
+
+ /* Restore rx mode. */
+ clear_bit(QL_ALLMULTI, &qdev->flags);
+ clear_bit(QL_PROMISCUOUS, &qdev->flags);
+ qlge_set_multicast_list(qdev->ndev);
+
rtnl_unlock();
return;
error:
@@ -3863,6 +3916,9 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
goto err_out;
}
+ /* Set PCIe reset type for EEH to fundamental. */
+ pdev->needs_freset = 1;
+ pci_save_state(pdev);
qdev->reg_base =
ioremap_nocache(pci_resource_start(pdev, 1),
pci_resource_len(pdev, 1));
@@ -4017,6 +4073,33 @@ static void __devexit qlge_remove(struct pci_dev *pdev)
free_netdev(ndev);
}
+/* Clean up resources without touching hardware. */
+static void ql_eeh_close(struct net_device *ndev)
+{
+ int i;
+ struct ql_adapter *qdev = netdev_priv(ndev);
+
+ if (netif_carrier_ok(ndev)) {
+ netif_carrier_off(ndev);
+ netif_stop_queue(ndev);
+ }
+
+ if (test_bit(QL_ADAPTER_UP, &qdev->flags))
+ cancel_delayed_work_sync(&qdev->asic_reset_work);
+ cancel_delayed_work_sync(&qdev->mpi_reset_work);
+ cancel_delayed_work_sync(&qdev->mpi_work);
+ cancel_delayed_work_sync(&qdev->mpi_idc_work);
+ cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+
+ for (i = 0; i < qdev->rss_ring_count; i++)
+ netif_napi_del(&qdev->rx_ring[i].napi);
+
+ clear_bit(QL_ADAPTER_UP, &qdev->flags);
+ ql_tx_ring_clean(qdev);
+ ql_free_rx_buffers(qdev);
+ ql_release_adapter_resources(qdev);
+}
+
/*
* This callback is called by the PCI subsystem whenever
* a PCI bus error is detected.
@@ -4025,17 +4108,21 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev,
enum pci_channel_state state)
{
struct net_device *ndev = pci_get_drvdata(pdev);
- struct ql_adapter *qdev = netdev_priv(ndev);
- netif_device_detach(ndev);
-
- if (state == pci_channel_io_perm_failure)
+ switch (state) {
+ case pci_channel_io_normal:
+ return PCI_ERS_RESULT_CAN_RECOVER;
+ case pci_channel_io_frozen:
+ netif_device_detach(ndev);
+ if (netif_running(ndev))
+ ql_eeh_close(ndev);
+ pci_disable_device(pdev);
+ return PCI_ERS_RESULT_NEED_RESET;
+ case pci_channel_io_perm_failure:
+ dev_err(&pdev->dev,
+ "%s: pci_channel_io_perm_failure.\n", __func__);
return PCI_ERS_RESULT_DISCONNECT;
-
- if (netif_running(ndev))
- ql_adapter_down(qdev);
-
- pci_disable_device(pdev);
+ }
/* Request a slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
@@ -4052,25 +4139,15 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev)
struct net_device *ndev = pci_get_drvdata(pdev);
struct ql_adapter *qdev = netdev_priv(ndev);
+ pdev->error_state = pci_channel_io_normal;
+
+ pci_restore_state(pdev);
if (pci_enable_device(pdev)) {
QPRINTK(qdev, IFUP, ERR,
"Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
}
-
pci_set_master(pdev);
-
- netif_carrier_off(ndev);
- ql_adapter_reset(qdev);
-
- /* Make sure the EEPROM is good */
- memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
-
- if (!is_valid_ether_addr(ndev->perm_addr)) {
- QPRINTK(qdev, IFUP, ERR, "After reset, invalid MAC address.\n");
- return PCI_ERS_RESULT_DISCONNECT;
- }
-
return PCI_ERS_RESULT_RECOVERED;
}
@@ -4078,17 +4155,21 @@ static void qlge_io_resume(struct pci_dev *pdev)
{
struct net_device *ndev = pci_get_drvdata(pdev);
struct ql_adapter *qdev = netdev_priv(ndev);
+ int err = 0;
- pci_set_master(pdev);
-
+ if (ql_adapter_reset(qdev))
+ QPRINTK(qdev, DRV, ERR, "reset FAILED!\n");
if (netif_running(ndev)) {
- if (ql_adapter_up(qdev)) {
+ err = qlge_open(ndev);
+ if (err) {
QPRINTK(qdev, IFUP, ERR,
"Device initialization failed after reset.\n");
return;
}
+ } else {
+ QPRINTK(qdev, IFUP, ERR,
+ "Device was not running prior to EEH.\n");
}
-
netif_device_attach(ndev);
}
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index c2e43073047e..aec05f266107 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -470,7 +470,8 @@ end:
*/
static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
- int status, count;
+ int status;
+ unsigned long count;
/* Begin polled mode for MPI */
@@ -491,14 +492,14 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
/* Wait for the command to complete. We loop
* here because some AEN might arrive while
* we're waiting for the mailbox command to
- * complete. If more than 5 arrive then we can
+ * complete. If more than 5 seconds expire we can
* assume something is wrong. */
- count = 5;
+ count = jiffies + HZ * MAILBOX_TIMEOUT;
do {
/* Wait for the interrupt to come in. */
status = ql_wait_mbx_cmd_cmplt(qdev);
if (status)
- goto end;
+ continue;
/* Process the event. If it's an AEN, it
* will be handled in-line or a worker
@@ -517,15 +518,15 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
MB_CMD_STS_GOOD) ||
((mbcp->mbox_out[0] & 0x0000f000) ==
MB_CMD_STS_INTRMDT))
- break;
- } while (--count);
+ goto done;
+ } while (time_before(jiffies, count));
- if (!count) {
- QPRINTK(qdev, DRV, ERR,
- "Timed out waiting for mailbox complete.\n");
- status = -ETIMEDOUT;
- goto end;
- }
+ QPRINTK(qdev, DRV, ERR,
+ "Timed out waiting for mailbox complete.\n");
+ status = -ETIMEDOUT;
+ goto end;
+
+done:
/* Now we can clear the interrupt condition
* and look at our status.
@@ -768,6 +769,95 @@ static int ql_idc_wait(struct ql_adapter *qdev)
return status;
}
+int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control)
+{
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+ int status;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 1;
+ mbcp->out_count = 2;
+
+ mbcp->mbox_in[0] = MB_CMD_SET_MGMNT_TFK_CTL;
+ mbcp->mbox_in[1] = control;
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD)
+ return status;
+
+ if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Command not supported by firmware.\n");
+ status = -EINVAL;
+ } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
+ /* This indicates that the firmware is
+ * already in the state we are trying to
+ * change it to.
+ */
+ QPRINTK(qdev, DRV, ERR,
+ "Command parameters make no change.\n");
+ }
+ return status;
+}
+
+/* Returns a negative error code or the mailbox command status. */
+static int ql_mb_get_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 *control)
+{
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+ int status;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+ *control = 0;
+
+ mbcp->in_count = 1;
+ mbcp->out_count = 1;
+
+ mbcp->mbox_in[0] = MB_CMD_GET_MGMNT_TFK_CTL;
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD) {
+ *control = mbcp->mbox_in[1];
+ return status;
+ }
+
+ if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Command not supported by firmware.\n");
+ status = -EINVAL;
+ } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed to get MPI traffic control.\n");
+ status = -EIO;
+ }
+ return status;
+}
+
+int ql_wait_fifo_empty(struct ql_adapter *qdev)
+{
+ int count = 5;
+ u32 mgmnt_fifo_empty;
+ u32 nic_fifo_empty;
+
+ do {
+ nic_fifo_empty = ql_read32(qdev, STS) & STS_NFE;
+ ql_mb_get_mgmnt_traffic_ctl(qdev, &mgmnt_fifo_empty);
+ mgmnt_fifo_empty &= MB_GET_MPI_TFK_FIFO_EMPTY;
+ if (nic_fifo_empty && mgmnt_fifo_empty)
+ return 0;
+ msleep(100);
+ } while (count-- > 0);
+ return -ETIMEDOUT;
+}
+
/* API called in work thread context to set new TX/RX
* maximum frame size values to match MTU.
*/
@@ -876,6 +966,8 @@ void ql_mpi_work(struct work_struct *work)
int err = 0;
rtnl_lock();
+ /* Begin polled mode for MPI */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
while (ql_read32(qdev, STS) & STS_PI) {
memset(mbcp, 0, sizeof(struct mbox_params));
@@ -888,6 +980,8 @@ void ql_mpi_work(struct work_struct *work)
break;
}
+ /* End polled mode for MPI */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
rtnl_unlock();
ql_enable_completion_interrupt(qdev, 0);
}
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 7dfcb58b0eb4..8b14c6eda7c3 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -1085,7 +1085,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
int bar = 0;
u16 *adrp;
- printk(KERN_INFO "%s\n", version);
+ printk("%s\n", version);
err = pci_enable_device(pdev);
if (err)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 50c6a3cfe439..0fe2fc90f207 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -115,7 +115,9 @@ enum mac_version {
RTL_GIGA_MAC_VER_22 = 0x16, // 8168C
RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP
RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP
- RTL_GIGA_MAC_VER_25 = 0x19 // 8168D
+ RTL_GIGA_MAC_VER_25 = 0x19, // 8168D
+ RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D
+ RTL_GIGA_MAC_VER_27 = 0x1b // 8168DP
};
#define _R(NAME,MAC,MASK) \
@@ -150,7 +152,9 @@ static const struct {
_R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E
_R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E
_R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E
- _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880) // PCI-E
+ _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E
+ _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E
+ _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880) // PCI-E
};
#undef _R
@@ -253,6 +257,13 @@ enum rtl8168_8101_registers {
DBG_REG = 0xd1,
#define FIX_NAK_1 (1 << 4)
#define FIX_NAK_2 (1 << 3)
+ EFUSEAR = 0xdc,
+#define EFUSEAR_FLAG 0x80000000
+#define EFUSEAR_WRITE_CMD 0x80000000
+#define EFUSEAR_READ_CMD 0x00000000
+#define EFUSEAR_REG_MASK 0x03ff
+#define EFUSEAR_REG_SHIFT 8
+#define EFUSEAR_DATA_MASK 0xff
};
enum rtl_register_content {
@@ -568,6 +579,14 @@ static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
}
+static void mdio_plus_minus(void __iomem *ioaddr, int reg_addr, int p, int m)
+{
+ int val;
+
+ val = mdio_read(ioaddr, reg_addr);
+ mdio_write(ioaddr, reg_addr, (val | p) & ~m);
+}
+
static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
int val)
{
@@ -651,6 +670,24 @@ static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
return value;
}
+static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
+{
+ u8 value = 0xff;
+ unsigned int i;
+
+ RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);
+
+ for (i = 0; i < 300; i++) {
+ if (RTL_R32(EFUSEAR) & EFUSEAR_FLAG) {
+ value = RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK;
+ break;
+ }
+ udelay(100);
+ }
+
+ return value;
+}
+
static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
{
RTL_W16(IntrMask, 0x0000);
@@ -992,7 +1029,10 @@ static void rtl8169_vlan_rx_register(struct net_device *dev,
spin_lock_irqsave(&tp->lock, flags);
tp->vlgrp = grp;
- if (tp->vlgrp)
+ /*
+ * Do not disable RxVlan on 8110SCd.
+ */
+ if (tp->vlgrp || (tp->mac_version == RTL_GIGA_MAC_VER_05))
tp->cp_cmd |= RxVlan;
else
tp->cp_cmd &= ~RxVlan;
@@ -1243,7 +1283,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
int mac_version;
} mac_info[] = {
/* 8168D family. */
- { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_25 },
+ { 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 },
+ { 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 },
+ { 0x7c800000, 0x28800000, RTL_GIGA_MAC_VER_27 },
+ { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 },
/* 8168C family. */
{ 0x7cf00000, 0x3ca00000, RTL_GIGA_MAC_VER_24 },
@@ -1648,74 +1691,903 @@ static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr)
rtl8168c_3_hw_phy_config(ioaddr);
}
-static void rtl8168d_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
{
- struct phy_reg phy_reg_init_0[] = {
+ static struct phy_reg phy_reg_init_0[] = {
{ 0x1f, 0x0001 },
- { 0x09, 0x2770 },
- { 0x08, 0x04d0 },
- { 0x0b, 0xad15 },
- { 0x0c, 0x5bf0 },
- { 0x1c, 0xf101 },
+ { 0x06, 0x4064 },
+ { 0x07, 0x2863 },
+ { 0x08, 0x059c },
+ { 0x09, 0x26b4 },
+ { 0x0a, 0x6a19 },
+ { 0x0b, 0xdcc8 },
+ { 0x10, 0xf06d },
+ { 0x14, 0x7f68 },
+ { 0x18, 0x7fd9 },
+ { 0x1c, 0xf0ff },
+ { 0x1d, 0x3d9c },
{ 0x1f, 0x0003 },
- { 0x14, 0x94d7 },
- { 0x12, 0xf4d6 },
- { 0x09, 0xca0f },
- { 0x1f, 0x0002 },
- { 0x0b, 0x0b10 },
- { 0x0c, 0xd1f7 },
- { 0x1f, 0x0002 },
- { 0x06, 0x5461 },
+ { 0x12, 0xf49f },
+ { 0x13, 0x070b },
+ { 0x1a, 0x05ad },
+ { 0x14, 0x94c0 }
+ };
+ static struct phy_reg phy_reg_init_1[] = {
{ 0x1f, 0x0002 },
- { 0x05, 0x6662 },
+ { 0x06, 0x5561 },
+ { 0x1f, 0x0005 },
+ { 0x05, 0x8332 },
+ { 0x06, 0x5561 }
+ };
+ static struct phy_reg phy_reg_init_2[] = {
+ { 0x1f, 0x0005 },
+ { 0x05, 0xffc2 },
+ { 0x1f, 0x0005 },
+ { 0x05, 0x8000 },
+ { 0x06, 0xf8f9 },
+ { 0x06, 0xfaef },
+ { 0x06, 0x59ee },
+ { 0x06, 0xf8ea },
+ { 0x06, 0x00ee },
+ { 0x06, 0xf8eb },
+ { 0x06, 0x00e0 },
+ { 0x06, 0xf87c },
+ { 0x06, 0xe1f8 },
+ { 0x06, 0x7d59 },
+ { 0x06, 0x0fef },
+ { 0x06, 0x0139 },
+ { 0x06, 0x029e },
+ { 0x06, 0x06ef },
+ { 0x06, 0x1039 },
+ { 0x06, 0x089f },
+ { 0x06, 0x2aee },
+ { 0x06, 0xf8ea },
+ { 0x06, 0x00ee },
+ { 0x06, 0xf8eb },
+ { 0x06, 0x01e0 },
+ { 0x06, 0xf87c },
+ { 0x06, 0xe1f8 },
+ { 0x06, 0x7d58 },
+ { 0x06, 0x409e },
+ { 0x06, 0x0f39 },
+ { 0x06, 0x46aa },
+ { 0x06, 0x0bbf },
+ { 0x06, 0x8290 },
+ { 0x06, 0xd682 },
+ { 0x06, 0x9802 },
+ { 0x06, 0x014f },
+ { 0x06, 0xae09 },
+ { 0x06, 0xbf82 },
+ { 0x06, 0x98d6 },
+ { 0x06, 0x82a0 },
+ { 0x06, 0x0201 },
+ { 0x06, 0x4fef },
+ { 0x06, 0x95fe },
+ { 0x06, 0xfdfc },
+ { 0x06, 0x05f8 },
+ { 0x06, 0xf9fa },
+ { 0x06, 0xeef8 },
+ { 0x06, 0xea00 },
+ { 0x06, 0xeef8 },
+ { 0x06, 0xeb00 },
+ { 0x06, 0xe2f8 },
+ { 0x06, 0x7ce3 },
+ { 0x06, 0xf87d },
+ { 0x06, 0xa511 },
+ { 0x06, 0x1112 },
+ { 0x06, 0xd240 },
+ { 0x06, 0xd644 },
+ { 0x06, 0x4402 },
+ { 0x06, 0x8217 },
+ { 0x06, 0xd2a0 },
+ { 0x06, 0xd6aa },
+ { 0x06, 0xaa02 },
+ { 0x06, 0x8217 },
+ { 0x06, 0xae0f },
+ { 0x06, 0xa544 },
+ { 0x06, 0x4402 },
+ { 0x06, 0xae4d },
+ { 0x06, 0xa5aa },
+ { 0x06, 0xaa02 },
+ { 0x06, 0xae47 },
+ { 0x06, 0xaf82 },
+ { 0x06, 0x13ee },
+ { 0x06, 0x834e },
+ { 0x06, 0x00ee },
+ { 0x06, 0x834d },
+ { 0x06, 0x0fee },
+ { 0x06, 0x834c },
+ { 0x06, 0x0fee },
+ { 0x06, 0x834f },
+ { 0x06, 0x00ee },
+ { 0x06, 0x8351 },
+ { 0x06, 0x00ee },
+ { 0x06, 0x834a },
+ { 0x06, 0xffee },
+ { 0x06, 0x834b },
+ { 0x06, 0xffe0 },
+ { 0x06, 0x8330 },
+ { 0x06, 0xe183 },
+ { 0x06, 0x3158 },
+ { 0x06, 0xfee4 },
+ { 0x06, 0xf88a },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0x8be0 },
+ { 0x06, 0x8332 },
+ { 0x06, 0xe183 },
+ { 0x06, 0x3359 },
+ { 0x06, 0x0fe2 },
+ { 0x06, 0x834d },
+ { 0x06, 0x0c24 },
+ { 0x06, 0x5af0 },
+ { 0x06, 0x1e12 },
+ { 0x06, 0xe4f8 },
+ { 0x06, 0x8ce5 },
+ { 0x06, 0xf88d },
+ { 0x06, 0xaf82 },
+ { 0x06, 0x13e0 },
+ { 0x06, 0x834f },
+ { 0x06, 0x10e4 },
+ { 0x06, 0x834f },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4e78 },
+ { 0x06, 0x009f },
+ { 0x06, 0x0ae0 },
+ { 0x06, 0x834f },
+ { 0x06, 0xa010 },
+ { 0x06, 0xa5ee },
+ { 0x06, 0x834e },
+ { 0x06, 0x01e0 },
+ { 0x06, 0x834e },
+ { 0x06, 0x7805 },
+ { 0x06, 0x9e9a },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4e78 },
+ { 0x06, 0x049e },
+ { 0x06, 0x10e0 },
+ { 0x06, 0x834e },
+ { 0x06, 0x7803 },
+ { 0x06, 0x9e0f },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4e78 },
+ { 0x06, 0x019e },
+ { 0x06, 0x05ae },
+ { 0x06, 0x0caf },
+ { 0x06, 0x81f8 },
+ { 0x06, 0xaf81 },
+ { 0x06, 0xa3af },
+ { 0x06, 0x81dc },
+ { 0x06, 0xaf82 },
+ { 0x06, 0x13ee },
+ { 0x06, 0x8348 },
+ { 0x06, 0x00ee },
+ { 0x06, 0x8349 },
+ { 0x06, 0x00e0 },
+ { 0x06, 0x8351 },
+ { 0x06, 0x10e4 },
+ { 0x06, 0x8351 },
+ { 0x06, 0x5801 },
+ { 0x06, 0x9fea },
+ { 0x06, 0xd000 },
+ { 0x06, 0xd180 },
+ { 0x06, 0x1f66 },
+ { 0x06, 0xe2f8 },
+ { 0x06, 0xeae3 },
+ { 0x06, 0xf8eb },
+ { 0x06, 0x5af8 },
+ { 0x06, 0x1e20 },
+ { 0x06, 0xe6f8 },
+ { 0x06, 0xeae5 },
+ { 0x06, 0xf8eb },
+ { 0x06, 0xd302 },
+ { 0x06, 0xb3fe },
+ { 0x06, 0xe2f8 },
+ { 0x06, 0x7cef },
+ { 0x06, 0x325b },
+ { 0x06, 0x80e3 },
+ { 0x06, 0xf87d },
+ { 0x06, 0x9e03 },
+ { 0x06, 0x7dff },
+ { 0x06, 0xff0d },
+ { 0x06, 0x581c },
+ { 0x06, 0x551a },
+ { 0x06, 0x6511 },
+ { 0x06, 0xa190 },
+ { 0x06, 0xd3e2 },
+ { 0x06, 0x8348 },
+ { 0x06, 0xe383 },
+ { 0x06, 0x491b },
+ { 0x06, 0x56ab },
+ { 0x06, 0x08ef },
+ { 0x06, 0x56e6 },
+ { 0x06, 0x8348 },
+ { 0x06, 0xe783 },
+ { 0x06, 0x4910 },
+ { 0x06, 0xd180 },
+ { 0x06, 0x1f66 },
+ { 0x06, 0xa004 },
+ { 0x06, 0xb9e2 },
+ { 0x06, 0x8348 },
+ { 0x06, 0xe383 },
+ { 0x06, 0x49ef },
+ { 0x06, 0x65e2 },
+ { 0x06, 0x834a },
+ { 0x06, 0xe383 },
+ { 0x06, 0x4b1b },
+ { 0x06, 0x56aa },
+ { 0x06, 0x0eef },
+ { 0x06, 0x56e6 },
+ { 0x06, 0x834a },
+ { 0x06, 0xe783 },
+ { 0x06, 0x4be2 },
+ { 0x06, 0x834d },
+ { 0x06, 0xe683 },
+ { 0x06, 0x4ce0 },
+ { 0x06, 0x834d },
+ { 0x06, 0xa000 },
+ { 0x06, 0x0caf },
+ { 0x06, 0x81dc },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4d10 },
+ { 0x06, 0xe483 },
+ { 0x06, 0x4dae },
+ { 0x06, 0x0480 },
+ { 0x06, 0xe483 },
+ { 0x06, 0x4de0 },
+ { 0x06, 0x834e },
+ { 0x06, 0x7803 },
+ { 0x06, 0x9e0b },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4e78 },
+ { 0x06, 0x049e },
+ { 0x06, 0x04ee },
+ { 0x06, 0x834e },
+ { 0x06, 0x02e0 },
+ { 0x06, 0x8332 },
+ { 0x06, 0xe183 },
+ { 0x06, 0x3359 },
+ { 0x06, 0x0fe2 },
+ { 0x06, 0x834d },
+ { 0x06, 0x0c24 },
+ { 0x06, 0x5af0 },
+ { 0x06, 0x1e12 },
+ { 0x06, 0xe4f8 },
+ { 0x06, 0x8ce5 },
+ { 0x06, 0xf88d },
+ { 0x06, 0xe083 },
+ { 0x06, 0x30e1 },
+ { 0x06, 0x8331 },
+ { 0x06, 0x6801 },
+ { 0x06, 0xe4f8 },
+ { 0x06, 0x8ae5 },
+ { 0x06, 0xf88b },
+ { 0x06, 0xae37 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4e03 },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4ce1 },
+ { 0x06, 0x834d },
+ { 0x06, 0x1b01 },
+ { 0x06, 0x9e04 },
+ { 0x06, 0xaaa1 },
+ { 0x06, 0xaea8 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4e04 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4f00 },
+ { 0x06, 0xaeab },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4f78 },
+ { 0x06, 0x039f },
+ { 0x06, 0x14ee },
+ { 0x06, 0x834e },
+ { 0x06, 0x05d2 },
+ { 0x06, 0x40d6 },
+ { 0x06, 0x5554 },
+ { 0x06, 0x0282 },
+ { 0x06, 0x17d2 },
+ { 0x06, 0xa0d6 },
+ { 0x06, 0xba00 },
+ { 0x06, 0x0282 },
+ { 0x06, 0x17fe },
+ { 0x06, 0xfdfc },
+ { 0x06, 0x05f8 },
+ { 0x06, 0xe0f8 },
+ { 0x06, 0x60e1 },
+ { 0x06, 0xf861 },
+ { 0x06, 0x6802 },
+ { 0x06, 0xe4f8 },
+ { 0x06, 0x60e5 },
+ { 0x06, 0xf861 },
+ { 0x06, 0xe0f8 },
+ { 0x06, 0x48e1 },
+ { 0x06, 0xf849 },
+ { 0x06, 0x580f },
+ { 0x06, 0x1e02 },
+ { 0x06, 0xe4f8 },
+ { 0x06, 0x48e5 },
+ { 0x06, 0xf849 },
+ { 0x06, 0xd000 },
+ { 0x06, 0x0282 },
+ { 0x06, 0x5bbf },
+ { 0x06, 0x8350 },
+ { 0x06, 0xef46 },
+ { 0x06, 0xdc19 },
+ { 0x06, 0xddd0 },
+ { 0x06, 0x0102 },
+ { 0x06, 0x825b },
+ { 0x06, 0x0282 },
+ { 0x06, 0x77e0 },
+ { 0x06, 0xf860 },
+ { 0x06, 0xe1f8 },
+ { 0x06, 0x6158 },
+ { 0x06, 0xfde4 },
+ { 0x06, 0xf860 },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0x61fc },
+ { 0x06, 0x04f9 },
+ { 0x06, 0xfafb },
+ { 0x06, 0xc6bf },
+ { 0x06, 0xf840 },
+ { 0x06, 0xbe83 },
+ { 0x06, 0x50a0 },
+ { 0x06, 0x0101 },
+ { 0x06, 0x071b },
+ { 0x06, 0x89cf },
+ { 0x06, 0xd208 },
+ { 0x06, 0xebdb },
+ { 0x06, 0x19b2 },
+ { 0x06, 0xfbff },
+ { 0x06, 0xfefd },
+ { 0x06, 0x04f8 },
+ { 0x06, 0xe0f8 },
+ { 0x06, 0x48e1 },
+ { 0x06, 0xf849 },
+ { 0x06, 0x6808 },
+ { 0x06, 0xe4f8 },
+ { 0x06, 0x48e5 },
+ { 0x06, 0xf849 },
+ { 0x06, 0x58f7 },
+ { 0x06, 0xe4f8 },
+ { 0x06, 0x48e5 },
+ { 0x06, 0xf849 },
+ { 0x06, 0xfc04 },
+ { 0x06, 0x4d20 },
+ { 0x06, 0x0002 },
+ { 0x06, 0x4e22 },
+ { 0x06, 0x0002 },
+ { 0x06, 0x4ddf },
+ { 0x06, 0xff01 },
+ { 0x06, 0x4edd },
+ { 0x06, 0xff01 },
+ { 0x05, 0x83d4 },
+ { 0x06, 0x8000 },
+ { 0x05, 0x83d8 },
+ { 0x06, 0x8051 },
+ { 0x02, 0x6010 },
+ { 0x03, 0xdc00 },
+ { 0x05, 0xfff6 },
+ { 0x06, 0x00fc },
{ 0x1f, 0x0000 },
- { 0x14, 0x0060 },
+
{ 0x1f, 0x0000 },
- { 0x0d, 0xf8a0 },
+ { 0x0d, 0xf880 },
+ { 0x1f, 0x0000 }
+ };
+
+ rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
+
+ mdio_write(ioaddr, 0x1f, 0x0002);
+ mdio_plus_minus(ioaddr, 0x0b, 0x0010, 0x00ef);
+ mdio_plus_minus(ioaddr, 0x0c, 0xa200, 0x5d00);
+
+ rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
+
+ if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
+ struct phy_reg phy_reg_init[] = {
+ { 0x1f, 0x0002 },
+ { 0x05, 0x669a },
+ { 0x1f, 0x0005 },
+ { 0x05, 0x8330 },
+ { 0x06, 0x669a },
+ { 0x1f, 0x0002 }
+ };
+ int val;
+
+ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+
+ val = mdio_read(ioaddr, 0x0d);
+
+ if ((val & 0x00ff) != 0x006c) {
+ u32 set[] = {
+ 0x0065, 0x0066, 0x0067, 0x0068,
+ 0x0069, 0x006a, 0x006b, 0x006c
+ };
+ int i;
+
+ mdio_write(ioaddr, 0x1f, 0x0002);
+
+ val &= 0xff00;
+ for (i = 0; i < ARRAY_SIZE(set); i++)
+ mdio_write(ioaddr, 0x0d, val | set[i]);
+ }
+ } else {
+ struct phy_reg phy_reg_init[] = {
+ { 0x1f, 0x0002 },
+ { 0x05, 0x6662 },
+ { 0x1f, 0x0005 },
+ { 0x05, 0x8330 },
+ { 0x06, 0x6662 }
+ };
+
+ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ }
+
+ mdio_write(ioaddr, 0x1f, 0x0002);
+ mdio_patch(ioaddr, 0x0d, 0x0300);
+ mdio_patch(ioaddr, 0x0f, 0x0010);
+
+ mdio_write(ioaddr, 0x1f, 0x0002);
+ mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
+ mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
+
+ rtl_phy_write(ioaddr, phy_reg_init_2, ARRAY_SIZE(phy_reg_init_2));
+}
+
+static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
+{
+ static struct phy_reg phy_reg_init_0[] = {
+ { 0x1f, 0x0001 },
+ { 0x06, 0x4064 },
+ { 0x07, 0x2863 },
+ { 0x08, 0x059c },
+ { 0x09, 0x26b4 },
+ { 0x0a, 0x6a19 },
+ { 0x0b, 0xdcc8 },
+ { 0x10, 0xf06d },
+ { 0x14, 0x7f68 },
+ { 0x18, 0x7fd9 },
+ { 0x1c, 0xf0ff },
+ { 0x1d, 0x3d9c },
+ { 0x1f, 0x0003 },
+ { 0x12, 0xf49f },
+ { 0x13, 0x070b },
+ { 0x1a, 0x05ad },
+ { 0x14, 0x94c0 },
+
+ { 0x1f, 0x0002 },
+ { 0x06, 0x5561 },
{ 0x1f, 0x0005 },
- { 0x05, 0xffc2 }
+ { 0x05, 0x8332 },
+ { 0x06, 0x5561 }
+ };
+ static struct phy_reg phy_reg_init_1[] = {
+ { 0x1f, 0x0005 },
+ { 0x05, 0xffc2 },
+ { 0x1f, 0x0005 },
+ { 0x05, 0x8000 },
+ { 0x06, 0xf8f9 },
+ { 0x06, 0xfaee },
+ { 0x06, 0xf8ea },
+ { 0x06, 0x00ee },
+ { 0x06, 0xf8eb },
+ { 0x06, 0x00e2 },
+ { 0x06, 0xf87c },
+ { 0x06, 0xe3f8 },
+ { 0x06, 0x7da5 },
+ { 0x06, 0x1111 },
+ { 0x06, 0x12d2 },
+ { 0x06, 0x40d6 },
+ { 0x06, 0x4444 },
+ { 0x06, 0x0281 },
+ { 0x06, 0xc6d2 },
+ { 0x06, 0xa0d6 },
+ { 0x06, 0xaaaa },
+ { 0x06, 0x0281 },
+ { 0x06, 0xc6ae },
+ { 0x06, 0x0fa5 },
+ { 0x06, 0x4444 },
+ { 0x06, 0x02ae },
+ { 0x06, 0x4da5 },
+ { 0x06, 0xaaaa },
+ { 0x06, 0x02ae },
+ { 0x06, 0x47af },
+ { 0x06, 0x81c2 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4e00 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4d0f },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4c0f },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4f00 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x5100 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4aff },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4bff },
+ { 0x06, 0xe083 },
+ { 0x06, 0x30e1 },
+ { 0x06, 0x8331 },
+ { 0x06, 0x58fe },
+ { 0x06, 0xe4f8 },
+ { 0x06, 0x8ae5 },
+ { 0x06, 0xf88b },
+ { 0x06, 0xe083 },
+ { 0x06, 0x32e1 },
+ { 0x06, 0x8333 },
+ { 0x06, 0x590f },
+ { 0x06, 0xe283 },
+ { 0x06, 0x4d0c },
+ { 0x06, 0x245a },
+ { 0x06, 0xf01e },
+ { 0x06, 0x12e4 },
+ { 0x06, 0xf88c },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0x8daf },
+ { 0x06, 0x81c2 },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4f10 },
+ { 0x06, 0xe483 },
+ { 0x06, 0x4fe0 },
+ { 0x06, 0x834e },
+ { 0x06, 0x7800 },
+ { 0x06, 0x9f0a },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4fa0 },
+ { 0x06, 0x10a5 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4e01 },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4e78 },
+ { 0x06, 0x059e },
+ { 0x06, 0x9ae0 },
+ { 0x06, 0x834e },
+ { 0x06, 0x7804 },
+ { 0x06, 0x9e10 },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4e78 },
+ { 0x06, 0x039e },
+ { 0x06, 0x0fe0 },
+ { 0x06, 0x834e },
+ { 0x06, 0x7801 },
+ { 0x06, 0x9e05 },
+ { 0x06, 0xae0c },
+ { 0x06, 0xaf81 },
+ { 0x06, 0xa7af },
+ { 0x06, 0x8152 },
+ { 0x06, 0xaf81 },
+ { 0x06, 0x8baf },
+ { 0x06, 0x81c2 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4800 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4900 },
+ { 0x06, 0xe083 },
+ { 0x06, 0x5110 },
+ { 0x06, 0xe483 },
+ { 0x06, 0x5158 },
+ { 0x06, 0x019f },
+ { 0x06, 0xead0 },
+ { 0x06, 0x00d1 },
+ { 0x06, 0x801f },
+ { 0x06, 0x66e2 },
+ { 0x06, 0xf8ea },
+ { 0x06, 0xe3f8 },
+ { 0x06, 0xeb5a },
+ { 0x06, 0xf81e },
+ { 0x06, 0x20e6 },
+ { 0x06, 0xf8ea },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0xebd3 },
+ { 0x06, 0x02b3 },
+ { 0x06, 0xfee2 },
+ { 0x06, 0xf87c },
+ { 0x06, 0xef32 },
+ { 0x06, 0x5b80 },
+ { 0x06, 0xe3f8 },
+ { 0x06, 0x7d9e },
+ { 0x06, 0x037d },
+ { 0x06, 0xffff },
+ { 0x06, 0x0d58 },
+ { 0x06, 0x1c55 },
+ { 0x06, 0x1a65 },
+ { 0x06, 0x11a1 },
+ { 0x06, 0x90d3 },
+ { 0x06, 0xe283 },
+ { 0x06, 0x48e3 },
+ { 0x06, 0x8349 },
+ { 0x06, 0x1b56 },
+ { 0x06, 0xab08 },
+ { 0x06, 0xef56 },
+ { 0x06, 0xe683 },
+ { 0x06, 0x48e7 },
+ { 0x06, 0x8349 },
+ { 0x06, 0x10d1 },
+ { 0x06, 0x801f },
+ { 0x06, 0x66a0 },
+ { 0x06, 0x04b9 },
+ { 0x06, 0xe283 },
+ { 0x06, 0x48e3 },
+ { 0x06, 0x8349 },
+ { 0x06, 0xef65 },
+ { 0x06, 0xe283 },
+ { 0x06, 0x4ae3 },
+ { 0x06, 0x834b },
+ { 0x06, 0x1b56 },
+ { 0x06, 0xaa0e },
+ { 0x06, 0xef56 },
+ { 0x06, 0xe683 },
+ { 0x06, 0x4ae7 },
+ { 0x06, 0x834b },
+ { 0x06, 0xe283 },
+ { 0x06, 0x4de6 },
+ { 0x06, 0x834c },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4da0 },
+ { 0x06, 0x000c },
+ { 0x06, 0xaf81 },
+ { 0x06, 0x8be0 },
+ { 0x06, 0x834d },
+ { 0x06, 0x10e4 },
+ { 0x06, 0x834d },
+ { 0x06, 0xae04 },
+ { 0x06, 0x80e4 },
+ { 0x06, 0x834d },
+ { 0x06, 0xe083 },
+ { 0x06, 0x4e78 },
+ { 0x06, 0x039e },
+ { 0x06, 0x0be0 },
+ { 0x06, 0x834e },
+ { 0x06, 0x7804 },
+ { 0x06, 0x9e04 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4e02 },
+ { 0x06, 0xe083 },
+ { 0x06, 0x32e1 },
+ { 0x06, 0x8333 },
+ { 0x06, 0x590f },
+ { 0x06, 0xe283 },
+ { 0x06, 0x4d0c },
+ { 0x06, 0x245a },
+ { 0x06, 0xf01e },
+ { 0x06, 0x12e4 },
+ { 0x06, 0xf88c },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0x8de0 },
+ { 0x06, 0x8330 },
+ { 0x06, 0xe183 },
+ { 0x06, 0x3168 },
+ { 0x06, 0x01e4 },
+ { 0x06, 0xf88a },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0x8bae },
+ { 0x06, 0x37ee },
+ { 0x06, 0x834e },
+ { 0x06, 0x03e0 },
+ { 0x06, 0x834c },
+ { 0x06, 0xe183 },
+ { 0x06, 0x4d1b },
+ { 0x06, 0x019e },
+ { 0x06, 0x04aa },
+ { 0x06, 0xa1ae },
+ { 0x06, 0xa8ee },
+ { 0x06, 0x834e },
+ { 0x06, 0x04ee },
+ { 0x06, 0x834f },
+ { 0x06, 0x00ae },
+ { 0x06, 0xabe0 },
+ { 0x06, 0x834f },
+ { 0x06, 0x7803 },
+ { 0x06, 0x9f14 },
+ { 0x06, 0xee83 },
+ { 0x06, 0x4e05 },
+ { 0x06, 0xd240 },
+ { 0x06, 0xd655 },
+ { 0x06, 0x5402 },
+ { 0x06, 0x81c6 },
+ { 0x06, 0xd2a0 },
+ { 0x06, 0xd6ba },
+ { 0x06, 0x0002 },
+ { 0x06, 0x81c6 },
+ { 0x06, 0xfefd },
+ { 0x06, 0xfc05 },
+ { 0x06, 0xf8e0 },
+ { 0x06, 0xf860 },
+ { 0x06, 0xe1f8 },
+ { 0x06, 0x6168 },
+ { 0x06, 0x02e4 },
+ { 0x06, 0xf860 },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0x61e0 },
+ { 0x06, 0xf848 },
+ { 0x06, 0xe1f8 },
+ { 0x06, 0x4958 },
+ { 0x06, 0x0f1e },
+ { 0x06, 0x02e4 },
+ { 0x06, 0xf848 },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0x49d0 },
+ { 0x06, 0x0002 },
+ { 0x06, 0x820a },
+ { 0x06, 0xbf83 },
+ { 0x06, 0x50ef },
+ { 0x06, 0x46dc },
+ { 0x06, 0x19dd },
+ { 0x06, 0xd001 },
+ { 0x06, 0x0282 },
+ { 0x06, 0x0a02 },
+ { 0x06, 0x8226 },
+ { 0x06, 0xe0f8 },
+ { 0x06, 0x60e1 },
+ { 0x06, 0xf861 },
+ { 0x06, 0x58fd },
+ { 0x06, 0xe4f8 },
+ { 0x06, 0x60e5 },
+ { 0x06, 0xf861 },
+ { 0x06, 0xfc04 },
+ { 0x06, 0xf9fa },
+ { 0x06, 0xfbc6 },
+ { 0x06, 0xbff8 },
+ { 0x06, 0x40be },
+ { 0x06, 0x8350 },
+ { 0x06, 0xa001 },
+ { 0x06, 0x0107 },
+ { 0x06, 0x1b89 },
+ { 0x06, 0xcfd2 },
+ { 0x06, 0x08eb },
+ { 0x06, 0xdb19 },
+ { 0x06, 0xb2fb },
+ { 0x06, 0xfffe },
+ { 0x06, 0xfd04 },
+ { 0x06, 0xf8e0 },
+ { 0x06, 0xf848 },
+ { 0x06, 0xe1f8 },
+ { 0x06, 0x4968 },
+ { 0x06, 0x08e4 },
+ { 0x06, 0xf848 },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0x4958 },
+ { 0x06, 0xf7e4 },
+ { 0x06, 0xf848 },
+ { 0x06, 0xe5f8 },
+ { 0x06, 0x49fc },
+ { 0x06, 0x044d },
+ { 0x06, 0x2000 },
+ { 0x06, 0x024e },
+ { 0x06, 0x2200 },
+ { 0x06, 0x024d },
+ { 0x06, 0xdfff },
+ { 0x06, 0x014e },
+ { 0x06, 0xddff },
+ { 0x06, 0x0100 },
+ { 0x05, 0x83d8 },
+ { 0x06, 0x8000 },
+ { 0x03, 0xdc00 },
+ { 0x05, 0xfff6 },
+ { 0x06, 0x00fc },
+ { 0x1f, 0x0000 },
+
+ { 0x1f, 0x0000 },
+ { 0x0d, 0xf880 },
+ { 0x1f, 0x0000 }
};
rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
- if (mdio_read(ioaddr, 0x06) == 0xc400) {
- struct phy_reg phy_reg_init_1[] = {
+ if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
+ struct phy_reg phy_reg_init[] = {
+ { 0x1f, 0x0002 },
+ { 0x05, 0x669a },
{ 0x1f, 0x0005 },
- { 0x01, 0x0300 },
- { 0x1f, 0x0000 },
- { 0x11, 0x401c },
- { 0x16, 0x4100 },
+ { 0x05, 0x8330 },
+ { 0x06, 0x669a },
+
+ { 0x1f, 0x0002 }
+ };
+ int val;
+
+ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+
+ val = mdio_read(ioaddr, 0x0d);
+ if ((val & 0x00ff) != 0x006c) {
+ u32 set[] = {
+ 0x0065, 0x0066, 0x0067, 0x0068,
+ 0x0069, 0x006a, 0x006b, 0x006c
+ };
+ int i;
+
+ mdio_write(ioaddr, 0x1f, 0x0002);
+
+ val &= 0xff00;
+ for (i = 0; i < ARRAY_SIZE(set); i++)
+ mdio_write(ioaddr, 0x0d, val | set[i]);
+ }
+ } else {
+ struct phy_reg phy_reg_init[] = {
+ { 0x1f, 0x0002 },
+ { 0x05, 0x2642 },
{ 0x1f, 0x0005 },
- { 0x07, 0x0010 },
- { 0x05, 0x83dc },
- { 0x06, 0x087d },
- { 0x05, 0x8300 },
- { 0x06, 0x0101 },
- { 0x06, 0x05f8 },
- { 0x06, 0xf9fa },
- { 0x06, 0xfbef },
- { 0x06, 0x79e2 },
- { 0x06, 0x835f },
- { 0x06, 0xe0f8 },
- { 0x06, 0x9ae1 },
- { 0x06, 0xf89b },
- { 0x06, 0xef31 },
- { 0x06, 0x3b65 },
- { 0x06, 0xaa07 },
- { 0x06, 0x81e4 },
- { 0x06, 0xf89a },
- { 0x06, 0xe5f8 },
- { 0x06, 0x9baf },
- { 0x06, 0x06ae },
- { 0x05, 0x83dc },
- { 0x06, 0x8300 },
+ { 0x05, 0x8330 },
+ { 0x06, 0x2642 }
};
- rtl_phy_write(ioaddr, phy_reg_init_1,
- ARRAY_SIZE(phy_reg_init_1));
+ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
- mdio_write(ioaddr, 0x1f, 0x0000);
+ mdio_write(ioaddr, 0x1f, 0x0002);
+ mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
+ mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
+
+ mdio_write(ioaddr, 0x1f, 0x0001);
+ mdio_write(ioaddr, 0x17, 0x0cc0);
+
+ mdio_write(ioaddr, 0x1f, 0x0002);
+ mdio_patch(ioaddr, 0x0f, 0x0017);
+
+ rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
+}
+
+static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr)
+{
+ struct phy_reg phy_reg_init[] = {
+ { 0x1f, 0x0002 },
+ { 0x10, 0x0008 },
+ { 0x0d, 0x006c },
+
+ { 0x1f, 0x0000 },
+ { 0x0d, 0xf880 },
+
+ { 0x1f, 0x0001 },
+ { 0x17, 0x0cc0 },
+
+ { 0x1f, 0x0001 },
+ { 0x0b, 0xa4d8 },
+ { 0x09, 0x281c },
+ { 0x07, 0x2883 },
+ { 0x0a, 0x6b35 },
+ { 0x1d, 0x3da4 },
+ { 0x1c, 0xeffd },
+ { 0x14, 0x7f52 },
+ { 0x18, 0x7fc6 },
+ { 0x08, 0x0601 },
+ { 0x06, 0x4063 },
+ { 0x10, 0xf074 },
+ { 0x1f, 0x0003 },
+ { 0x13, 0x0789 },
+ { 0x12, 0xf4bd },
+ { 0x1a, 0x04fd },
+ { 0x14, 0x84b0 },
+ { 0x1f, 0x0000 },
+ { 0x00, 0x9200 },
+
+ { 0x1f, 0x0005 },
+ { 0x01, 0x0340 },
+ { 0x1f, 0x0001 },
+ { 0x04, 0x4000 },
+ { 0x03, 0x1d21 },
+ { 0x02, 0x0c32 },
+ { 0x01, 0x0200 },
+ { 0x00, 0x5554 },
+ { 0x04, 0x4800 },
+ { 0x04, 0x4000 },
+ { 0x04, 0xf000 },
+ { 0x03, 0xdf01 },
+ { 0x02, 0xdf20 },
+ { 0x01, 0x101a },
+ { 0x00, 0xa0ff },
+ { 0x04, 0xf800 },
+ { 0x04, 0xf000 },
+ { 0x1f, 0x0000 },
+
+ { 0x1f, 0x0007 },
+ { 0x1e, 0x0023 },
+ { 0x16, 0x0000 },
+ { 0x1f, 0x0000 }
+ };
+
+ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
@@ -1792,7 +2664,13 @@ static void rtl_hw_phy_config(struct net_device *dev)
rtl8168cp_2_hw_phy_config(ioaddr);
break;
case RTL_GIGA_MAC_VER_25:
- rtl8168d_hw_phy_config(ioaddr);
+ rtl8168d_1_hw_phy_config(ioaddr);
+ break;
+ case RTL_GIGA_MAC_VER_26:
+ rtl8168d_2_hw_phy_config(ioaddr);
+ break;
+ case RTL_GIGA_MAC_VER_27:
+ rtl8168d_3_hw_phy_config(ioaddr);
break;
default:
@@ -2322,6 +3200,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
rtl8169_init_phy(dev, tp);
+
+ /*
+ * Pretend we are using VLANs; This bypasses a nasty bug where
+ * Interrupts stop flowing on high load on 8110SCd controllers.
+ */
+ if (tp->mac_version == RTL_GIGA_MAC_VER_05)
+ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | RxVlan);
+
device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
out:
@@ -2349,6 +3235,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
flush_scheduled_work();
unregister_netdev(dev);
+
+ /* restore original MAC address */
+ rtl_rar_set(tp, dev->perm_addr);
+
rtl_disable_msi(pdev, tp);
rtl8169_release_board(pdev, dev, tp->mmio_addr);
pci_set_drvdata(pdev, NULL);
@@ -2357,9 +3247,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
struct net_device *dev)
{
- unsigned int mtu = dev->mtu;
+ unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
- tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
+ tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
}
static int rtl8169_open(struct net_device *dev)
@@ -2493,7 +3383,7 @@ static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz)
{
/* Low hurts. Let's disable the filtering. */
- RTL_W16(RxMaxSize, rx_buf_sz);
+ RTL_W16(RxMaxSize, rx_buf_sz + 1);
}
static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
@@ -2863,6 +3753,8 @@ static void rtl_hw_start_8168(struct net_device *dev)
break;
case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_27:
rtl_hw_start_8168d(ioaddr, pdev);
break;
@@ -3993,6 +4885,9 @@ static void rtl_shutdown(struct pci_dev *pdev)
rtl8169_net_suspend(dev);
+ /* restore original MAC address */
+ rtl_rar_set(tp, dev->perm_addr);
+
spin_lock_irq(&tp->lock);
rtl8169_asic_down(ioaddr);
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index ddccf5fa56b6..0dd7839322bc 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3494,6 +3494,7 @@ static void s2io_reset(struct s2io_nic *sp)
/* Restore the PCI state saved during initialization. */
pci_restore_state(sp->pdev);
+ pci_save_state(sp->pdev);
pci_read_config_word(sp->pdev, 0x2, &val16);
if (check_pci_device_id(val16) != (u16)PCI_ANY_ID)
break;
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 01f9432c31ef..98bff5ada09a 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -444,7 +444,8 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
* the appropriate LRO method
*/
static void efx_rx_packet_lro(struct efx_channel *channel,
- struct efx_rx_buffer *rx_buf)
+ struct efx_rx_buffer *rx_buf,
+ bool checksummed)
{
struct napi_struct *napi = &channel->napi_str;
@@ -466,7 +467,8 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
skb->len = rx_buf->len;
skb->data_len = rx_buf->len;
skb->truesize += rx_buf->len;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->ip_summed =
+ checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
napi_gro_frags(napi);
@@ -475,6 +477,7 @@ out:
rx_buf->page = NULL;
} else {
EFX_BUG_ON_PARANOID(!rx_buf->skb);
+ EFX_BUG_ON_PARANOID(!checksummed);
napi_gro_receive(napi, rx_buf->skb);
rx_buf->skb = NULL;
@@ -570,7 +573,7 @@ void __efx_rx_packet(struct efx_channel *channel,
}
if (likely(checksummed || rx_buf->page)) {
- efx_rx_packet_lro(channel, rx_buf);
+ efx_rx_packet_lro(channel, rx_buf, checksummed);
goto done;
}
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index cee00ad49b57..49eb91b5f50c 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -188,7 +188,7 @@ static int sfn4111t_reset(struct efx_nic *efx)
efx_oword_t reg;
/* GPIO 3 and the GPIO register are shared with I2C, so block that */
- mutex_lock(&efx->i2c_adap.bus_lock);
+ i2c_lock_adapter(&efx->i2c_adap);
/* Pull RST_N (GPIO 2) low then let it up again, setting the
* FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the
@@ -204,7 +204,7 @@ static int sfn4111t_reset(struct efx_nic *efx)
falcon_write(efx, &reg, GPIO_CTL_REG_KER);
msleep(1);
- mutex_unlock(&efx->i2c_adap.bus_lock);
+ i2c_unlock_adapter(&efx->i2c_adap);
ssleep(1);
return 0;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index f49d0800c1d1..528b912a4b0d 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -30,6 +30,7 @@
#include <linux/phy.h>
#include <linux/cache.h>
#include <linux/io.h>
+#include <asm/cacheflush.h>
#include "sh_eth.h"
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 2ab5c39f33ca..6a10d7ba5877 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -4538,6 +4538,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out_free_netdev;
}
+ netif_carrier_off(dev);
+
netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
err = request_irq(pdev->irq, sky2_intr,
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 05c91ee6921e..f12206bdbb75 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -2283,7 +2283,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev)
ndev->irq = ires->start;
- if (ires->flags & IRQF_TRIGGER_MASK)
+ if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK)
irq_flags = ires->flags & IRQF_TRIGGER_MASK;
ret = smc_request_attrib(pdev, ndev);
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index ccdd196f5297..f9cdcbcb77d4 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -986,7 +986,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
struct net_device *dev = pdata->dev;
int npackets = 0;
- while (likely(netif_running(dev)) && (npackets < budget)) {
+ while (npackets < budget) {
unsigned int pktlength;
unsigned int pktwords;
struct sk_buff *skb;
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index b4909a2dec66..0f7909276237 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -252,6 +252,9 @@ static int smsc9420_ethtool_get_settings(struct net_device *dev,
{
struct smsc9420_pdata *pd = netdev_priv(dev);
+ if (!pd->phy_dev)
+ return -ENODEV;
+
cmd->maxtxpkt = 1;
cmd->maxrxpkt = 1;
return phy_ethtool_gset(pd->phy_dev, cmd);
@@ -262,6 +265,9 @@ static int smsc9420_ethtool_set_settings(struct net_device *dev,
{
struct smsc9420_pdata *pd = netdev_priv(dev);
+ if (!pd->phy_dev)
+ return -ENODEV;
+
return phy_ethtool_sset(pd->phy_dev, cmd);
}
@@ -290,6 +296,10 @@ static void smsc9420_ethtool_set_msglevel(struct net_device *netdev, u32 data)
static int smsc9420_ethtool_nway_reset(struct net_device *netdev)
{
struct smsc9420_pdata *pd = netdev_priv(netdev);
+
+ if (!pd->phy_dev)
+ return -ENODEV;
+
return phy_start_aneg(pd->phy_dev);
}
@@ -312,6 +322,10 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
for (i = 0; i < 0x100; i += (sizeof(u32)))
data[j++] = smsc9420_reg_read(pd, i);
+ // cannot read phy registers if the net device is down
+ if (!phy_dev)
+ return;
+
for (i = 0; i <= 31; i++)
data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i);
}
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
new file mode 100644
index 000000000000..35eaa5251d7f
--- /dev/null
+++ b/drivers/net/stmmac/Kconfig
@@ -0,0 +1,53 @@
+config STMMAC_ETH
+ tristate "STMicroelectronics 10/100/1000 Ethernet driver"
+ select MII
+ select PHYLIB
+ depends on NETDEVICES && CPU_SUBTYPE_ST40
+ help
+ This is the driver for the ST MAC 10/100/1000 on-chip Ethernet
+ controllers. ST Ethernet IPs are built around a Synopsys IP Core.
+
+if STMMAC_ETH
+
+config STMMAC_DA
+ bool "STMMAC DMA arbitration scheme"
+ default n
+ help
+ Selecting this option, rx has priority over Tx (only for Giga
+ Ethernet device).
+ By default, the DMA arbitration scheme is based on Round-robin
+ (rx:tx priority is 1:1).
+
+config STMMAC_DUAL_MAC
+ bool "STMMAC: dual mac support (EXPERIMENTAL)"
+ default n
+ depends on EXPERIMENTAL && STMMAC_ETH && !STMMAC_TIMER
+ help
+ Some ST SoCs (for example the stx7141 and stx7200c2) have two
+ Ethernet Controllers. This option turns on the second Ethernet
+ device on this kind of platforms.
+
+config STMMAC_TIMER
+ bool "STMMAC Timer optimisation"
+ default n
+ help
+ Use an external timer for mitigating the number of network
+ interrupts.
+
+choice
+ prompt "Select Timer device"
+ depends on STMMAC_TIMER
+
+config STMMAC_TMU_TIMER
+ bool "TMU channel 2"
+ depends on CPU_SH4
+ help
+
+config STMMAC_RTC_TIMER
+ bool "Real time clock"
+ depends on RTC_CLASS
+ help
+
+endchoice
+
+endif
diff --git a/drivers/net/stmmac/Makefile b/drivers/net/stmmac/Makefile
new file mode 100644
index 000000000000..b2d7a5564dfa
--- /dev/null
+++ b/drivers/net/stmmac/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_STMMAC_ETH) += stmmac.o
+stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
+stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
+ mac100.o gmac.o $(stmmac-y)
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
new file mode 100644
index 000000000000..e49e5188e887
--- /dev/null
+++ b/drivers/net/stmmac/common.h
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ STMMAC Common Header File
+
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include "descs.h"
+#include <linux/io.h>
+
+/* *********************************************
+ DMA CRS Control and Status Register Mapping
+ * *********************************************/
+#define DMA_BUS_MODE 0x00001000 /* Bus Mode */
+#define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */
+#define DMA_RCV_POLL_DEMAND 0x00001008 /* Received Poll Demand */
+#define DMA_RCV_BASE_ADDR 0x0000100c /* Receive List Base */
+#define DMA_TX_BASE_ADDR 0x00001010 /* Transmit List Base */
+#define DMA_STATUS 0x00001014 /* Status Register */
+#define DMA_CONTROL 0x00001018 /* Ctrl (Operational Mode) */
+#define DMA_INTR_ENA 0x0000101c /* Interrupt Enable */
+#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */
+#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */
+#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */
+
+/* ********************************
+ DMA Control register defines
+ * ********************************/
+#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */
+#define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */
+
+/* **************************************
+ DMA Interrupt Enable register defines
+ * **************************************/
+/**** NORMAL INTERRUPT ****/
+#define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */
+#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */
+#define DMA_INTR_ENA_TUE 0x00000004 /* Transmit Buffer Unavailable */
+#define DMA_INTR_ENA_RIE 0x00000040 /* Receive Interrupt */
+#define DMA_INTR_ENA_ERE 0x00004000 /* Early Receive */
+
+#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
+ DMA_INTR_ENA_TIE)
+
+/**** ABNORMAL INTERRUPT ****/
+#define DMA_INTR_ENA_AIE 0x00008000 /* Abnormal Summary */
+#define DMA_INTR_ENA_FBE 0x00002000 /* Fatal Bus Error */
+#define DMA_INTR_ENA_ETE 0x00000400 /* Early Transmit */
+#define DMA_INTR_ENA_RWE 0x00000200 /* Receive Watchdog */
+#define DMA_INTR_ENA_RSE 0x00000100 /* Receive Stopped */
+#define DMA_INTR_ENA_RUE 0x00000080 /* Receive Buffer Unavailable */
+#define DMA_INTR_ENA_UNE 0x00000020 /* Tx Underflow */
+#define DMA_INTR_ENA_OVE 0x00000010 /* Receive Overflow */
+#define DMA_INTR_ENA_TJE 0x00000008 /* Transmit Jabber */
+#define DMA_INTR_ENA_TSE 0x00000002 /* Transmit Stopped */
+
+#define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
+ DMA_INTR_ENA_UNE)
+
+/* DMA default interrupt mask */
+#define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
+
+/* ****************************
+ * DMA Status register defines
+ * ****************************/
+#define DMA_STATUS_GPI 0x10000000 /* PMT interrupt */
+#define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */
+#define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int. */
+#define DMA_STATUS_GMI 0x08000000
+#define DMA_STATUS_GLI 0x04000000
+#define DMA_STATUS_EB_MASK 0x00380000 /* Error Bits Mask */
+#define DMA_STATUS_EB_TX_ABORT 0x00080000 /* Error Bits - TX Abort */
+#define DMA_STATUS_EB_RX_ABORT 0x00100000 /* Error Bits - RX Abort */
+#define DMA_STATUS_TS_MASK 0x00700000 /* Transmit Process State */
+#define DMA_STATUS_TS_SHIFT 20
+#define DMA_STATUS_RS_MASK 0x000e0000 /* Receive Process State */
+#define DMA_STATUS_RS_SHIFT 17
+#define DMA_STATUS_NIS 0x00010000 /* Normal Interrupt Summary */
+#define DMA_STATUS_AIS 0x00008000 /* Abnormal Interrupt Summary */
+#define DMA_STATUS_ERI 0x00004000 /* Early Receive Interrupt */
+#define DMA_STATUS_FBI 0x00002000 /* Fatal Bus Error Interrupt */
+#define DMA_STATUS_ETI 0x00000400 /* Early Transmit Interrupt */
+#define DMA_STATUS_RWT 0x00000200 /* Receive Watchdog Timeout */
+#define DMA_STATUS_RPS 0x00000100 /* Receive Process Stopped */
+#define DMA_STATUS_RU 0x00000080 /* Receive Buffer Unavailable */
+#define DMA_STATUS_RI 0x00000040 /* Receive Interrupt */
+#define DMA_STATUS_UNF 0x00000020 /* Transmit Underflow */
+#define DMA_STATUS_OVF 0x00000010 /* Receive Overflow */
+#define DMA_STATUS_TJT 0x00000008 /* Transmit Jabber Timeout */
+#define DMA_STATUS_TU 0x00000004 /* Transmit Buffer Unavailable */
+#define DMA_STATUS_TPS 0x00000002 /* Transmit Process Stopped */
+#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
+
+/* Other defines */
+#define HASH_TABLE_SIZE 64
+#define PAUSE_TIME 0x200
+
+/* Flow Control defines */
+#define FLOW_OFF 0
+#define FLOW_RX 1
+#define FLOW_TX 2
+#define FLOW_AUTO (FLOW_TX | FLOW_RX)
+
+/* DMA STORE-AND-FORWARD Operation Mode */
+#define SF_DMA_MODE 1
+
+#define HW_CSUM 1
+#define NO_HW_CSUM 0
+
+/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
+#define BUF_SIZE_16KiB 16384
+#define BUF_SIZE_8KiB 8192
+#define BUF_SIZE_4KiB 4096
+#define BUF_SIZE_2KiB 2048
+
+/* Power Down and WOL */
+#define PMT_NOT_SUPPORTED 0
+#define PMT_SUPPORTED 1
+
+/* Common MAC defines */
+#define MAC_CTRL_REG 0x00000000 /* MAC Control */
+#define MAC_ENABLE_TX 0x00000008 /* Transmitter Enable */
+#define MAC_RNABLE_RX 0x00000004 /* Receiver Enable */
+
+/* MAC Management Counters register */
+#define MMC_CONTROL 0x00000100 /* MMC Control */
+#define MMC_HIGH_INTR 0x00000104 /* MMC High Interrupt */
+#define MMC_LOW_INTR 0x00000108 /* MMC Low Interrupt */
+#define MMC_HIGH_INTR_MASK 0x0000010c /* MMC High Interrupt Mask */
+#define MMC_LOW_INTR_MASK 0x00000110 /* MMC Low Interrupt Mask */
+
+#define MMC_CONTROL_MAX_FRM_MASK 0x0003ff8 /* Maximum Frame Size */
+#define MMC_CONTROL_MAX_FRM_SHIFT 3
+#define MMC_CONTROL_MAX_FRAME 0x7FF
+
+struct stmmac_extra_stats {
+ /* Transmit errors */
+ unsigned long tx_underflow ____cacheline_aligned;
+ unsigned long tx_carrier;
+ unsigned long tx_losscarrier;
+ unsigned long tx_heartbeat;
+ unsigned long tx_deferred;
+ unsigned long tx_vlan;
+ unsigned long tx_jabber;
+ unsigned long tx_frame_flushed;
+ unsigned long tx_payload_error;
+ unsigned long tx_ip_header_error;
+ /* Receive errors */
+ unsigned long rx_desc;
+ unsigned long rx_partial;
+ unsigned long rx_runt;
+ unsigned long rx_toolong;
+ unsigned long rx_collision;
+ unsigned long rx_crc;
+ unsigned long rx_lenght;
+ unsigned long rx_mii;
+ unsigned long rx_multicast;
+ unsigned long rx_gmac_overflow;
+ unsigned long rx_watchdog;
+ unsigned long da_rx_filter_fail;
+ unsigned long sa_rx_filter_fail;
+ unsigned long rx_missed_cntr;
+ unsigned long rx_overflow_cntr;
+ unsigned long rx_vlan;
+ /* Tx/Rx IRQ errors */
+ unsigned long tx_undeflow_irq;
+ unsigned long tx_process_stopped_irq;
+ unsigned long tx_jabber_irq;
+ unsigned long rx_overflow_irq;
+ unsigned long rx_buf_unav_irq;
+ unsigned long rx_process_stopped_irq;
+ unsigned long rx_watchdog_irq;
+ unsigned long tx_early_irq;
+ unsigned long fatal_bus_error_irq;
+ /* Extra info */
+ unsigned long threshold;
+ unsigned long tx_pkt_n;
+ unsigned long rx_pkt_n;
+ unsigned long poll_n;
+ unsigned long sched_timer_n;
+ unsigned long normal_irq_n;
+};
+
+/* GMAC core can compute the checksums in HW. */
+enum rx_frame_status {
+ good_frame = 0,
+ discard_frame = 1,
+ csum_none = 2,
+};
+
+static inline void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
+ unsigned int high, unsigned int low)
+{
+ unsigned long data;
+
+ data = (addr[5] << 8) | addr[4];
+ writel(data, ioaddr + high);
+ data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
+ writel(data, ioaddr + low);
+
+ return;
+}
+
+static inline void stmmac_get_mac_addr(unsigned long ioaddr,
+ unsigned char *addr, unsigned int high,
+ unsigned int low)
+{
+ unsigned int hi_addr, lo_addr;
+
+ /* Read the MAC address from the hardware */
+ hi_addr = readl(ioaddr + high);
+ lo_addr = readl(ioaddr + low);
+
+ /* Extract the MAC address from the high and low words */
+ addr[0] = lo_addr & 0xff;
+ addr[1] = (lo_addr >> 8) & 0xff;
+ addr[2] = (lo_addr >> 16) & 0xff;
+ addr[3] = (lo_addr >> 24) & 0xff;
+ addr[4] = hi_addr & 0xff;
+ addr[5] = (hi_addr >> 8) & 0xff;
+
+ return;
+}
+
+struct stmmac_ops {
+ /* MAC core initialization */
+ void (*core_init) (unsigned long ioaddr) ____cacheline_aligned;
+ /* DMA core initialization */
+ int (*dma_init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
+ /* Dump MAC registers */
+ void (*dump_mac_regs) (unsigned long ioaddr);
+ /* Dump DMA registers */
+ void (*dump_dma_regs) (unsigned long ioaddr);
+ /* Set tx/rx threshold in the csr6 register
+ * An invalid value enables the store-and-forward mode */
+ void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode);
+ /* To track extra statistic (if supported) */
+ void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
+ unsigned long ioaddr);
+ /* RX descriptor ring initialization */
+ void (*init_rx_desc) (struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic);
+ /* TX descriptor ring initialization */
+ void (*init_tx_desc) (struct dma_desc *p, unsigned int ring_size);
+
+ /* Invoked by the xmit function to prepare the tx descriptor */
+ void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len,
+ int csum_flag);
+ /* Set/get the owner of the descriptor */
+ void (*set_tx_owner) (struct dma_desc *p);
+ int (*get_tx_owner) (struct dma_desc *p);
+ /* Invoked by the xmit function to close the tx descriptor */
+ void (*close_tx_desc) (struct dma_desc *p);
+ /* Clean the tx descriptor as soon as the tx irq is received */
+ void (*release_tx_desc) (struct dma_desc *p);
+ /* Clear interrupt on tx frame completion. When this bit is
+ * set an interrupt happens as soon as the frame is transmitted */
+ void (*clear_tx_ic) (struct dma_desc *p);
+ /* Last tx segment reports the transmit status */
+ int (*get_tx_ls) (struct dma_desc *p);
+ /* Return the transmit status looking at the TDES1 */
+ int (*tx_status) (void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p, unsigned long ioaddr);
+ /* Get the buffer size from the descriptor */
+ int (*get_tx_len) (struct dma_desc *p);
+ /* Handle extra events on specific interrupts hw dependent */
+ void (*host_irq_status) (unsigned long ioaddr);
+ int (*get_rx_owner) (struct dma_desc *p);
+ void (*set_rx_owner) (struct dma_desc *p);
+ /* Get the receive frame size */
+ int (*get_rx_frame_len) (struct dma_desc *p);
+ /* Return the reception status looking at the RDES1 */
+ int (*rx_status) (void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p);
+ /* Multicast filter setting */
+ void (*set_filter) (struct net_device *dev);
+ /* Flow control setting */
+ void (*flow_ctrl) (unsigned long ioaddr, unsigned int duplex,
+ unsigned int fc, unsigned int pause_time);
+ /* Set power management mode (e.g. magic frame) */
+ void (*pmt) (unsigned long ioaddr, unsigned long mode);
+ /* Set/Get Unicast MAC addresses */
+ void (*set_umac_addr) (unsigned long ioaddr, unsigned char *addr,
+ unsigned int reg_n);
+ void (*get_umac_addr) (unsigned long ioaddr, unsigned char *addr,
+ unsigned int reg_n);
+};
+
+struct mac_link {
+ int port;
+ int duplex;
+ int speed;
+};
+
+struct mii_regs {
+ unsigned int addr; /* MII Address */
+ unsigned int data; /* MII Data */
+};
+
+struct hw_cap {
+ unsigned int version; /* Core Version register (GMAC) */
+ unsigned int pmt; /* Power-Down mode (GMAC) */
+ struct mac_link link;
+ struct mii_regs mii;
+};
+
+struct mac_device_info {
+ struct hw_cap hw;
+ struct stmmac_ops *ops;
+};
+
+struct mac_device_info *gmac_setup(unsigned long addr);
+struct mac_device_info *mac100_setup(unsigned long addr);
diff --git a/drivers/net/stmmac/descs.h b/drivers/net/stmmac/descs.h
new file mode 100644
index 000000000000..6d2a0b2f5e57
--- /dev/null
+++ b/drivers/net/stmmac/descs.h
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ Header File to describe the DMA descriptors
+ Use enhanced descriptors in case of GMAC Cores.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+struct dma_desc {
+ /* Receive descriptor */
+ union {
+ struct {
+ /* RDES0 */
+ u32 reserved1:1;
+ u32 crc_error:1;
+ u32 dribbling:1;
+ u32 mii_error:1;
+ u32 receive_watchdog:1;
+ u32 frame_type:1;
+ u32 collision:1;
+ u32 frame_too_long:1;
+ u32 last_descriptor:1;
+ u32 first_descriptor:1;
+ u32 multicast_frame:1;
+ u32 run_frame:1;
+ u32 length_error:1;
+ u32 partial_frame_error:1;
+ u32 descriptor_error:1;
+ u32 error_summary:1;
+ u32 frame_length:14;
+ u32 filtering_fail:1;
+ u32 own:1;
+ /* RDES1 */
+ u32 buffer1_size:11;
+ u32 buffer2_size:11;
+ u32 reserved2:2;
+ u32 second_address_chained:1;
+ u32 end_ring:1;
+ u32 reserved3:5;
+ u32 disable_ic:1;
+ } rx;
+ struct {
+ /* RDES0 */
+ u32 payload_csum_error:1;
+ u32 crc_error:1;
+ u32 dribbling:1;
+ u32 error_gmii:1;
+ u32 receive_watchdog:1;
+ u32 frame_type:1;
+ u32 late_collision:1;
+ u32 ipc_csum_error:1;
+ u32 last_descriptor:1;
+ u32 first_descriptor:1;
+ u32 vlan_tag:1;
+ u32 overflow_error:1;
+ u32 length_error:1;
+ u32 sa_filter_fail:1;
+ u32 descriptor_error:1;
+ u32 error_summary:1;
+ u32 frame_length:14;
+ u32 da_filter_fail:1;
+ u32 own:1;
+ /* RDES1 */
+ u32 buffer1_size:13;
+ u32 reserved1:1;
+ u32 second_address_chained:1;
+ u32 end_ring:1;
+ u32 buffer2_size:13;
+ u32 reserved2:2;
+ u32 disable_ic:1;
+ } erx; /* -- enhanced -- */
+
+ /* Transmit descriptor */
+ struct {
+ /* TDES0 */
+ u32 deferred:1;
+ u32 underflow_error:1;
+ u32 excessive_deferral:1;
+ u32 collision_count:4;
+ u32 heartbeat_fail:1;
+ u32 excessive_collisions:1;
+ u32 late_collision:1;
+ u32 no_carrier:1;
+ u32 loss_carrier:1;
+ u32 reserved1:3;
+ u32 error_summary:1;
+ u32 reserved2:15;
+ u32 own:1;
+ /* TDES1 */
+ u32 buffer1_size:11;
+ u32 buffer2_size:11;
+ u32 reserved3:1;
+ u32 disable_padding:1;
+ u32 second_address_chained:1;
+ u32 end_ring:1;
+ u32 crc_disable:1;
+ u32 reserved4:2;
+ u32 first_segment:1;
+ u32 last_segment:1;
+ u32 interrupt:1;
+ } tx;
+ struct {
+ /* TDES0 */
+ u32 deferred:1;
+ u32 underflow_error:1;
+ u32 excessive_deferral:1;
+ u32 collision_count:4;
+ u32 vlan_frame:1;
+ u32 excessive_collisions:1;
+ u32 late_collision:1;
+ u32 no_carrier:1;
+ u32 loss_carrier:1;
+ u32 payload_error:1;
+ u32 frame_flushed:1;
+ u32 jabber_timeout:1;
+ u32 error_summary:1;
+ u32 ip_header_error:1;
+ u32 time_stamp_status:1;
+ u32 reserved1:2;
+ u32 second_address_chained:1;
+ u32 end_ring:1;
+ u32 checksum_insertion:2;
+ u32 reserved2:1;
+ u32 time_stamp_enable:1;
+ u32 disable_padding:1;
+ u32 crc_disable:1;
+ u32 first_segment:1;
+ u32 last_segment:1;
+ u32 interrupt:1;
+ u32 own:1;
+ /* TDES1 */
+ u32 buffer1_size:13;
+ u32 reserved3:3;
+ u32 buffer2_size:13;
+ u32 reserved4:3;
+ } etx; /* -- enhanced -- */
+ } des01;
+ unsigned int des2;
+ unsigned int des3;
+};
+
+/* Transmit checksum insertion control */
+enum tdes_csum_insertion {
+ cic_disabled = 0, /* Checksum Insertion Control */
+ cic_only_ip = 1, /* Only IP header */
+ cic_no_pseudoheader = 2, /* IP header but pseudoheader
+ * is not calculated */
+ cic_full = 3, /* IP header and pseudoheader */
+};
diff --git a/drivers/net/stmmac/gmac.c b/drivers/net/stmmac/gmac.c
new file mode 100644
index 000000000000..b624bb5bae0a
--- /dev/null
+++ b/drivers/net/stmmac/gmac.c
@@ -0,0 +1,693 @@
+/*******************************************************************************
+ This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
+ DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
+ developing this code.
+
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/netdevice.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include "stmmac.h"
+#include "gmac.h"
+
+#undef GMAC_DEBUG
+/*#define GMAC_DEBUG*/
+#undef FRAME_FILTER_DEBUG
+/*#define FRAME_FILTER_DEBUG*/
+#ifdef GMAC_DEBUG
+#define DBG(fmt, args...) printk(fmt, ## args)
+#else
+#define DBG(fmt, args...) do { } while (0)
+#endif
+
+static void gmac_dump_regs(unsigned long ioaddr)
+{
+ int i;
+ pr_info("\t----------------------------------------------\n"
+ "\t GMAC registers (base addr = 0x%8x)\n"
+ "\t----------------------------------------------\n",
+ (unsigned int)ioaddr);
+
+ for (i = 0; i < 55; i++) {
+ int offset = i * 4;
+ pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
+ offset, readl(ioaddr + offset));
+ }
+ return;
+}
+
+static int gmac_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx)
+{
+ u32 value = readl(ioaddr + DMA_BUS_MODE);
+ /* DMA SW reset */
+ value |= DMA_BUS_MODE_SFT_RESET;
+ writel(value, ioaddr + DMA_BUS_MODE);
+ do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
+
+ value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
+ ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
+ (pbl << DMA_BUS_MODE_RPBL_SHIFT));
+
+#ifdef CONFIG_STMMAC_DA
+ value |= DMA_BUS_MODE_DA; /* Rx has priority over tx */
+#endif
+ writel(value, ioaddr + DMA_BUS_MODE);
+
+ /* Mask interrupts by writing to CSR7 */
+ writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+
+ /* The base address of the RX/TX descriptor lists must be written into
+ * DMA CSR3 and CSR4, respectively. */
+ writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
+ writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
+
+ return 0;
+}
+
+/* Transmit FIFO flush operation */
+static void gmac_flush_tx_fifo(unsigned long ioaddr)
+{
+ u32 csr6 = readl(ioaddr + DMA_CONTROL);
+ writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
+
+ do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
+}
+
+static void gmac_dma_operation_mode(unsigned long ioaddr, int txmode,
+ int rxmode)
+{
+ u32 csr6 = readl(ioaddr + DMA_CONTROL);
+
+ if (txmode == SF_DMA_MODE) {
+ DBG(KERN_DEBUG "GMAC: enabling TX store and forward mode\n");
+ /* Transmit COE type 2 cannot be done in cut-through mode. */
+ csr6 |= DMA_CONTROL_TSF;
+ /* Operating on second frame increase the performance
+ * especially when transmit store-and-forward is used.*/
+ csr6 |= DMA_CONTROL_OSF;
+ } else {
+ DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
+ " (threshold = %d)\n", txmode);
+ csr6 &= ~DMA_CONTROL_TSF;
+ csr6 &= DMA_CONTROL_TC_TX_MASK;
+ /* Set the transmit threashold */
+ if (txmode <= 32)
+ csr6 |= DMA_CONTROL_TTC_32;
+ else if (txmode <= 64)
+ csr6 |= DMA_CONTROL_TTC_64;
+ else if (txmode <= 128)
+ csr6 |= DMA_CONTROL_TTC_128;
+ else if (txmode <= 192)
+ csr6 |= DMA_CONTROL_TTC_192;
+ else
+ csr6 |= DMA_CONTROL_TTC_256;
+ }
+
+ if (rxmode == SF_DMA_MODE) {
+ DBG(KERN_DEBUG "GMAC: enabling RX store and forward mode\n");
+ csr6 |= DMA_CONTROL_RSF;
+ } else {
+ DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
+ " (threshold = %d)\n", rxmode);
+ csr6 &= ~DMA_CONTROL_RSF;
+ csr6 &= DMA_CONTROL_TC_RX_MASK;
+ if (rxmode <= 32)
+ csr6 |= DMA_CONTROL_RTC_32;
+ else if (rxmode <= 64)
+ csr6 |= DMA_CONTROL_RTC_64;
+ else if (rxmode <= 96)
+ csr6 |= DMA_CONTROL_RTC_96;
+ else
+ csr6 |= DMA_CONTROL_RTC_128;
+ }
+
+ writel(csr6, ioaddr + DMA_CONTROL);
+ return;
+}
+
+/* Not yet implemented --- no RMON module */
+static void gmac_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
+ unsigned long ioaddr)
+{
+ return;
+}
+
+static void gmac_dump_dma_regs(unsigned long ioaddr)
+{
+ int i;
+ pr_info(" DMA registers\n");
+ for (i = 0; i < 22; i++) {
+ if ((i < 9) || (i > 17)) {
+ int offset = i * 4;
+ pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
+ (DMA_BUS_MODE + offset),
+ readl(ioaddr + DMA_BUS_MODE + offset));
+ }
+ }
+ return;
+}
+
+static int gmac_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p, unsigned long ioaddr)
+{
+ int ret = 0;
+ struct net_device_stats *stats = (struct net_device_stats *)data;
+
+ if (unlikely(p->des01.etx.error_summary)) {
+ DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
+ if (unlikely(p->des01.etx.jabber_timeout)) {
+ DBG(KERN_ERR "\tjabber_timeout error\n");
+ x->tx_jabber++;
+ }
+
+ if (unlikely(p->des01.etx.frame_flushed)) {
+ DBG(KERN_ERR "\tframe_flushed error\n");
+ x->tx_frame_flushed++;
+ gmac_flush_tx_fifo(ioaddr);
+ }
+
+ if (unlikely(p->des01.etx.loss_carrier)) {
+ DBG(KERN_ERR "\tloss_carrier error\n");
+ x->tx_losscarrier++;
+ stats->tx_carrier_errors++;
+ }
+ if (unlikely(p->des01.etx.no_carrier)) {
+ DBG(KERN_ERR "\tno_carrier error\n");
+ x->tx_carrier++;
+ stats->tx_carrier_errors++;
+ }
+ if (unlikely(p->des01.etx.late_collision)) {
+ DBG(KERN_ERR "\tlate_collision error\n");
+ stats->collisions += p->des01.etx.collision_count;
+ }
+ if (unlikely(p->des01.etx.excessive_collisions)) {
+ DBG(KERN_ERR "\texcessive_collisions\n");
+ stats->collisions += p->des01.etx.collision_count;
+ }
+ if (unlikely(p->des01.etx.excessive_deferral)) {
+ DBG(KERN_INFO "\texcessive tx_deferral\n");
+ x->tx_deferred++;
+ }
+
+ if (unlikely(p->des01.etx.underflow_error)) {
+ DBG(KERN_ERR "\tunderflow error\n");
+ gmac_flush_tx_fifo(ioaddr);
+ x->tx_underflow++;
+ }
+
+ if (unlikely(p->des01.etx.ip_header_error)) {
+ DBG(KERN_ERR "\tTX IP header csum error\n");
+ x->tx_ip_header_error++;
+ }
+
+ if (unlikely(p->des01.etx.payload_error)) {
+ DBG(KERN_ERR "\tAddr/Payload csum error\n");
+ x->tx_payload_error++;
+ gmac_flush_tx_fifo(ioaddr);
+ }
+
+ ret = -1;
+ }
+
+ if (unlikely(p->des01.etx.deferred)) {
+ DBG(KERN_INFO "GMAC TX status: tx deferred\n");
+ x->tx_deferred++;
+ }
+#ifdef STMMAC_VLAN_TAG_USED
+ if (p->des01.etx.vlan_frame) {
+ DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
+ x->tx_vlan++;
+ }
+#endif
+
+ return ret;
+}
+
+static int gmac_get_tx_len(struct dma_desc *p)
+{
+ return p->des01.etx.buffer1_size;
+}
+
+static int gmac_coe_rdes0(int ipc_err, int type, int payload_err)
+{
+ int ret = good_frame;
+ u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
+
+ /* bits 5 7 0 | Frame status
+ * ----------------------------------------------------------
+ * 0 0 0 | IEEE 802.3 Type frame (lenght < 1536 octects)
+ * 1 0 0 | IPv4/6 No CSUM errorS.
+ * 1 0 1 | IPv4/6 CSUM PAYLOAD error
+ * 1 1 0 | IPv4/6 CSUM IP HR error
+ * 1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
+ * 0 0 1 | IPv4/6 unsupported IP PAYLOAD
+ * 0 1 1 | COE bypassed.. no IPv4/6 frame
+ * 0 1 0 | Reserved.
+ */
+ if (status == 0x0) {
+ DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
+ ret = good_frame;
+ } else if (status == 0x4) {
+ DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
+ ret = good_frame;
+ } else if (status == 0x5) {
+ DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
+ ret = csum_none;
+ } else if (status == 0x6) {
+ DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
+ ret = csum_none;
+ } else if (status == 0x7) {
+ DBG(KERN_ERR
+ "RX Des0 status: IPv4/6 Header and Payload Error.\n");
+ ret = csum_none;
+ } else if (status == 0x1) {
+ DBG(KERN_ERR
+ "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
+ ret = discard_frame;
+ } else if (status == 0x3) {
+ DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
+ ret = discard_frame;
+ }
+ return ret;
+}
+
+static int gmac_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p)
+{
+ int ret = good_frame;
+ struct net_device_stats *stats = (struct net_device_stats *)data;
+
+ if (unlikely(p->des01.erx.error_summary)) {
+ DBG(KERN_ERR "GMAC RX Error Summary... 0x%08x\n", p->des01.erx);
+ if (unlikely(p->des01.erx.descriptor_error)) {
+ DBG(KERN_ERR "\tdescriptor error\n");
+ x->rx_desc++;
+ stats->rx_length_errors++;
+ }
+ if (unlikely(p->des01.erx.overflow_error)) {
+ DBG(KERN_ERR "\toverflow error\n");
+ x->rx_gmac_overflow++;
+ }
+
+ if (unlikely(p->des01.erx.ipc_csum_error))
+ DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
+
+ if (unlikely(p->des01.erx.late_collision)) {
+ DBG(KERN_ERR "\tlate_collision error\n");
+ stats->collisions++;
+ stats->collisions++;
+ }
+ if (unlikely(p->des01.erx.receive_watchdog)) {
+ DBG(KERN_ERR "\treceive_watchdog error\n");
+ x->rx_watchdog++;
+ }
+ if (unlikely(p->des01.erx.error_gmii)) {
+ DBG(KERN_ERR "\tReceive Error\n");
+ x->rx_mii++;
+ }
+ if (unlikely(p->des01.erx.crc_error)) {
+ DBG(KERN_ERR "\tCRC error\n");
+ x->rx_crc++;
+ stats->rx_crc_errors++;
+ }
+ ret = discard_frame;
+ }
+
+ /* After a payload csum error, the ES bit is set.
+ * It doesn't match with the information reported into the databook.
+ * At any rate, we need to understand if the CSUM hw computation is ok
+ * and report this info to the upper layers. */
+ ret = gmac_coe_rdes0(p->des01.erx.ipc_csum_error,
+ p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
+
+ if (unlikely(p->des01.erx.dribbling)) {
+ DBG(KERN_ERR "GMAC RX: dribbling error\n");
+ ret = discard_frame;
+ }
+ if (unlikely(p->des01.erx.sa_filter_fail)) {
+ DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
+ x->sa_rx_filter_fail++;
+ ret = discard_frame;
+ }
+ if (unlikely(p->des01.erx.da_filter_fail)) {
+ DBG(KERN_ERR "GMAC RX : Destination Address filter fail\n");
+ x->da_rx_filter_fail++;
+ ret = discard_frame;
+ }
+ if (unlikely(p->des01.erx.length_error)) {
+ DBG(KERN_ERR "GMAC RX: length_error error\n");
+ x->rx_lenght++;
+ ret = discard_frame;
+ }
+#ifdef STMMAC_VLAN_TAG_USED
+ if (p->des01.erx.vlan_tag) {
+ DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
+ x->rx_vlan++;
+ }
+#endif
+ return ret;
+}
+
+static void gmac_irq_status(unsigned long ioaddr)
+{
+ u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
+
+ /* Not used events (e.g. MMC interrupts) are not handled. */
+ if ((intr_status & mmc_tx_irq))
+ DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
+ readl(ioaddr + GMAC_MMC_TX_INTR));
+ if (unlikely(intr_status & mmc_rx_irq))
+ DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
+ readl(ioaddr + GMAC_MMC_RX_INTR));
+ if (unlikely(intr_status & mmc_rx_csum_offload_irq))
+ DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
+ readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
+ if (unlikely(intr_status & pmt_irq)) {
+ DBG(KERN_DEBUG "GMAC: received Magic frame\n");
+ /* clear the PMT bits 5 and 6 by reading the PMT
+ * status register. */
+ readl(ioaddr + GMAC_PMT);
+ }
+
+ return;
+}
+
+static void gmac_core_init(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + GMAC_CONTROL);
+ value |= GMAC_CORE_INIT;
+ writel(value, ioaddr + GMAC_CONTROL);
+
+ /* STBus Bridge Configuration */
+ /*writel(0xc5608, ioaddr + 0x00007000);*/
+
+ /* Freeze MMC counters */
+ writel(0x8, ioaddr + GMAC_MMC_CTRL);
+ /* Mask GMAC interrupts */
+ writel(0x207, ioaddr + GMAC_INT_MASK);
+
+#ifdef STMMAC_VLAN_TAG_USED
+ /* Tag detection without filtering */
+ writel(0x0, ioaddr + GMAC_VLAN_TAG);
+#endif
+ return;
+}
+
+static void gmac_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+ unsigned int reg_n)
+{
+ stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
+ GMAC_ADDR_LOW(reg_n));
+}
+
+static void gmac_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+ unsigned int reg_n)
+{
+ stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
+ GMAC_ADDR_LOW(reg_n));
+}
+
+static void gmac_set_filter(struct net_device *dev)
+{
+ unsigned long ioaddr = dev->base_addr;
+ unsigned int value = 0;
+
+ DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
+ __func__, dev->mc_count, dev->uc_count);
+
+ if (dev->flags & IFF_PROMISC)
+ value = GMAC_FRAME_FILTER_PR;
+ else if ((dev->mc_count > HASH_TABLE_SIZE)
+ || (dev->flags & IFF_ALLMULTI)) {
+ value = GMAC_FRAME_FILTER_PM; /* pass all multi */
+ writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
+ writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
+ } else if (dev->mc_count > 0) {
+ int i;
+ u32 mc_filter[2];
+ struct dev_mc_list *mclist;
+
+ /* Hash filter for multicast */
+ value = GMAC_FRAME_FILTER_HMC;
+
+ memset(mc_filter, 0, sizeof(mc_filter));
+ for (i = 0, mclist = dev->mc_list;
+ mclist && i < dev->mc_count; i++, mclist = mclist->next) {
+ /* The upper 6 bits of the calculated CRC are used to
+ index the contens of the hash table */
+ int bit_nr =
+ bitrev32(~crc32_le(~0, mclist->dmi_addr, 6)) >> 26;
+ /* The most significant bit determines the register to
+ * use (H/L) while the other 5 bits determine the bit
+ * within the register. */
+ mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+ }
+ writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
+ writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
+ }
+
+ /* Handle multiple unicast addresses (perfect filtering)*/
+ if (dev->uc_count > GMAC_MAX_UNICAST_ADDRESSES)
+ /* Switch to promiscuous mode is more than 16 addrs
+ are required */
+ value |= GMAC_FRAME_FILTER_PR;
+ else {
+ int i;
+ struct dev_addr_list *uc_ptr = dev->uc_list;
+
+ for (i = 0; i < dev->uc_count; i++) {
+ gmac_set_umac_addr(ioaddr, uc_ptr->da_addr,
+ i + 1);
+
+ DBG(KERN_INFO "\t%d "
+ "- Unicast addr %02x:%02x:%02x:%02x:%02x:"
+ "%02x\n", i + 1,
+ uc_ptr->da_addr[0], uc_ptr->da_addr[1],
+ uc_ptr->da_addr[2], uc_ptr->da_addr[3],
+ uc_ptr->da_addr[4], uc_ptr->da_addr[5]);
+ uc_ptr = uc_ptr->next;
+ }
+ }
+
+#ifdef FRAME_FILTER_DEBUG
+ /* Enable Receive all mode (to debug filtering_fail errors) */
+ value |= GMAC_FRAME_FILTER_RA;
+#endif
+ writel(value, ioaddr + GMAC_FRAME_FILTER);
+
+ DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
+ "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
+ readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
+
+ return;
+}
+
+static void gmac_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+ unsigned int fc, unsigned int pause_time)
+{
+ unsigned int flow = 0;
+
+ DBG(KERN_DEBUG "GMAC Flow-Control:\n");
+ if (fc & FLOW_RX) {
+ DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
+ flow |= GMAC_FLOW_CTRL_RFE;
+ }
+ if (fc & FLOW_TX) {
+ DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
+ flow |= GMAC_FLOW_CTRL_TFE;
+ }
+
+ if (duplex) {
+ DBG(KERN_DEBUG "\tduplex mode: pause time: %d\n", pause_time);
+ flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
+ }
+
+ writel(flow, ioaddr + GMAC_FLOW_CTRL);
+ return;
+}
+
+static void gmac_pmt(unsigned long ioaddr, unsigned long mode)
+{
+ unsigned int pmt = 0;
+
+ if (mode == WAKE_MAGIC) {
+ DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
+ pmt |= power_down | magic_pkt_en;
+ } else if (mode == WAKE_UCAST) {
+ DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
+ pmt |= global_unicast;
+ }
+
+ writel(pmt, ioaddr + GMAC_PMT);
+ return;
+}
+
+static void gmac_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic)
+{
+ int i;
+ for (i = 0; i < ring_size; i++) {
+ p->des01.erx.own = 1;
+ p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
+ /* To support jumbo frames */
+ p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
+ if (i == ring_size - 1)
+ p->des01.erx.end_ring = 1;
+ if (disable_rx_ic)
+ p->des01.erx.disable_ic = 1;
+ p++;
+ }
+ return;
+}
+
+static void gmac_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+ int i;
+
+ for (i = 0; i < ring_size; i++) {
+ p->des01.etx.own = 0;
+ if (i == ring_size - 1)
+ p->des01.etx.end_ring = 1;
+ p++;
+ }
+
+ return;
+}
+
+static int gmac_get_tx_owner(struct dma_desc *p)
+{
+ return p->des01.etx.own;
+}
+
+static int gmac_get_rx_owner(struct dma_desc *p)
+{
+ return p->des01.erx.own;
+}
+
+static void gmac_set_tx_owner(struct dma_desc *p)
+{
+ p->des01.etx.own = 1;
+}
+
+static void gmac_set_rx_owner(struct dma_desc *p)
+{
+ p->des01.erx.own = 1;
+}
+
+static int gmac_get_tx_ls(struct dma_desc *p)
+{
+ return p->des01.etx.last_segment;
+}
+
+static void gmac_release_tx_desc(struct dma_desc *p)
+{
+ int ter = p->des01.etx.end_ring;
+
+ memset(p, 0, sizeof(struct dma_desc));
+ p->des01.etx.end_ring = ter;
+
+ return;
+}
+
+static void gmac_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+ int csum_flag)
+{
+ p->des01.etx.first_segment = is_fs;
+ if (unlikely(len > BUF_SIZE_4KiB)) {
+ p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
+ p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
+ } else {
+ p->des01.etx.buffer1_size = len;
+ }
+ if (likely(csum_flag))
+ p->des01.etx.checksum_insertion = cic_full;
+}
+
+static void gmac_clear_tx_ic(struct dma_desc *p)
+{
+ p->des01.etx.interrupt = 0;
+}
+
+static void gmac_close_tx_desc(struct dma_desc *p)
+{
+ p->des01.etx.last_segment = 1;
+ p->des01.etx.interrupt = 1;
+}
+
+static int gmac_get_rx_frame_len(struct dma_desc *p)
+{
+ return p->des01.erx.frame_length;
+}
+
+struct stmmac_ops gmac_driver = {
+ .core_init = gmac_core_init,
+ .dump_mac_regs = gmac_dump_regs,
+ .dma_init = gmac_dma_init,
+ .dump_dma_regs = gmac_dump_dma_regs,
+ .dma_mode = gmac_dma_operation_mode,
+ .dma_diagnostic_fr = gmac_dma_diagnostic_fr,
+ .tx_status = gmac_get_tx_frame_status,
+ .rx_status = gmac_get_rx_frame_status,
+ .get_tx_len = gmac_get_tx_len,
+ .set_filter = gmac_set_filter,
+ .flow_ctrl = gmac_flow_ctrl,
+ .pmt = gmac_pmt,
+ .init_rx_desc = gmac_init_rx_desc,
+ .init_tx_desc = gmac_init_tx_desc,
+ .get_tx_owner = gmac_get_tx_owner,
+ .get_rx_owner = gmac_get_rx_owner,
+ .release_tx_desc = gmac_release_tx_desc,
+ .prepare_tx_desc = gmac_prepare_tx_desc,
+ .clear_tx_ic = gmac_clear_tx_ic,
+ .close_tx_desc = gmac_close_tx_desc,
+ .get_tx_ls = gmac_get_tx_ls,
+ .set_tx_owner = gmac_set_tx_owner,
+ .set_rx_owner = gmac_set_rx_owner,
+ .get_rx_frame_len = gmac_get_rx_frame_len,
+ .host_irq_status = gmac_irq_status,
+ .set_umac_addr = gmac_set_umac_addr,
+ .get_umac_addr = gmac_get_umac_addr,
+};
+
+struct mac_device_info *gmac_setup(unsigned long ioaddr)
+{
+ struct mac_device_info *mac;
+ u32 uid = readl(ioaddr + GMAC_VERSION);
+
+ pr_info("\tGMAC - user ID: 0x%x, Synopsys ID: 0x%x\n",
+ ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
+
+ mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
+
+ mac->ops = &gmac_driver;
+ mac->hw.pmt = PMT_SUPPORTED;
+ mac->hw.link.port = GMAC_CONTROL_PS;
+ mac->hw.link.duplex = GMAC_CONTROL_DM;
+ mac->hw.link.speed = GMAC_CONTROL_FES;
+ mac->hw.mii.addr = GMAC_MII_ADDR;
+ mac->hw.mii.data = GMAC_MII_DATA;
+
+ return mac;
+}
diff --git a/drivers/net/stmmac/gmac.h b/drivers/net/stmmac/gmac.h
new file mode 100644
index 000000000000..684a363120a9
--- /dev/null
+++ b/drivers/net/stmmac/gmac.h
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#define GMAC_CONTROL 0x00000000 /* Configuration */
+#define GMAC_FRAME_FILTER 0x00000004 /* Frame Filter */
+#define GMAC_HASH_HIGH 0x00000008 /* Multicast Hash Table High */
+#define GMAC_HASH_LOW 0x0000000c /* Multicast Hash Table Low */
+#define GMAC_MII_ADDR 0x00000010 /* MII Address */
+#define GMAC_MII_DATA 0x00000014 /* MII Data */
+#define GMAC_FLOW_CTRL 0x00000018 /* Flow Control */
+#define GMAC_VLAN_TAG 0x0000001c /* VLAN Tag */
+#define GMAC_VERSION 0x00000020 /* GMAC CORE Version */
+#define GMAC_WAKEUP_FILTER 0x00000028 /* Wake-up Frame Filter */
+
+#define GMAC_INT_STATUS 0x00000038 /* interrupt status register */
+enum gmac_irq_status {
+ time_stamp_irq = 0x0200,
+ mmc_rx_csum_offload_irq = 0x0080,
+ mmc_tx_irq = 0x0040,
+ mmc_rx_irq = 0x0020,
+ mmc_irq = 0x0010,
+ pmt_irq = 0x0008,
+ pcs_ane_irq = 0x0004,
+ pcs_link_irq = 0x0002,
+ rgmii_irq = 0x0001,
+};
+#define GMAC_INT_MASK 0x0000003c /* interrupt mask register */
+
+/* PMT Control and Status */
+#define GMAC_PMT 0x0000002c
+enum power_event {
+ pointer_reset = 0x80000000,
+ global_unicast = 0x00000200,
+ wake_up_rx_frame = 0x00000040,
+ magic_frame = 0x00000020,
+ wake_up_frame_en = 0x00000004,
+ magic_pkt_en = 0x00000002,
+ power_down = 0x00000001,
+};
+
+/* GMAC HW ADDR regs */
+#define GMAC_ADDR_HIGH(reg) (0x00000040+(reg * 8))
+#define GMAC_ADDR_LOW(reg) (0x00000044+(reg * 8))
+#define GMAC_MAX_UNICAST_ADDRESSES 16
+
+#define GMAC_AN_CTRL 0x000000c0 /* AN control */
+#define GMAC_AN_STATUS 0x000000c4 /* AN status */
+#define GMAC_ANE_ADV 0x000000c8 /* Auto-Neg. Advertisement */
+#define GMAC_ANE_LINK 0x000000cc /* Auto-Neg. link partener ability */
+#define GMAC_ANE_EXP 0x000000d0 /* ANE expansion */
+#define GMAC_TBI 0x000000d4 /* TBI extend status */
+#define GMAC_GMII_STATUS 0x000000d8 /* S/R-GMII status */
+
+/* GMAC Configuration defines */
+#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in RGMII/SGMII */
+#define GMAC_CONTROL_WD 0x00800000 /* Disable Watchdog on receive */
+#define GMAC_CONTROL_JD 0x00400000 /* Jabber disable */
+#define GMAC_CONTROL_BE 0x00200000 /* Frame Burst Enable */
+#define GMAC_CONTROL_JE 0x00100000 /* Jumbo frame */
+enum inter_frame_gap {
+ GMAC_CONTROL_IFG_88 = 0x00040000,
+ GMAC_CONTROL_IFG_80 = 0x00020000,
+ GMAC_CONTROL_IFG_40 = 0x000e0000,
+};
+#define GMAC_CONTROL_DCRS 0x00010000 /* Disable carrier sense during tx */
+#define GMAC_CONTROL_PS 0x00008000 /* Port Select 0:GMI 1:MII */
+#define GMAC_CONTROL_FES 0x00004000 /* Speed 0:10 1:100 */
+#define GMAC_CONTROL_DO 0x00002000 /* Disable Rx Own */
+#define GMAC_CONTROL_LM 0x00001000 /* Loop-back mode */
+#define GMAC_CONTROL_DM 0x00000800 /* Duplex Mode */
+#define GMAC_CONTROL_IPC 0x00000400 /* Checksum Offload */
+#define GMAC_CONTROL_DR 0x00000200 /* Disable Retry */
+#define GMAC_CONTROL_LUD 0x00000100 /* Link up/down */
+#define GMAC_CONTROL_ACS 0x00000080 /* Automatic Pad Stripping */
+#define GMAC_CONTROL_DC 0x00000010 /* Deferral Check */
+#define GMAC_CONTROL_TE 0x00000008 /* Transmitter Enable */
+#define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */
+
+#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
+ GMAC_CONTROL_IPC | GMAC_CONTROL_JE | GMAC_CONTROL_BE)
+
+/* GMAC Frame Filter defines */
+#define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */
+#define GMAC_FRAME_FILTER_HUC 0x00000002 /* Hash Unicast */
+#define GMAC_FRAME_FILTER_HMC 0x00000004 /* Hash Multicast */
+#define GMAC_FRAME_FILTER_DAIF 0x00000008 /* DA Inverse Filtering */
+#define GMAC_FRAME_FILTER_PM 0x00000010 /* Pass all multicast */
+#define GMAC_FRAME_FILTER_DBF 0x00000020 /* Disable Broadcast frames */
+#define GMAC_FRAME_FILTER_SAIF 0x00000100 /* Inverse Filtering */
+#define GMAC_FRAME_FILTER_SAF 0x00000200 /* Source Address Filter */
+#define GMAC_FRAME_FILTER_HPF 0x00000400 /* Hash or perfect Filter */
+#define GMAC_FRAME_FILTER_RA 0x80000000 /* Receive all mode */
+/* GMII ADDR defines */
+#define GMAC_MII_ADDR_WRITE 0x00000002 /* MII Write */
+#define GMAC_MII_ADDR_BUSY 0x00000001 /* MII Busy */
+/* GMAC FLOW CTRL defines */
+#define GMAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */
+#define GMAC_FLOW_CTRL_PT_SHIFT 16
+#define GMAC_FLOW_CTRL_RFE 0x00000004 /* Rx Flow Control Enable */
+#define GMAC_FLOW_CTRL_TFE 0x00000002 /* Tx Flow Control Enable */
+#define GMAC_FLOW_CTRL_FCB_BPA 0x00000001 /* Flow Control Busy ... */
+
+/*--- DMA BLOCK defines ---*/
+/* DMA Bus Mode register defines */
+#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */
+#define DMA_BUS_MODE_DA 0x00000002 /* Arbitration scheme */
+#define DMA_BUS_MODE_DSL_MASK 0x0000007c /* Descriptor Skip Length */
+#define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */
+/* Programmable burst length (passed thorugh platform)*/
+#define DMA_BUS_MODE_PBL_MASK 0x00003f00 /* Programmable Burst Len */
+#define DMA_BUS_MODE_PBL_SHIFT 8
+
+enum rx_tx_priority_ratio {
+ double_ratio = 0x00004000, /*2:1 */
+ triple_ratio = 0x00008000, /*3:1 */
+ quadruple_ratio = 0x0000c000, /*4:1 */
+};
+
+#define DMA_BUS_MODE_FB 0x00010000 /* Fixed burst */
+#define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */
+#define DMA_BUS_MODE_RPBL_SHIFT 17
+#define DMA_BUS_MODE_USP 0x00800000
+#define DMA_BUS_MODE_4PBL 0x01000000
+#define DMA_BUS_MODE_AAL 0x02000000
+
+/* DMA CRS Control and Status Register Mapping */
+#define DMA_HOST_TX_DESC 0x00001048 /* Current Host Tx descriptor */
+#define DMA_HOST_RX_DESC 0x0000104c /* Current Host Rx descriptor */
+/* DMA Bus Mode register defines */
+#define DMA_BUS_PR_RATIO_MASK 0x0000c000 /* Rx/Tx priority ratio */
+#define DMA_BUS_PR_RATIO_SHIFT 14
+#define DMA_BUS_FB 0x00010000 /* Fixed Burst */
+
+/* DMA operation mode defines (start/stop tx/rx are placed in common header)*/
+#define DMA_CONTROL_DT 0x04000000 /* Disable Drop TCP/IP csum error */
+#define DMA_CONTROL_RSF 0x02000000 /* Receive Store and Forward */
+#define DMA_CONTROL_DFF 0x01000000 /* Disaable flushing */
+/* Theshold for Activating the FC */
+enum rfa {
+ act_full_minus_1 = 0x00800000,
+ act_full_minus_2 = 0x00800200,
+ act_full_minus_3 = 0x00800400,
+ act_full_minus_4 = 0x00800600,
+};
+/* Theshold for Deactivating the FC */
+enum rfd {
+ deac_full_minus_1 = 0x00400000,
+ deac_full_minus_2 = 0x00400800,
+ deac_full_minus_3 = 0x00401000,
+ deac_full_minus_4 = 0x00401800,
+};
+#define DMA_CONTROL_TSF 0x00200000 /* Transmit Store and Forward */
+#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
+
+enum ttc_control {
+ DMA_CONTROL_TTC_64 = 0x00000000,
+ DMA_CONTROL_TTC_128 = 0x00004000,
+ DMA_CONTROL_TTC_192 = 0x00008000,
+ DMA_CONTROL_TTC_256 = 0x0000c000,
+ DMA_CONTROL_TTC_40 = 0x00010000,
+ DMA_CONTROL_TTC_32 = 0x00014000,
+ DMA_CONTROL_TTC_24 = 0x00018000,
+ DMA_CONTROL_TTC_16 = 0x0001c000,
+};
+#define DMA_CONTROL_TC_TX_MASK 0xfffe3fff
+
+#define DMA_CONTROL_EFC 0x00000100
+#define DMA_CONTROL_FEF 0x00000080
+#define DMA_CONTROL_FUF 0x00000040
+
+enum rtc_control {
+ DMA_CONTROL_RTC_64 = 0x00000000,
+ DMA_CONTROL_RTC_32 = 0x00000008,
+ DMA_CONTROL_RTC_96 = 0x00000010,
+ DMA_CONTROL_RTC_128 = 0x00000018,
+};
+#define DMA_CONTROL_TC_RX_MASK 0xffffffe7
+
+#define DMA_CONTROL_OSF 0x00000004 /* Operate on second frame */
+
+/* MMC registers offset */
+#define GMAC_MMC_CTRL 0x100
+#define GMAC_MMC_RX_INTR 0x104
+#define GMAC_MMC_TX_INTR 0x108
+#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
diff --git a/drivers/net/stmmac/mac100.c b/drivers/net/stmmac/mac100.c
new file mode 100644
index 000000000000..625171b6062b
--- /dev/null
+++ b/drivers/net/stmmac/mac100.c
@@ -0,0 +1,517 @@
+/*******************************************************************************
+ This is the driver for the MAC 10/100 on-chip Ethernet controller
+ currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
+
+ DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
+ this code.
+
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/netdevice.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include "common.h"
+#include "mac100.h"
+
+#undef MAC100_DEBUG
+/*#define MAC100_DEBUG*/
+#ifdef MAC100_DEBUG
+#define DBG(fmt, args...) printk(fmt, ## args)
+#else
+#define DBG(fmt, args...) do { } while (0)
+#endif
+
+static void mac100_core_init(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + MAC_CONTROL);
+
+ writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
+
+#ifdef STMMAC_VLAN_TAG_USED
+ writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
+#endif
+ return;
+}
+
+static void mac100_dump_mac_regs(unsigned long ioaddr)
+{
+ pr_info("\t----------------------------------------------\n"
+ "\t MAC100 CSR (base addr = 0x%8x)\n"
+ "\t----------------------------------------------\n",
+ (unsigned int)ioaddr);
+ pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
+ readl(ioaddr + MAC_CONTROL));
+ pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
+ readl(ioaddr + MAC_ADDR_HIGH));
+ pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
+ readl(ioaddr + MAC_ADDR_LOW));
+ pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
+ MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
+ pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
+ MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
+ pr_info("\tflow control (offset 0x%x): 0x%08x\n",
+ MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
+ pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
+ readl(ioaddr + MAC_VLAN1));
+ pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
+ readl(ioaddr + MAC_VLAN2));
+ pr_info("\n\tMAC management counter registers\n");
+ pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
+ MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
+ pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
+ MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
+ pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
+ MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
+ pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
+ MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
+ pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
+ MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
+ return;
+}
+
+static int mac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
+ u32 dma_rx)
+{
+ u32 value = readl(ioaddr + DMA_BUS_MODE);
+ /* DMA SW reset */
+ value |= DMA_BUS_MODE_SFT_RESET;
+ writel(value, ioaddr + DMA_BUS_MODE);
+ do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
+
+ /* Enable Application Access by writing to DMA CSR0 */
+ writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
+ ioaddr + DMA_BUS_MODE);
+
+ /* Mask interrupts by writing to CSR7 */
+ writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+
+ /* The base address of the RX/TX descriptor lists must be written into
+ * DMA CSR3 and CSR4, respectively. */
+ writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
+ writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
+
+ return 0;
+}
+
+/* Store and Forward capability is not used at all..
+ * The transmit threshold can be programmed by
+ * setting the TTC bits in the DMA control register.*/
+static void mac100_dma_operation_mode(unsigned long ioaddr, int txmode,
+ int rxmode)
+{
+ u32 csr6 = readl(ioaddr + DMA_CONTROL);
+
+ if (txmode <= 32)
+ csr6 |= DMA_CONTROL_TTC_32;
+ else if (txmode <= 64)
+ csr6 |= DMA_CONTROL_TTC_64;
+ else
+ csr6 |= DMA_CONTROL_TTC_128;
+
+ writel(csr6, ioaddr + DMA_CONTROL);
+
+ return;
+}
+
+static void mac100_dump_dma_regs(unsigned long ioaddr)
+{
+ int i;
+
+ DBG(KERN_DEBUG "MAC100 DMA CSR \n");
+ for (i = 0; i < 9; i++)
+ pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
+ (DMA_BUS_MODE + i * 4),
+ readl(ioaddr + DMA_BUS_MODE + i * 4));
+ DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
+ DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
+ DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
+ DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
+ return;
+}
+
+/* DMA controller has two counters to track the number of
+ the receive missed frames. */
+static void mac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
+ unsigned long ioaddr)
+{
+ struct net_device_stats *stats = (struct net_device_stats *)data;
+ u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
+
+ if (unlikely(csr8)) {
+ if (csr8 & DMA_MISSED_FRAME_OVE) {
+ stats->rx_over_errors += 0x800;
+ x->rx_overflow_cntr += 0x800;
+ } else {
+ unsigned int ove_cntr;
+ ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
+ stats->rx_over_errors += ove_cntr;
+ x->rx_overflow_cntr += ove_cntr;
+ }
+
+ if (csr8 & DMA_MISSED_FRAME_OVE_M) {
+ stats->rx_missed_errors += 0xffff;
+ x->rx_missed_cntr += 0xffff;
+ } else {
+ unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
+ stats->rx_missed_errors += miss_f;
+ x->rx_missed_cntr += miss_f;
+ }
+ }
+ return;
+}
+
+static int mac100_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p, unsigned long ioaddr)
+{
+ int ret = 0;
+ struct net_device_stats *stats = (struct net_device_stats *)data;
+
+ if (unlikely(p->des01.tx.error_summary)) {
+ if (unlikely(p->des01.tx.underflow_error)) {
+ x->tx_underflow++;
+ stats->tx_fifo_errors++;
+ }
+ if (unlikely(p->des01.tx.no_carrier)) {
+ x->tx_carrier++;
+ stats->tx_carrier_errors++;
+ }
+ if (unlikely(p->des01.tx.loss_carrier)) {
+ x->tx_losscarrier++;
+ stats->tx_carrier_errors++;
+ }
+ if (unlikely((p->des01.tx.excessive_deferral) ||
+ (p->des01.tx.excessive_collisions) ||
+ (p->des01.tx.late_collision)))
+ stats->collisions += p->des01.tx.collision_count;
+ ret = -1;
+ }
+ if (unlikely(p->des01.tx.heartbeat_fail)) {
+ x->tx_heartbeat++;
+ stats->tx_heartbeat_errors++;
+ ret = -1;
+ }
+ if (unlikely(p->des01.tx.deferred))
+ x->tx_deferred++;
+
+ return ret;
+}
+
+static int mac100_get_tx_len(struct dma_desc *p)
+{
+ return p->des01.tx.buffer1_size;
+}
+
+/* This function verifies if each incoming frame has some errors
+ * and, if required, updates the multicast statistics.
+ * In case of success, it returns csum_none becasue the device
+ * is not able to compute the csum in HW. */
+static int mac100_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p)
+{
+ int ret = csum_none;
+ struct net_device_stats *stats = (struct net_device_stats *)data;
+
+ if (unlikely(p->des01.rx.last_descriptor == 0)) {
+ pr_warning("mac100 Error: Oversized Ethernet "
+ "frame spanned multiple buffers\n");
+ stats->rx_length_errors++;
+ return discard_frame;
+ }
+
+ if (unlikely(p->des01.rx.error_summary)) {
+ if (unlikely(p->des01.rx.descriptor_error))
+ x->rx_desc++;
+ if (unlikely(p->des01.rx.partial_frame_error))
+ x->rx_partial++;
+ if (unlikely(p->des01.rx.run_frame))
+ x->rx_runt++;
+ if (unlikely(p->des01.rx.frame_too_long))
+ x->rx_toolong++;
+ if (unlikely(p->des01.rx.collision)) {
+ x->rx_collision++;
+ stats->collisions++;
+ }
+ if (unlikely(p->des01.rx.crc_error)) {
+ x->rx_crc++;
+ stats->rx_crc_errors++;
+ }
+ ret = discard_frame;
+ }
+ if (unlikely(p->des01.rx.dribbling))
+ ret = discard_frame;
+
+ if (unlikely(p->des01.rx.length_error)) {
+ x->rx_lenght++;
+ ret = discard_frame;
+ }
+ if (unlikely(p->des01.rx.mii_error)) {
+ x->rx_mii++;
+ ret = discard_frame;
+ }
+ if (p->des01.rx.multicast_frame) {
+ x->rx_multicast++;
+ stats->multicast++;
+ }
+ return ret;
+}
+
+static void mac100_irq_status(unsigned long ioaddr)
+{
+ return;
+}
+
+static void mac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+ unsigned int reg_n)
+{
+ stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
+}
+
+static void mac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+ unsigned int reg_n)
+{
+ stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
+}
+
+static void mac100_set_filter(struct net_device *dev)
+{
+ unsigned long ioaddr = dev->base_addr;
+ u32 value = readl(ioaddr + MAC_CONTROL);
+
+ if (dev->flags & IFF_PROMISC) {
+ value |= MAC_CONTROL_PR;
+ value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
+ MAC_CONTROL_HP);
+ } else if ((dev->mc_count > HASH_TABLE_SIZE)
+ || (dev->flags & IFF_ALLMULTI)) {
+ value |= MAC_CONTROL_PM;
+ value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
+ writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
+ writel(0xffffffff, ioaddr + MAC_HASH_LOW);
+ } else if (dev->mc_count == 0) { /* no multicast */
+ value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
+ MAC_CONTROL_HO | MAC_CONTROL_HP);
+ } else {
+ int i;
+ u32 mc_filter[2];
+ struct dev_mc_list *mclist;
+
+ /* Perfect filter mode for physical address and Hash
+ filter for multicast */
+ value |= MAC_CONTROL_HP;
+ value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF
+ | MAC_CONTROL_HO);
+
+ memset(mc_filter, 0, sizeof(mc_filter));
+ for (i = 0, mclist = dev->mc_list;
+ mclist && i < dev->mc_count; i++, mclist = mclist->next) {
+ /* The upper 6 bits of the calculated CRC are used to
+ * index the contens of the hash table */
+ int bit_nr =
+ ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+ /* The most significant bit determines the register to
+ * use (H/L) while the other 5 bits determine the bit
+ * within the register. */
+ mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+ }
+ writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
+ writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
+ }
+
+ writel(value, ioaddr + MAC_CONTROL);
+
+ DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
+ "HI 0x%08x, LO 0x%08x\n",
+ __func__, readl(ioaddr + MAC_CONTROL),
+ readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
+ return;
+}
+
+static void mac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+ unsigned int fc, unsigned int pause_time)
+{
+ unsigned int flow = MAC_FLOW_CTRL_ENABLE;
+
+ if (duplex)
+ flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
+ writel(flow, ioaddr + MAC_FLOW_CTRL);
+
+ return;
+}
+
+/* No PMT module supported in our SoC for the Ethernet Controller. */
+static void mac100_pmt(unsigned long ioaddr, unsigned long mode)
+{
+ return;
+}
+
+static void mac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic)
+{
+ int i;
+ for (i = 0; i < ring_size; i++) {
+ p->des01.rx.own = 1;
+ p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
+ if (i == ring_size - 1)
+ p->des01.rx.end_ring = 1;
+ if (disable_rx_ic)
+ p->des01.rx.disable_ic = 1;
+ p++;
+ }
+ return;
+}
+
+static void mac100_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+ int i;
+ for (i = 0; i < ring_size; i++) {
+ p->des01.tx.own = 0;
+ if (i == ring_size - 1)
+ p->des01.tx.end_ring = 1;
+ p++;
+ }
+ return;
+}
+
+static int mac100_get_tx_owner(struct dma_desc *p)
+{
+ return p->des01.tx.own;
+}
+
+static int mac100_get_rx_owner(struct dma_desc *p)
+{
+ return p->des01.rx.own;
+}
+
+static void mac100_set_tx_owner(struct dma_desc *p)
+{
+ p->des01.tx.own = 1;
+}
+
+static void mac100_set_rx_owner(struct dma_desc *p)
+{
+ p->des01.rx.own = 1;
+}
+
+static int mac100_get_tx_ls(struct dma_desc *p)
+{
+ return p->des01.tx.last_segment;
+}
+
+static void mac100_release_tx_desc(struct dma_desc *p)
+{
+ int ter = p->des01.tx.end_ring;
+
+ /* clean field used within the xmit */
+ p->des01.tx.first_segment = 0;
+ p->des01.tx.last_segment = 0;
+ p->des01.tx.buffer1_size = 0;
+
+ /* clean status reported */
+ p->des01.tx.error_summary = 0;
+ p->des01.tx.underflow_error = 0;
+ p->des01.tx.no_carrier = 0;
+ p->des01.tx.loss_carrier = 0;
+ p->des01.tx.excessive_deferral = 0;
+ p->des01.tx.excessive_collisions = 0;
+ p->des01.tx.late_collision = 0;
+ p->des01.tx.heartbeat_fail = 0;
+ p->des01.tx.deferred = 0;
+
+ /* set termination field */
+ p->des01.tx.end_ring = ter;
+
+ return;
+}
+
+static void mac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+ int csum_flag)
+{
+ p->des01.tx.first_segment = is_fs;
+ p->des01.tx.buffer1_size = len;
+}
+
+static void mac100_clear_tx_ic(struct dma_desc *p)
+{
+ p->des01.tx.interrupt = 0;
+}
+
+static void mac100_close_tx_desc(struct dma_desc *p)
+{
+ p->des01.tx.last_segment = 1;
+ p->des01.tx.interrupt = 1;
+}
+
+static int mac100_get_rx_frame_len(struct dma_desc *p)
+{
+ return p->des01.rx.frame_length;
+}
+
+struct stmmac_ops mac100_driver = {
+ .core_init = mac100_core_init,
+ .dump_mac_regs = mac100_dump_mac_regs,
+ .dma_init = mac100_dma_init,
+ .dump_dma_regs = mac100_dump_dma_regs,
+ .dma_mode = mac100_dma_operation_mode,
+ .dma_diagnostic_fr = mac100_dma_diagnostic_fr,
+ .tx_status = mac100_get_tx_frame_status,
+ .rx_status = mac100_get_rx_frame_status,
+ .get_tx_len = mac100_get_tx_len,
+ .set_filter = mac100_set_filter,
+ .flow_ctrl = mac100_flow_ctrl,
+ .pmt = mac100_pmt,
+ .init_rx_desc = mac100_init_rx_desc,
+ .init_tx_desc = mac100_init_tx_desc,
+ .get_tx_owner = mac100_get_tx_owner,
+ .get_rx_owner = mac100_get_rx_owner,
+ .release_tx_desc = mac100_release_tx_desc,
+ .prepare_tx_desc = mac100_prepare_tx_desc,
+ .clear_tx_ic = mac100_clear_tx_ic,
+ .close_tx_desc = mac100_close_tx_desc,
+ .get_tx_ls = mac100_get_tx_ls,
+ .set_tx_owner = mac100_set_tx_owner,
+ .set_rx_owner = mac100_set_rx_owner,
+ .get_rx_frame_len = mac100_get_rx_frame_len,
+ .host_irq_status = mac100_irq_status,
+ .set_umac_addr = mac100_set_umac_addr,
+ .get_umac_addr = mac100_get_umac_addr,
+};
+
+struct mac_device_info *mac100_setup(unsigned long ioaddr)
+{
+ struct mac_device_info *mac;
+
+ mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
+
+ pr_info("\tMAC 10/100\n");
+
+ mac->ops = &mac100_driver;
+ mac->hw.pmt = PMT_NOT_SUPPORTED;
+ mac->hw.link.port = MAC_CONTROL_PS;
+ mac->hw.link.duplex = MAC_CONTROL_F;
+ mac->hw.link.speed = 0;
+ mac->hw.mii.addr = MAC_MII_ADDR;
+ mac->hw.mii.data = MAC_MII_DATA;
+
+ return mac;
+}
diff --git a/drivers/net/stmmac/mac100.h b/drivers/net/stmmac/mac100.h
new file mode 100644
index 000000000000..0f8f110d004a
--- /dev/null
+++ b/drivers/net/stmmac/mac100.h
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ MAC 10/100 Header File
+
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * MAC BLOCK defines
+ *---------------------------------------------------------------------------*/
+/* MAC CSR offset */
+#define MAC_CONTROL 0x00000000 /* MAC Control */
+#define MAC_ADDR_HIGH 0x00000004 /* MAC Address High */
+#define MAC_ADDR_LOW 0x00000008 /* MAC Address Low */
+#define MAC_HASH_HIGH 0x0000000c /* Multicast Hash Table High */
+#define MAC_HASH_LOW 0x00000010 /* Multicast Hash Table Low */
+#define MAC_MII_ADDR 0x00000014 /* MII Address */
+#define MAC_MII_DATA 0x00000018 /* MII Data */
+#define MAC_FLOW_CTRL 0x0000001c /* Flow Control */
+#define MAC_VLAN1 0x00000020 /* VLAN1 Tag */
+#define MAC_VLAN2 0x00000024 /* VLAN2 Tag */
+
+/* MAC CTRL defines */
+#define MAC_CONTROL_RA 0x80000000 /* Receive All Mode */
+#define MAC_CONTROL_BLE 0x40000000 /* Endian Mode */
+#define MAC_CONTROL_HBD 0x10000000 /* Heartbeat Disable */
+#define MAC_CONTROL_PS 0x08000000 /* Port Select */
+#define MAC_CONTROL_DRO 0x00800000 /* Disable Receive Own */
+#define MAC_CONTROL_EXT_LOOPBACK 0x00400000 /* Reserved (ext loopback?) */
+#define MAC_CONTROL_OM 0x00200000 /* Loopback Operating Mode */
+#define MAC_CONTROL_F 0x00100000 /* Full Duplex Mode */
+#define MAC_CONTROL_PM 0x00080000 /* Pass All Multicast */
+#define MAC_CONTROL_PR 0x00040000 /* Promiscuous Mode */
+#define MAC_CONTROL_IF 0x00020000 /* Inverse Filtering */
+#define MAC_CONTROL_PB 0x00010000 /* Pass Bad Frames */
+#define MAC_CONTROL_HO 0x00008000 /* Hash Only Filtering Mode */
+#define MAC_CONTROL_HP 0x00002000 /* Hash/Perfect Filtering Mode */
+#define MAC_CONTROL_LCC 0x00001000 /* Late Collision Control */
+#define MAC_CONTROL_DBF 0x00000800 /* Disable Broadcast Frames */
+#define MAC_CONTROL_DRTY 0x00000400 /* Disable Retry */
+#define MAC_CONTROL_ASTP 0x00000100 /* Automatic Pad Stripping */
+#define MAC_CONTROL_BOLMT_10 0x00000000 /* Back Off Limit 10 */
+#define MAC_CONTROL_BOLMT_8 0x00000040 /* Back Off Limit 8 */
+#define MAC_CONTROL_BOLMT_4 0x00000080 /* Back Off Limit 4 */
+#define MAC_CONTROL_BOLMT_1 0x000000c0 /* Back Off Limit 1 */
+#define MAC_CONTROL_DC 0x00000020 /* Deferral Check */
+#define MAC_CONTROL_TE 0x00000008 /* Transmitter Enable */
+#define MAC_CONTROL_RE 0x00000004 /* Receiver Enable */
+
+#define MAC_CORE_INIT (MAC_CONTROL_HBD | MAC_CONTROL_ASTP)
+
+/* MAC FLOW CTRL defines */
+#define MAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */
+#define MAC_FLOW_CTRL_PT_SHIFT 16
+#define MAC_FLOW_CTRL_PASS 0x00000004 /* Pass Control Frames */
+#define MAC_FLOW_CTRL_ENABLE 0x00000002 /* Flow Control Enable */
+#define MAC_FLOW_CTRL_PAUSE 0x00000001 /* Flow Control Busy ... */
+
+/* MII ADDR defines */
+#define MAC_MII_ADDR_WRITE 0x00000002 /* MII Write */
+#define MAC_MII_ADDR_BUSY 0x00000001 /* MII Busy */
+
+/*----------------------------------------------------------------------------
+ * DMA BLOCK defines
+ *---------------------------------------------------------------------------*/
+
+/* DMA Bus Mode register defines */
+#define DMA_BUS_MODE_DBO 0x00100000 /* Descriptor Byte Ordering */
+#define DMA_BUS_MODE_BLE 0x00000080 /* Big Endian/Little Endian */
+#define DMA_BUS_MODE_PBL_MASK 0x00003f00 /* Programmable Burst Len */
+#define DMA_BUS_MODE_PBL_SHIFT 8
+#define DMA_BUS_MODE_DSL_MASK 0x0000007c /* Descriptor Skip Length */
+#define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */
+#define DMA_BUS_MODE_BAR_BUS 0x00000002 /* Bar-Bus Arbitration */
+#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */
+#define DMA_BUS_MODE_DEFAULT 0x00000000
+
+/* DMA Control register defines */
+#define DMA_CONTROL_SF 0x00200000 /* Store And Forward */
+
+/* Transmit Threshold Control */
+enum ttc_control {
+ DMA_CONTROL_TTC_DEFAULT = 0x00000000, /* Threshold is 32 DWORDS */
+ DMA_CONTROL_TTC_64 = 0x00004000, /* Threshold is 64 DWORDS */
+ DMA_CONTROL_TTC_128 = 0x00008000, /* Threshold is 128 DWORDS */
+ DMA_CONTROL_TTC_256 = 0x0000c000, /* Threshold is 256 DWORDS */
+ DMA_CONTROL_TTC_18 = 0x00400000, /* Threshold is 18 DWORDS */
+ DMA_CONTROL_TTC_24 = 0x00404000, /* Threshold is 24 DWORDS */
+ DMA_CONTROL_TTC_32 = 0x00408000, /* Threshold is 32 DWORDS */
+ DMA_CONTROL_TTC_40 = 0x0040c000, /* Threshold is 40 DWORDS */
+ DMA_CONTROL_SE = 0x00000008, /* Stop On Empty */
+ DMA_CONTROL_OSF = 0x00000004, /* Operate On 2nd Frame */
+};
+
+/* STMAC110 DMA Missed Frame Counter register defines */
+#define DMA_MISSED_FRAME_OVE 0x10000000 /* FIFO Overflow Overflow */
+#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000 /* Overflow Frame Counter */
+#define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */
+#define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
new file mode 100644
index 000000000000..6d2eae3040e5
--- /dev/null
+++ b/drivers/net/stmmac/stmmac.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#define DRV_MODULE_VERSION "Oct_09"
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define STMMAC_VLAN_TAG_USED
+#include <linux/if_vlan.h>
+#endif
+
+#include "common.h"
+#ifdef CONFIG_STMMAC_TIMER
+#include "stmmac_timer.h"
+#endif
+
+struct stmmac_priv {
+ /* Frequently used values are kept adjacent for cache effect */
+ struct dma_desc *dma_tx ____cacheline_aligned;
+ dma_addr_t dma_tx_phy;
+ struct sk_buff **tx_skbuff;
+ unsigned int cur_tx;
+ unsigned int dirty_tx;
+ unsigned int dma_tx_size;
+ int tx_coe;
+ int tx_coalesce;
+
+ struct dma_desc *dma_rx ;
+ unsigned int cur_rx;
+ unsigned int dirty_rx;
+ struct sk_buff **rx_skbuff;
+ dma_addr_t *rx_skbuff_dma;
+ struct sk_buff_head rx_recycle;
+
+ struct net_device *dev;
+ int is_gmac;
+ dma_addr_t dma_rx_phy;
+ unsigned int dma_rx_size;
+ int rx_csum;
+ unsigned int dma_buf_sz;
+ struct device *device;
+ struct mac_device_info *mac_type;
+
+ struct stmmac_extra_stats xstats;
+ struct napi_struct napi;
+
+ phy_interface_t phy_interface;
+ int pbl;
+ int bus_id;
+ int phy_addr;
+ int phy_mask;
+ int (*phy_reset) (void *priv);
+ void (*fix_mac_speed) (void *priv, unsigned int speed);
+ void *bsp_priv;
+
+ int phy_irq;
+ struct phy_device *phydev;
+ int oldlink;
+ int speed;
+ int oldduplex;
+ unsigned int flow_ctrl;
+ unsigned int pause;
+ struct mii_bus *mii;
+
+ u32 msg_enable;
+ spinlock_t lock;
+ int wolopts;
+ int wolenabled;
+ int shutdown;
+#ifdef CONFIG_STMMAC_TIMER
+ struct stmmac_timer *tm;
+#endif
+#ifdef STMMAC_VLAN_TAG_USED
+ struct vlan_group *vlgrp;
+#endif
+};
+
+extern int stmmac_mdio_unregister(struct net_device *ndev);
+extern int stmmac_mdio_register(struct net_device *ndev);
+extern void stmmac_set_ethtool_ops(struct net_device *netdev);
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
new file mode 100644
index 000000000000..694ebe6a0758
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -0,0 +1,395 @@
+/*******************************************************************************
+ STMMAC Ethtool support
+
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include "stmmac.h"
+
+#define REG_SPACE_SIZE 0x1054
+#define MAC100_ETHTOOL_NAME "st_mac100"
+#define GMAC_ETHTOOL_NAME "st_gmac"
+
+struct stmmac_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int sizeof_stat;
+ int stat_offset;
+};
+
+#define STMMAC_STAT(m) \
+ { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m), \
+ offsetof(struct stmmac_priv, xstats.m)}
+
+static const struct stmmac_stats stmmac_gstrings_stats[] = {
+ STMMAC_STAT(tx_underflow),
+ STMMAC_STAT(tx_carrier),
+ STMMAC_STAT(tx_losscarrier),
+ STMMAC_STAT(tx_heartbeat),
+ STMMAC_STAT(tx_deferred),
+ STMMAC_STAT(tx_vlan),
+ STMMAC_STAT(rx_vlan),
+ STMMAC_STAT(tx_jabber),
+ STMMAC_STAT(tx_frame_flushed),
+ STMMAC_STAT(tx_payload_error),
+ STMMAC_STAT(tx_ip_header_error),
+ STMMAC_STAT(rx_desc),
+ STMMAC_STAT(rx_partial),
+ STMMAC_STAT(rx_runt),
+ STMMAC_STAT(rx_toolong),
+ STMMAC_STAT(rx_collision),
+ STMMAC_STAT(rx_crc),
+ STMMAC_STAT(rx_lenght),
+ STMMAC_STAT(rx_mii),
+ STMMAC_STAT(rx_multicast),
+ STMMAC_STAT(rx_gmac_overflow),
+ STMMAC_STAT(rx_watchdog),
+ STMMAC_STAT(da_rx_filter_fail),
+ STMMAC_STAT(sa_rx_filter_fail),
+ STMMAC_STAT(rx_missed_cntr),
+ STMMAC_STAT(rx_overflow_cntr),
+ STMMAC_STAT(tx_undeflow_irq),
+ STMMAC_STAT(tx_process_stopped_irq),
+ STMMAC_STAT(tx_jabber_irq),
+ STMMAC_STAT(rx_overflow_irq),
+ STMMAC_STAT(rx_buf_unav_irq),
+ STMMAC_STAT(rx_process_stopped_irq),
+ STMMAC_STAT(rx_watchdog_irq),
+ STMMAC_STAT(tx_early_irq),
+ STMMAC_STAT(fatal_bus_error_irq),
+ STMMAC_STAT(threshold),
+ STMMAC_STAT(tx_pkt_n),
+ STMMAC_STAT(rx_pkt_n),
+ STMMAC_STAT(poll_n),
+ STMMAC_STAT(sched_timer_n),
+ STMMAC_STAT(normal_irq_n),
+};
+#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
+
+void stmmac_ethtool_getdrvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ if (!priv->is_gmac)
+ strcpy(info->driver, MAC100_ETHTOOL_NAME);
+ else
+ strcpy(info->driver, GMAC_ETHTOOL_NAME);
+
+ strcpy(info->version, DRV_MODULE_VERSION);
+ info->fw_version[0] = '\0';
+ info->n_stats = STMMAC_STATS_LEN;
+ return;
+}
+
+int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ struct phy_device *phy = priv->phydev;
+ int rc;
+ if (phy == NULL) {
+ pr_err("%s: %s: PHY is not registered\n",
+ __func__, dev->name);
+ return -ENODEV;
+ }
+ if (!netif_running(dev)) {
+ pr_err("%s: interface is disabled: we cannot track "
+ "link speed / duplex setting\n", dev->name);
+ return -EBUSY;
+ }
+ cmd->transceiver = XCVR_INTERNAL;
+ spin_lock_irq(&priv->lock);
+ rc = phy_ethtool_gset(phy, cmd);
+ spin_unlock_irq(&priv->lock);
+ return rc;
+}
+
+int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ struct phy_device *phy = priv->phydev;
+ int rc;
+
+ spin_lock(&priv->lock);
+ rc = phy_ethtool_sset(phy, cmd);
+ spin_unlock(&priv->lock);
+
+ return rc;
+}
+
+u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ return priv->msg_enable;
+}
+
+void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ priv->msg_enable = level;
+
+}
+
+int stmmac_check_if_running(struct net_device *dev)
+{
+ if (!netif_running(dev))
+ return -EBUSY;
+ return 0;
+}
+
+int stmmac_ethtool_get_regs_len(struct net_device *dev)
+{
+ return REG_SPACE_SIZE;
+}
+
+void stmmac_ethtool_gregs(struct net_device *dev,
+ struct ethtool_regs *regs, void *space)
+{
+ int i;
+ u32 *reg_space = (u32 *) space;
+
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ memset(reg_space, 0x0, REG_SPACE_SIZE);
+
+ if (!priv->is_gmac) {
+ /* MAC registers */
+ for (i = 0; i < 12; i++)
+ reg_space[i] = readl(dev->base_addr + (i * 4));
+ /* DMA registers */
+ for (i = 0; i < 9; i++)
+ reg_space[i + 12] =
+ readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
+ reg_space[22] = readl(dev->base_addr + DMA_CUR_TX_BUF_ADDR);
+ reg_space[23] = readl(dev->base_addr + DMA_CUR_RX_BUF_ADDR);
+ } else {
+ /* MAC registers */
+ for (i = 0; i < 55; i++)
+ reg_space[i] = readl(dev->base_addr + (i * 4));
+ /* DMA registers */
+ for (i = 0; i < 22; i++)
+ reg_space[i + 55] =
+ readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
+ }
+
+ return;
+}
+
+int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
+{
+ if (data)
+ netdev->features |= NETIF_F_HW_CSUM;
+ else
+ netdev->features &= ~NETIF_F_HW_CSUM;
+
+ return 0;
+}
+
+u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ return priv->rx_csum;
+}
+
+static void
+stmmac_get_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct stmmac_priv *priv = netdev_priv(netdev);
+
+ spin_lock(&priv->lock);
+
+ pause->rx_pause = 0;
+ pause->tx_pause = 0;
+ pause->autoneg = priv->phydev->autoneg;
+
+ if (priv->flow_ctrl & FLOW_RX)
+ pause->rx_pause = 1;
+ if (priv->flow_ctrl & FLOW_TX)
+ pause->tx_pause = 1;
+
+ spin_unlock(&priv->lock);
+ return;
+}
+
+static int
+stmmac_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct stmmac_priv *priv = netdev_priv(netdev);
+ struct phy_device *phy = priv->phydev;
+ int new_pause = FLOW_OFF;
+ int ret = 0;
+
+ spin_lock(&priv->lock);
+
+ if (pause->rx_pause)
+ new_pause |= FLOW_RX;
+ if (pause->tx_pause)
+ new_pause |= FLOW_TX;
+
+ priv->flow_ctrl = new_pause;
+
+ if (phy->autoneg) {
+ if (netif_running(netdev)) {
+ struct ethtool_cmd cmd;
+ /* auto-negotiation automatically restarted */
+ cmd.cmd = ETHTOOL_NWAY_RST;
+ cmd.supported = phy->supported;
+ cmd.advertising = phy->advertising;
+ cmd.autoneg = phy->autoneg;
+ cmd.speed = phy->speed;
+ cmd.duplex = phy->duplex;
+ cmd.phy_address = phy->addr;
+ ret = phy_ethtool_sset(phy, &cmd);
+ }
+ } else {
+ unsigned long ioaddr = netdev->base_addr;
+ priv->mac_type->ops->flow_ctrl(ioaddr, phy->duplex,
+ priv->flow_ctrl, priv->pause);
+ }
+ spin_unlock(&priv->lock);
+ return ret;
+}
+
+static void stmmac_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *dummy, u64 *data)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ unsigned long ioaddr = dev->base_addr;
+ int i;
+
+ /* Update HW stats if supported */
+ priv->mac_type->ops->dma_diagnostic_fr(&dev->stats, &priv->xstats,
+ ioaddr);
+
+ for (i = 0; i < STMMAC_STATS_LEN; i++) {
+ char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
+ data[i] = (stmmac_gstrings_stats[i].sizeof_stat ==
+ sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
+ }
+
+ return;
+}
+
+static int stmmac_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return STMMAC_STATS_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+ int i;
+ u8 *p = data;
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < STMMAC_STATS_LEN; i++) {
+ memcpy(p, stmmac_gstrings_stats[i].stat_string,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ return;
+}
+
+/* Currently only support WOL through Magic packet. */
+static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ spin_lock_irq(&priv->lock);
+ if (priv->wolenabled == PMT_SUPPORTED) {
+ wol->supported = WAKE_MAGIC;
+ wol->wolopts = priv->wolopts;
+ }
+ spin_unlock_irq(&priv->lock);
+}
+
+static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ u32 support = WAKE_MAGIC;
+
+ if (priv->wolenabled == PMT_NOT_SUPPORTED)
+ return -EINVAL;
+
+ if (wol->wolopts & ~support)
+ return -EINVAL;
+
+ if (wol->wolopts == 0)
+ device_set_wakeup_enable(priv->device, 0);
+ else
+ device_set_wakeup_enable(priv->device, 1);
+
+ spin_lock_irq(&priv->lock);
+ priv->wolopts = wol->wolopts;
+ spin_unlock_irq(&priv->lock);
+
+ return 0;
+}
+
+static struct ethtool_ops stmmac_ethtool_ops = {
+ .begin = stmmac_check_if_running,
+ .get_drvinfo = stmmac_ethtool_getdrvinfo,
+ .get_settings = stmmac_ethtool_getsettings,
+ .set_settings = stmmac_ethtool_setsettings,
+ .get_msglevel = stmmac_ethtool_getmsglevel,
+ .set_msglevel = stmmac_ethtool_setmsglevel,
+ .get_regs = stmmac_ethtool_gregs,
+ .get_regs_len = stmmac_ethtool_get_regs_len,
+ .get_link = ethtool_op_get_link,
+ .get_rx_csum = stmmac_ethtool_get_rx_csum,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = stmmac_ethtool_set_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_pauseparam = stmmac_get_pauseparam,
+ .set_pauseparam = stmmac_set_pauseparam,
+ .get_ethtool_stats = stmmac_get_ethtool_stats,
+ .get_strings = stmmac_get_strings,
+ .get_wol = stmmac_get_wol,
+ .set_wol = stmmac_set_wol,
+ .get_sset_count = stmmac_get_sset_count,
+#ifdef NETIF_F_TSO
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = ethtool_op_set_tso,
+#endif
+};
+
+void stmmac_set_ethtool_ops(struct net_device *netdev)
+{
+ SET_ETHTOOL_OPS(netdev, &stmmac_ethtool_ops);
+}
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
new file mode 100644
index 000000000000..9542995ba667
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -0,0 +1,2210 @@
+/*******************************************************************************
+ This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers.
+ ST Ethernet IPs are built around a Synopsys IP Core.
+
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+
+ Documentation available at:
+ http://www.stlinux.com
+ Support available at:
+ https://bugzilla.stlinux.com/
+*******************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/if_ether.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/if_vlan.h>
+#include <linux/dma-mapping.h>
+#include <linux/stm/soc.h>
+#include "stmmac.h"
+
+#define STMMAC_RESOURCE_NAME "stmmaceth"
+#define PHY_RESOURCE_NAME "stmmacphy"
+
+#undef STMMAC_DEBUG
+/*#define STMMAC_DEBUG*/
+#ifdef STMMAC_DEBUG
+#define DBG(nlevel, klevel, fmt, args...) \
+ ((void)(netif_msg_##nlevel(priv) && \
+ printk(KERN_##klevel fmt, ## args)))
+#else
+#define DBG(nlevel, klevel, fmt, args...) do { } while (0)
+#endif
+
+#undef STMMAC_RX_DEBUG
+/*#define STMMAC_RX_DEBUG*/
+#ifdef STMMAC_RX_DEBUG
+#define RX_DBG(fmt, args...) printk(fmt, ## args)
+#else
+#define RX_DBG(fmt, args...) do { } while (0)
+#endif
+
+#undef STMMAC_XMIT_DEBUG
+/*#define STMMAC_XMIT_DEBUG*/
+#ifdef STMMAC_TX_DEBUG
+#define TX_DBG(fmt, args...) printk(fmt, ## args)
+#else
+#define TX_DBG(fmt, args...) do { } while (0)
+#endif
+
+#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
+#define JUMBO_LEN 9000
+
+/* Module parameters */
+#define TX_TIMEO 5000 /* default 5 seconds */
+static int watchdog = TX_TIMEO;
+module_param(watchdog, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds");
+
+static int debug = -1; /* -1: default, 0: no output, 16: all */
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)");
+
+static int phyaddr = -1;
+module_param(phyaddr, int, S_IRUGO);
+MODULE_PARM_DESC(phyaddr, "Physical device address");
+
+#define DMA_TX_SIZE 256
+static int dma_txsize = DMA_TX_SIZE;
+module_param(dma_txsize, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list");
+
+#define DMA_RX_SIZE 256
+static int dma_rxsize = DMA_RX_SIZE;
+module_param(dma_rxsize, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list");
+
+static int flow_ctrl = FLOW_OFF;
+module_param(flow_ctrl, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]");
+
+static int pause = PAUSE_TIME;
+module_param(pause, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(pause, "Flow Control Pause Time");
+
+#define TC_DEFAULT 64
+static int tc = TC_DEFAULT;
+module_param(tc, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(tc, "DMA threshold control value");
+
+#define RX_NO_COALESCE 1 /* Always interrupt on completion */
+#define TX_NO_COALESCE -1 /* No moderation by default */
+
+/* Pay attention to tune this parameter; take care of both
+ * hardware capability and network stabitily/performance impact.
+ * Many tests showed that ~4ms latency seems to be good enough. */
+#ifdef CONFIG_STMMAC_TIMER
+#define DEFAULT_PERIODIC_RATE 256
+static int tmrate = DEFAULT_PERIODIC_RATE;
+module_param(tmrate, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)");
+#endif
+
+#define DMA_BUFFER_SIZE BUF_SIZE_2KiB
+static int buf_sz = DMA_BUFFER_SIZE;
+module_param(buf_sz, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(buf_sz, "DMA buffer size");
+
+/* In case of Giga ETH, we can enable/disable the COE for the
+ * transmit HW checksum computation.
+ * Note that, if tx csum is off in HW, SG will be still supported. */
+static int tx_coe = HW_CSUM;
+module_param(tx_coe, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(tx_coe, "GMAC COE type 2 [on/off]");
+
+static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
+ NETIF_MSG_LINK | NETIF_MSG_IFUP |
+ NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
+
+static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
+static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev);
+
+/**
+ * stmmac_verify_args - verify the driver parameters.
+ * Description: it verifies if some wrong parameter is passed to the driver.
+ * Note that wrong parameters are replaced with the default values.
+ */
+static void stmmac_verify_args(void)
+{
+ if (unlikely(watchdog < 0))
+ watchdog = TX_TIMEO;
+ if (unlikely(dma_rxsize < 0))
+ dma_rxsize = DMA_RX_SIZE;
+ if (unlikely(dma_txsize < 0))
+ dma_txsize = DMA_TX_SIZE;
+ if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
+ buf_sz = DMA_BUFFER_SIZE;
+ if (unlikely(flow_ctrl > 1))
+ flow_ctrl = FLOW_AUTO;
+ else if (likely(flow_ctrl < 0))
+ flow_ctrl = FLOW_OFF;
+ if (unlikely((pause < 0) || (pause > 0xffff)))
+ pause = PAUSE_TIME;
+
+ return;
+}
+
+#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
+static void print_pkt(unsigned char *buf, int len)
+{
+ int j;
+ pr_info("len = %d byte, buf addr: 0x%p", len, buf);
+ for (j = 0; j < len; j++) {
+ if ((j % 16) == 0)
+ pr_info("\n %03x:", j);
+ pr_info(" %02x", buf[j]);
+ }
+ pr_info("\n");
+ return;
+}
+#endif
+
+/* minimum number of free TX descriptors required to wake up TX process */
+#define STMMAC_TX_THRESH(x) (x->dma_tx_size/4)
+
+static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
+{
+ return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
+}
+
+/**
+ * stmmac_adjust_link
+ * @dev: net device structure
+ * Description: it adjusts the link parameters.
+ */
+static void stmmac_adjust_link(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ struct phy_device *phydev = priv->phydev;
+ unsigned long ioaddr = dev->base_addr;
+ unsigned long flags;
+ int new_state = 0;
+ unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
+
+ if (phydev == NULL)
+ return;
+
+ DBG(probe, DEBUG, "stmmac_adjust_link: called. address %d link %d\n",
+ phydev->addr, phydev->link);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (phydev->link) {
+ u32 ctrl = readl(ioaddr + MAC_CTRL_REG);
+
+ /* Now we make sure that we can be in full duplex mode.
+ * If not, we operate in half-duplex mode. */
+ if (phydev->duplex != priv->oldduplex) {
+ new_state = 1;
+ if (!(phydev->duplex))
+ ctrl &= ~priv->mac_type->hw.link.duplex;
+ else
+ ctrl |= priv->mac_type->hw.link.duplex;
+ priv->oldduplex = phydev->duplex;
+ }
+ /* Flow Control operation */
+ if (phydev->pause)
+ priv->mac_type->ops->flow_ctrl(ioaddr, phydev->duplex,
+ fc, pause_time);
+
+ if (phydev->speed != priv->speed) {
+ new_state = 1;
+ switch (phydev->speed) {
+ case 1000:
+ if (likely(priv->is_gmac))
+ ctrl &= ~priv->mac_type->hw.link.port;
+ break;
+ case 100:
+ case 10:
+ if (priv->is_gmac) {
+ ctrl |= priv->mac_type->hw.link.port;
+ if (phydev->speed == SPEED_100) {
+ ctrl |=
+ priv->mac_type->hw.link.
+ speed;
+ } else {
+ ctrl &=
+ ~(priv->mac_type->hw.
+ link.speed);
+ }
+ } else {
+ ctrl &= ~priv->mac_type->hw.link.port;
+ }
+ priv->fix_mac_speed(priv->bsp_priv,
+ phydev->speed);
+ break;
+ default:
+ if (netif_msg_link(priv))
+ pr_warning("%s: Speed (%d) is not 10"
+ " or 100!\n", dev->name, phydev->speed);
+ break;
+ }
+
+ priv->speed = phydev->speed;
+ }
+
+ writel(ctrl, ioaddr + MAC_CTRL_REG);
+
+ if (!priv->oldlink) {
+ new_state = 1;
+ priv->oldlink = 1;
+ }
+ } else if (priv->oldlink) {
+ new_state = 1;
+ priv->oldlink = 0;
+ priv->speed = 0;
+ priv->oldduplex = -1;
+ }
+
+ if (new_state && netif_msg_link(priv))
+ phy_print_status(phydev);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
+}
+
+/**
+ * stmmac_init_phy - PHY initialization
+ * @dev: net device structure
+ * Description: it initializes the driver's PHY state, and attaches the PHY
+ * to the mac driver.
+ * Return value:
+ * 0 on success
+ */
+static int stmmac_init_phy(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ struct phy_device *phydev;
+ char phy_id[BUS_ID_SIZE]; /* PHY to connect */
+ char bus_id[BUS_ID_SIZE];
+
+ priv->oldlink = 0;
+ priv->speed = 0;
+ priv->oldduplex = -1;
+
+ if (priv->phy_addr == -1) {
+ /* We don't have a PHY, so do nothing */
+ return 0;
+ }
+
+ snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->bus_id);
+ snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, bus_id, priv->phy_addr);
+ pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
+
+ phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
+ priv->phy_interface);
+
+ if (IS_ERR(phydev)) {
+ pr_err("%s: Could not attach to PHY\n", dev->name);
+ return PTR_ERR(phydev);
+ }
+
+ /*
+ * Broken HW is sometimes missing the pull-up resistor on the
+ * MDIO line, which results in reads to non-existent devices returning
+ * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
+ * device as well.
+ * Note: phydev->phy_id is the result of reading the UID PHY registers.
+ */
+ if (phydev->phy_id == 0) {
+ phy_disconnect(phydev);
+ return -ENODEV;
+ }
+ pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)"
+ " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
+
+ priv->phydev = phydev;
+
+ return 0;
+}
+
+static inline void stmmac_mac_enable_rx(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + MAC_CTRL_REG);
+ value |= MAC_RNABLE_RX;
+ /* Set the RE (receive enable bit into the MAC CTRL register). */
+ writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+static inline void stmmac_mac_enable_tx(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + MAC_CTRL_REG);
+ value |= MAC_ENABLE_TX;
+ /* Set the TE (transmit enable bit into the MAC CTRL register). */
+ writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+static inline void stmmac_mac_disable_rx(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + MAC_CTRL_REG);
+ value &= ~MAC_RNABLE_RX;
+ writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+static inline void stmmac_mac_disable_tx(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + MAC_CTRL_REG);
+ value &= ~MAC_ENABLE_TX;
+ writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+/**
+ * display_ring
+ * @p: pointer to the ring.
+ * @size: size of the ring.
+ * Description: display all the descriptors within the ring.
+ */
+static void display_ring(struct dma_desc *p, int size)
+{
+ struct tmp_s {
+ u64 a;
+ unsigned int b;
+ unsigned int c;
+ };
+ int i;
+ for (i = 0; i < size; i++) {
+ struct tmp_s *x = (struct tmp_s *)(p + i);
+ pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
+ i, (unsigned int)virt_to_phys(&p[i]),
+ (unsigned int)(x->a), (unsigned int)((x->a) >> 32),
+ x->b, x->c);
+ pr_info("\n");
+ }
+}
+
+/**
+ * init_dma_desc_rings - init the RX/TX descriptor rings
+ * @dev: net device structure
+ * Description: this function initializes the DMA RX/TX descriptors
+ * and allocates the socket buffers.
+ */
+static void init_dma_desc_rings(struct net_device *dev)
+{
+ int i;
+ struct stmmac_priv *priv = netdev_priv(dev);
+ struct sk_buff *skb;
+ unsigned int txsize = priv->dma_tx_size;
+ unsigned int rxsize = priv->dma_rx_size;
+ unsigned int bfsize = priv->dma_buf_sz;
+ int buff2_needed = 0, dis_ic = 0;
+
+ /* Set the Buffer size according to the MTU;
+ * indeed, in case of jumbo we need to bump-up the buffer sizes.
+ */
+ if (unlikely(dev->mtu >= BUF_SIZE_8KiB))
+ bfsize = BUF_SIZE_16KiB;
+ else if (unlikely(dev->mtu >= BUF_SIZE_4KiB))
+ bfsize = BUF_SIZE_8KiB;
+ else if (unlikely(dev->mtu >= BUF_SIZE_2KiB))
+ bfsize = BUF_SIZE_4KiB;
+ else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE))
+ bfsize = BUF_SIZE_2KiB;
+ else
+ bfsize = DMA_BUFFER_SIZE;
+
+#ifdef CONFIG_STMMAC_TIMER
+ /* Disable interrupts on completion for the reception if timer is on */
+ if (likely(priv->tm->enable))
+ dis_ic = 1;
+#endif
+ /* If the MTU exceeds 8k so use the second buffer in the chain */
+ if (bfsize >= BUF_SIZE_8KiB)
+ buff2_needed = 1;
+
+ DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
+ txsize, rxsize, bfsize);
+
+ priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL);
+ priv->rx_skbuff =
+ kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL);
+ priv->dma_rx =
+ (struct dma_desc *)dma_alloc_coherent(priv->device,
+ rxsize *
+ sizeof(struct dma_desc),
+ &priv->dma_rx_phy,
+ GFP_KERNEL);
+ priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize,
+ GFP_KERNEL);
+ priv->dma_tx =
+ (struct dma_desc *)dma_alloc_coherent(priv->device,
+ txsize *
+ sizeof(struct dma_desc),
+ &priv->dma_tx_phy,
+ GFP_KERNEL);
+
+ if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) {
+ pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__);
+ return;
+ }
+
+ DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, "
+ "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
+ dev->name, priv->dma_rx, priv->dma_tx,
+ (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
+
+ /* RX INITIALIZATION */
+ DBG(probe, INFO, "stmmac: SKB addresses:\n"
+ "skb\t\tskb data\tdma data\n");
+
+ for (i = 0; i < rxsize; i++) {
+ struct dma_desc *p = priv->dma_rx + i;
+
+ skb = netdev_alloc_skb_ip_align(dev, bfsize);
+ if (unlikely(skb == NULL)) {
+ pr_err("%s: Rx init fails; skb is NULL\n", __func__);
+ break;
+ }
+ priv->rx_skbuff[i] = skb;
+ priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
+ bfsize, DMA_FROM_DEVICE);
+
+ p->des2 = priv->rx_skbuff_dma[i];
+ if (unlikely(buff2_needed))
+ p->des3 = p->des2 + BUF_SIZE_8KiB;
+ DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
+ priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
+ }
+ priv->cur_rx = 0;
+ priv->dirty_rx = (unsigned int)(i - rxsize);
+ priv->dma_buf_sz = bfsize;
+ buf_sz = bfsize;
+
+ /* TX INITIALIZATION */
+ for (i = 0; i < txsize; i++) {
+ priv->tx_skbuff[i] = NULL;
+ priv->dma_tx[i].des2 = 0;
+ }
+ priv->dirty_tx = 0;
+ priv->cur_tx = 0;
+
+ /* Clear the Rx/Tx descriptors */
+ priv->mac_type->ops->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
+ priv->mac_type->ops->init_tx_desc(priv->dma_tx, txsize);
+
+ if (netif_msg_hw(priv)) {
+ pr_info("RX descriptor ring:\n");
+ display_ring(priv->dma_rx, rxsize);
+ pr_info("TX descriptor ring:\n");
+ display_ring(priv->dma_tx, txsize);
+ }
+ return;
+}
+
+static void dma_free_rx_skbufs(struct stmmac_priv *priv)
+{
+ int i;
+
+ for (i = 0; i < priv->dma_rx_size; i++) {
+ if (priv->rx_skbuff[i]) {
+ dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
+ priv->dma_buf_sz, DMA_FROM_DEVICE);
+ dev_kfree_skb_any(priv->rx_skbuff[i]);
+ }
+ priv->rx_skbuff[i] = NULL;
+ }
+ return;
+}
+
+static void dma_free_tx_skbufs(struct stmmac_priv *priv)
+{
+ int i;
+
+ for (i = 0; i < priv->dma_tx_size; i++) {
+ if (priv->tx_skbuff[i] != NULL) {
+ struct dma_desc *p = priv->dma_tx + i;
+ if (p->des2)
+ dma_unmap_single(priv->device, p->des2,
+ priv->mac_type->ops->get_tx_len(p),
+ DMA_TO_DEVICE);
+ dev_kfree_skb_any(priv->tx_skbuff[i]);
+ priv->tx_skbuff[i] = NULL;
+ }
+ }
+ return;
+}
+
+static void free_dma_desc_resources(struct stmmac_priv *priv)
+{
+ /* Release the DMA TX/RX socket buffers */
+ dma_free_rx_skbufs(priv);
+ dma_free_tx_skbufs(priv);
+
+ /* Free the region of consistent memory previously allocated for
+ * the DMA */
+ dma_free_coherent(priv->device,
+ priv->dma_tx_size * sizeof(struct dma_desc),
+ priv->dma_tx, priv->dma_tx_phy);
+ dma_free_coherent(priv->device,
+ priv->dma_rx_size * sizeof(struct dma_desc),
+ priv->dma_rx, priv->dma_rx_phy);
+ kfree(priv->rx_skbuff_dma);
+ kfree(priv->rx_skbuff);
+ kfree(priv->tx_skbuff);
+
+ return;
+}
+
+/**
+ * stmmac_dma_start_tx
+ * @ioaddr: device I/O address
+ * Description: this function starts the DMA tx process.
+ */
+static void stmmac_dma_start_tx(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + DMA_CONTROL);
+ value |= DMA_CONTROL_ST;
+ writel(value, ioaddr + DMA_CONTROL);
+ return;
+}
+
+static void stmmac_dma_stop_tx(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + DMA_CONTROL);
+ value &= ~DMA_CONTROL_ST;
+ writel(value, ioaddr + DMA_CONTROL);
+ return;
+}
+
+/**
+ * stmmac_dma_start_rx
+ * @ioaddr: device I/O address
+ * Description: this function starts the DMA rx process.
+ */
+static void stmmac_dma_start_rx(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + DMA_CONTROL);
+ value |= DMA_CONTROL_SR;
+ writel(value, ioaddr + DMA_CONTROL);
+
+ return;
+}
+
+static void stmmac_dma_stop_rx(unsigned long ioaddr)
+{
+ u32 value = readl(ioaddr + DMA_CONTROL);
+ value &= ~DMA_CONTROL_SR;
+ writel(value, ioaddr + DMA_CONTROL);
+
+ return;
+}
+
+/**
+ * stmmac_dma_operation_mode - HW DMA operation mode
+ * @priv : pointer to the private device structure.
+ * Description: it sets the DMA operation mode: tx/rx DMA thresholds
+ * or Store-And-Forward capability. It also verifies the COE for the
+ * transmission in case of Giga ETH.
+ */
+static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
+{
+ if (!priv->is_gmac) {
+ /* MAC 10/100 */
+ priv->mac_type->ops->dma_mode(priv->dev->base_addr, tc, 0);
+ priv->tx_coe = NO_HW_CSUM;
+ } else {
+ if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) {
+ priv->mac_type->ops->dma_mode(priv->dev->base_addr,
+ SF_DMA_MODE, SF_DMA_MODE);
+ tc = SF_DMA_MODE;
+ priv->tx_coe = HW_CSUM;
+ } else {
+ /* Checksum computation is performed in software. */
+ priv->mac_type->ops->dma_mode(priv->dev->base_addr, tc,
+ SF_DMA_MODE);
+ priv->tx_coe = NO_HW_CSUM;
+ }
+ }
+ tx_coe = priv->tx_coe;
+
+ return;
+}
+
+#ifdef STMMAC_DEBUG
+/**
+ * show_tx_process_state
+ * @status: tx descriptor status field
+ * Description: it shows the Transmit Process State for CSR5[22:20]
+ */
+static void show_tx_process_state(unsigned int status)
+{
+ unsigned int state;
+ state = (status & DMA_STATUS_TS_MASK) >> DMA_STATUS_TS_SHIFT;
+
+ switch (state) {
+ case 0:
+ pr_info("- TX (Stopped): Reset or Stop command\n");
+ break;
+ case 1:
+ pr_info("- TX (Running):Fetching the Tx desc\n");
+ break;
+ case 2:
+ pr_info("- TX (Running): Waiting for end of tx\n");
+ break;
+ case 3:
+ pr_info("- TX (Running): Reading the data "
+ "and queuing the data into the Tx buf\n");
+ break;
+ case 6:
+ pr_info("- TX (Suspended): Tx Buff Underflow "
+ "or an unavailable Transmit descriptor\n");
+ break;
+ case 7:
+ pr_info("- TX (Running): Closing Tx descriptor\n");
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+/**
+ * show_rx_process_state
+ * @status: rx descriptor status field
+ * Description: it shows the Receive Process State for CSR5[19:17]
+ */
+static void show_rx_process_state(unsigned int status)
+{
+ unsigned int state;
+ state = (status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_SHIFT;
+
+ switch (state) {
+ case 0:
+ pr_info("- RX (Stopped): Reset or Stop command\n");
+ break;
+ case 1:
+ pr_info("- RX (Running): Fetching the Rx desc\n");
+ break;
+ case 2:
+ pr_info("- RX (Running):Checking for end of pkt\n");
+ break;
+ case 3:
+ pr_info("- RX (Running): Waiting for Rx pkt\n");
+ break;
+ case 4:
+ pr_info("- RX (Suspended): Unavailable Rx buf\n");
+ break;
+ case 5:
+ pr_info("- RX (Running): Closing Rx descriptor\n");
+ break;
+ case 6:
+ pr_info("- RX(Running): Flushing the current frame"
+ " from the Rx buf\n");
+ break;
+ case 7:
+ pr_info("- RX (Running): Queuing the Rx frame"
+ " from the Rx buf into memory\n");
+ break;
+ default:
+ break;
+ }
+ return;
+}
+#endif
+
+/**
+ * stmmac_tx:
+ * @priv: private driver structure
+ * Description: it reclaims resources after transmission completes.
+ */
+static void stmmac_tx(struct stmmac_priv *priv)
+{
+ unsigned int txsize = priv->dma_tx_size;
+ unsigned long ioaddr = priv->dev->base_addr;
+
+ while (priv->dirty_tx != priv->cur_tx) {
+ int last;
+ unsigned int entry = priv->dirty_tx % txsize;
+ struct sk_buff *skb = priv->tx_skbuff[entry];
+ struct dma_desc *p = priv->dma_tx + entry;
+
+ /* Check if the descriptor is owned by the DMA. */
+ if (priv->mac_type->ops->get_tx_owner(p))
+ break;
+
+ /* Verify tx error by looking at the last segment */
+ last = priv->mac_type->ops->get_tx_ls(p);
+ if (likely(last)) {
+ int tx_error =
+ priv->mac_type->ops->tx_status(&priv->dev->stats,
+ &priv->xstats,
+ p, ioaddr);
+ if (likely(tx_error == 0)) {
+ priv->dev->stats.tx_packets++;
+ priv->xstats.tx_pkt_n++;
+ } else
+ priv->dev->stats.tx_errors++;
+ }
+ TX_DBG("%s: curr %d, dirty %d\n", __func__,
+ priv->cur_tx, priv->dirty_tx);
+
+ if (likely(p->des2))
+ dma_unmap_single(priv->device, p->des2,
+ priv->mac_type->ops->get_tx_len(p),
+ DMA_TO_DEVICE);
+ if (unlikely(p->des3))
+ p->des3 = 0;
+
+ if (likely(skb != NULL)) {
+ /*
+ * If there's room in the queue (limit it to size)
+ * we add this skb back into the pool,
+ * if it's the right size.
+ */
+ if ((skb_queue_len(&priv->rx_recycle) <
+ priv->dma_rx_size) &&
+ skb_recycle_check(skb, priv->dma_buf_sz))
+ __skb_queue_head(&priv->rx_recycle, skb);
+ else
+ dev_kfree_skb(skb);
+
+ priv->tx_skbuff[entry] = NULL;
+ }
+
+ priv->mac_type->ops->release_tx_desc(p);
+
+ entry = (++priv->dirty_tx) % txsize;
+ }
+ if (unlikely(netif_queue_stopped(priv->dev) &&
+ stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
+ netif_tx_lock(priv->dev);
+ if (netif_queue_stopped(priv->dev) &&
+ stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
+ TX_DBG("%s: restart transmit\n", __func__);
+ netif_wake_queue(priv->dev);
+ }
+ netif_tx_unlock(priv->dev);
+ }
+ return;
+}
+
+static inline void stmmac_enable_irq(struct stmmac_priv *priv)
+{
+#ifdef CONFIG_STMMAC_TIMER
+ if (likely(priv->tm->enable))
+ priv->tm->timer_start(tmrate);
+ else
+#endif
+ writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA);
+}
+
+static inline void stmmac_disable_irq(struct stmmac_priv *priv)
+{
+#ifdef CONFIG_STMMAC_TIMER
+ if (likely(priv->tm->enable))
+ priv->tm->timer_stop();
+ else
+#endif
+ writel(0, priv->dev->base_addr + DMA_INTR_ENA);
+}
+
+static int stmmac_has_work(struct stmmac_priv *priv)
+{
+ unsigned int has_work = 0;
+ int rxret, tx_work = 0;
+
+ rxret = priv->mac_type->ops->get_rx_owner(priv->dma_rx +
+ (priv->cur_rx % priv->dma_rx_size));
+
+ if (priv->dirty_tx != priv->cur_tx)
+ tx_work = 1;
+
+ if (likely(!rxret || tx_work))
+ has_work = 1;
+
+ return has_work;
+}
+
+static inline void _stmmac_schedule(struct stmmac_priv *priv)
+{
+ if (likely(stmmac_has_work(priv))) {
+ stmmac_disable_irq(priv);
+ napi_schedule(&priv->napi);
+ }
+}
+
+#ifdef CONFIG_STMMAC_TIMER
+void stmmac_schedule(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ priv->xstats.sched_timer_n++;
+
+ _stmmac_schedule(priv);
+
+ return;
+}
+
+static void stmmac_no_timer_started(unsigned int x)
+{;
+};
+
+static void stmmac_no_timer_stopped(void)
+{;
+};
+#endif
+
+/**
+ * stmmac_tx_err:
+ * @priv: pointer to the private device structure
+ * Description: it cleans the descriptors and restarts the transmission
+ * in case of errors.
+ */
+static void stmmac_tx_err(struct stmmac_priv *priv)
+{
+ netif_stop_queue(priv->dev);
+
+ stmmac_dma_stop_tx(priv->dev->base_addr);
+ dma_free_tx_skbufs(priv);
+ priv->mac_type->ops->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
+ priv->dirty_tx = 0;
+ priv->cur_tx = 0;
+ stmmac_dma_start_tx(priv->dev->base_addr);
+
+ priv->dev->stats.tx_errors++;
+ netif_wake_queue(priv->dev);
+
+ return;
+}
+
+/**
+ * stmmac_dma_interrupt - Interrupt handler for the driver
+ * @dev: net device structure
+ * Description: Interrupt handler for the driver (DMA).
+ */
+static void stmmac_dma_interrupt(struct net_device *dev)
+{
+ unsigned long ioaddr = dev->base_addr;
+ struct stmmac_priv *priv = netdev_priv(dev);
+ /* read the status register (CSR5) */
+ u32 intr_status = readl(ioaddr + DMA_STATUS);
+
+ DBG(intr, INFO, "%s: [CSR5: 0x%08x]\n", __func__, intr_status);
+
+#ifdef STMMAC_DEBUG
+ /* It displays the DMA transmit process state (CSR5 register) */
+ if (netif_msg_tx_done(priv))
+ show_tx_process_state(intr_status);
+ if (netif_msg_rx_status(priv))
+ show_rx_process_state(intr_status);
+#endif
+ /* ABNORMAL interrupts */
+ if (unlikely(intr_status & DMA_STATUS_AIS)) {
+ DBG(intr, INFO, "CSR5[15] DMA ABNORMAL IRQ: ");
+ if (unlikely(intr_status & DMA_STATUS_UNF)) {
+ DBG(intr, INFO, "transmit underflow\n");
+ if (unlikely(tc != SF_DMA_MODE)
+ && (tc <= 256)) {
+ /* Try to bump up the threshold */
+ tc += 64;
+ priv->mac_type->ops->dma_mode(ioaddr, tc,
+ SF_DMA_MODE);
+ priv->xstats.threshold = tc;
+ }
+ stmmac_tx_err(priv);
+ priv->xstats.tx_undeflow_irq++;
+ }
+ if (unlikely(intr_status & DMA_STATUS_TJT)) {
+ DBG(intr, INFO, "transmit jabber\n");
+ priv->xstats.tx_jabber_irq++;
+ }
+ if (unlikely(intr_status & DMA_STATUS_OVF)) {
+ DBG(intr, INFO, "recv overflow\n");
+ priv->xstats.rx_overflow_irq++;
+ }
+ if (unlikely(intr_status & DMA_STATUS_RU)) {
+ DBG(intr, INFO, "receive buffer unavailable\n");
+ priv->xstats.rx_buf_unav_irq++;
+ }
+ if (unlikely(intr_status & DMA_STATUS_RPS)) {
+ DBG(intr, INFO, "receive process stopped\n");
+ priv->xstats.rx_process_stopped_irq++;
+ }
+ if (unlikely(intr_status & DMA_STATUS_RWT)) {
+ DBG(intr, INFO, "receive watchdog\n");
+ priv->xstats.rx_watchdog_irq++;
+ }
+ if (unlikely(intr_status & DMA_STATUS_ETI)) {
+ DBG(intr, INFO, "transmit early interrupt\n");
+ priv->xstats.tx_early_irq++;
+ }
+ if (unlikely(intr_status & DMA_STATUS_TPS)) {
+ DBG(intr, INFO, "transmit process stopped\n");
+ priv->xstats.tx_process_stopped_irq++;
+ stmmac_tx_err(priv);
+ }
+ if (unlikely(intr_status & DMA_STATUS_FBI)) {
+ DBG(intr, INFO, "fatal bus error\n");
+ priv->xstats.fatal_bus_error_irq++;
+ stmmac_tx_err(priv);
+ }
+ }
+
+ /* TX/RX NORMAL interrupts */
+ if (intr_status & DMA_STATUS_NIS) {
+ priv->xstats.normal_irq_n++;
+ if (likely((intr_status & DMA_STATUS_RI) ||
+ (intr_status & (DMA_STATUS_TI))))
+ _stmmac_schedule(priv);
+ }
+
+ /* Optional hardware blocks, interrupts should be disabled */
+ if (unlikely(intr_status &
+ (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
+ pr_info("%s: unexpected status %08x\n", __func__, intr_status);
+
+ /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
+ writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
+
+ DBG(intr, INFO, "\n\n");
+
+ return;
+}
+
+/**
+ * stmmac_open - open entry point of the driver
+ * @dev : pointer to the device structure.
+ * Description:
+ * This function is the open entry point of the driver.
+ * Return value:
+ * 0 on success and an appropriate (-)ve integer as defined in errno.h
+ * file on failure.
+ */
+static int stmmac_open(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ unsigned long ioaddr = dev->base_addr;
+ int ret;
+
+ /* Check that the MAC address is valid. If its not, refuse
+ * to bring the device up. The user must specify an
+ * address using the following linux command:
+ * ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx */
+ if (!is_valid_ether_addr(dev->dev_addr)) {
+ random_ether_addr(dev->dev_addr);
+ pr_warning("%s: generated random MAC address %pM\n", dev->name,
+ dev->dev_addr);
+ }
+
+ stmmac_verify_args();
+
+ ret = stmmac_init_phy(dev);
+ if (unlikely(ret)) {
+ pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
+ return ret;
+ }
+
+ /* Request the IRQ lines */
+ ret = request_irq(dev->irq, &stmmac_interrupt,
+ IRQF_SHARED, dev->name, dev);
+ if (unlikely(ret < 0)) {
+ pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
+ __func__, dev->irq, ret);
+ return ret;
+ }
+
+#ifdef CONFIG_STMMAC_TIMER
+ priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
+ if (unlikely(priv->tm == NULL)) {
+ pr_err("%s: ERROR: timer memory alloc failed \n", __func__);
+ return -ENOMEM;
+ }
+ priv->tm->freq = tmrate;
+
+ /* Test if the external timer can be actually used.
+ * In case of failure continue without timer. */
+ if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
+ pr_warning("stmmaceth: cannot attach the external timer.\n");
+ tmrate = 0;
+ priv->tm->freq = 0;
+ priv->tm->timer_start = stmmac_no_timer_started;
+ priv->tm->timer_stop = stmmac_no_timer_stopped;
+ } else
+ priv->tm->enable = 1;
+#endif
+
+ /* Create and initialize the TX/RX descriptors chains. */
+ priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
+ priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
+ priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
+ init_dma_desc_rings(dev);
+
+ /* DMA initialization and SW reset */
+ if (unlikely(priv->mac_type->ops->dma_init(ioaddr,
+ priv->pbl, priv->dma_tx_phy, priv->dma_rx_phy) < 0)) {
+
+ pr_err("%s: DMA initialization failed\n", __func__);
+ return -1;
+ }
+
+ /* Copy the MAC addr into the HW */
+ priv->mac_type->ops->set_umac_addr(ioaddr, dev->dev_addr, 0);
+ /* Initialize the MAC Core */
+ priv->mac_type->ops->core_init(ioaddr);
+
+ priv->shutdown = 0;
+
+ /* Initialise the MMC (if present) to disable all interrupts. */
+ writel(0xffffffff, ioaddr + MMC_HIGH_INTR_MASK);
+ writel(0xffffffff, ioaddr + MMC_LOW_INTR_MASK);
+
+ /* Enable the MAC Rx/Tx */
+ stmmac_mac_enable_rx(ioaddr);
+ stmmac_mac_enable_tx(ioaddr);
+
+ /* Set the HW DMA mode and the COE */
+ stmmac_dma_operation_mode(priv);
+
+ /* Extra statistics */
+ memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
+ priv->xstats.threshold = tc;
+
+ /* Start the ball rolling... */
+ DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
+ stmmac_dma_start_tx(ioaddr);
+ stmmac_dma_start_rx(ioaddr);
+
+#ifdef CONFIG_STMMAC_TIMER
+ priv->tm->timer_start(tmrate);
+#endif
+ /* Dump DMA/MAC registers */
+ if (netif_msg_hw(priv)) {
+ priv->mac_type->ops->dump_mac_regs(ioaddr);
+ priv->mac_type->ops->dump_dma_regs(ioaddr);
+ }
+
+ if (priv->phydev)
+ phy_start(priv->phydev);
+
+ napi_enable(&priv->napi);
+ skb_queue_head_init(&priv->rx_recycle);
+ netif_start_queue(dev);
+ return 0;
+}
+
+/**
+ * stmmac_release - close entry point of the driver
+ * @dev : device pointer.
+ * Description:
+ * This is the stop entry point of the driver.
+ */
+static int stmmac_release(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ /* Stop and disconnect the PHY */
+ if (priv->phydev) {
+ phy_stop(priv->phydev);
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+ }
+
+ netif_stop_queue(dev);
+
+#ifdef CONFIG_STMMAC_TIMER
+ /* Stop and release the timer */
+ stmmac_close_ext_timer();
+ if (priv->tm != NULL)
+ kfree(priv->tm);
+#endif
+ napi_disable(&priv->napi);
+ skb_queue_purge(&priv->rx_recycle);
+
+ /* Free the IRQ lines */
+ free_irq(dev->irq, dev);
+
+ /* Stop TX/RX DMA and clear the descriptors */
+ stmmac_dma_stop_tx(dev->base_addr);
+ stmmac_dma_stop_rx(dev->base_addr);
+
+ /* Release and free the Rx/Tx resources */
+ free_dma_desc_resources(priv);
+
+ /* Disable the MAC core */
+ stmmac_mac_disable_tx(dev->base_addr);
+ stmmac_mac_disable_rx(dev->base_addr);
+
+ netif_carrier_off(dev);
+
+ return 0;
+}
+
+/*
+ * To perform emulated hardware segmentation on skb.
+ */
+static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb)
+{
+ struct sk_buff *segs, *curr_skb;
+ int gso_segs = skb_shinfo(skb)->gso_segs;
+
+ /* Estimate the number of fragments in the worst case */
+ if (unlikely(stmmac_tx_avail(priv) < gso_segs)) {
+ netif_stop_queue(priv->dev);
+ TX_DBG(KERN_ERR "%s: TSO BUG! Tx Ring full when queue awake\n",
+ __func__);
+ if (stmmac_tx_avail(priv) < gso_segs)
+ return NETDEV_TX_BUSY;
+
+ netif_wake_queue(priv->dev);
+ }
+ TX_DBG("\tstmmac_sw_tso: segmenting: skb %p (len %d)\n",
+ skb, skb->len);
+
+ segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO);
+ if (unlikely(IS_ERR(segs)))
+ goto sw_tso_end;
+
+ do {
+ curr_skb = segs;
+ segs = segs->next;
+ TX_DBG("\t\tcurrent skb->len: %d, *curr %p,"
+ "*next %p\n", curr_skb->len, curr_skb, segs);
+ curr_skb->next = NULL;
+ stmmac_xmit(curr_skb, priv->dev);
+ } while (segs);
+
+sw_tso_end:
+ dev_kfree_skb(skb);
+
+ return NETDEV_TX_OK;
+}
+
+static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
+ struct net_device *dev,
+ int csum_insertion)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ unsigned int nopaged_len = skb_headlen(skb);
+ unsigned int txsize = priv->dma_tx_size;
+ unsigned int entry = priv->cur_tx % txsize;
+ struct dma_desc *desc = priv->dma_tx + entry;
+
+ if (nopaged_len > BUF_SIZE_8KiB) {
+
+ int buf2_size = nopaged_len - BUF_SIZE_8KiB;
+
+ desc->des2 = dma_map_single(priv->device, skb->data,
+ BUF_SIZE_8KiB, DMA_TO_DEVICE);
+ desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+ priv->mac_type->ops->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
+ csum_insertion);
+
+ entry = (++priv->cur_tx) % txsize;
+ desc = priv->dma_tx + entry;
+
+ desc->des2 = dma_map_single(priv->device,
+ skb->data + BUF_SIZE_8KiB,
+ buf2_size, DMA_TO_DEVICE);
+ desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+ priv->mac_type->ops->prepare_tx_desc(desc, 0,
+ buf2_size, csum_insertion);
+ priv->mac_type->ops->set_tx_owner(desc);
+ priv->tx_skbuff[entry] = NULL;
+ } else {
+ desc->des2 = dma_map_single(priv->device, skb->data,
+ nopaged_len, DMA_TO_DEVICE);
+ desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+ priv->mac_type->ops->prepare_tx_desc(desc, 1, nopaged_len,
+ csum_insertion);
+ }
+ return entry;
+}
+
+/**
+ * stmmac_xmit:
+ * @skb : the socket buffer
+ * @dev : device pointer
+ * Description : Tx entry point of the driver.
+ */
+static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ unsigned int txsize = priv->dma_tx_size;
+ unsigned int entry;
+ int i, csum_insertion = 0;
+ int nfrags = skb_shinfo(skb)->nr_frags;
+ struct dma_desc *desc, *first;
+
+ if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
+ if (!netif_queue_stopped(dev)) {
+ netif_stop_queue(dev);
+ /* This is a hard error, log it. */
+ pr_err("%s: BUG! Tx Ring full when queue awake\n",
+ __func__);
+ }
+ return NETDEV_TX_BUSY;
+ }
+
+ entry = priv->cur_tx % txsize;
+
+#ifdef STMMAC_XMIT_DEBUG
+ if ((skb->len > ETH_FRAME_LEN) || nfrags)
+ pr_info("stmmac xmit:\n"
+ "\tskb addr %p - len: %d - nopaged_len: %d\n"
+ "\tn_frags: %d - ip_summed: %d - %s gso\n",
+ skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed,
+ !skb_is_gso(skb) ? "isn't" : "is");
+#endif
+
+ if (unlikely(skb_is_gso(skb)))
+ return stmmac_sw_tso(priv, skb);
+
+ if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) {
+ if (likely(priv->tx_coe == NO_HW_CSUM))
+ skb_checksum_help(skb);
+ else
+ csum_insertion = 1;
+ }
+
+ desc = priv->dma_tx + entry;
+ first = desc;
+
+#ifdef STMMAC_XMIT_DEBUG
+ if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
+ pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
+ "\t\tn_frags: %d, ip_summed: %d\n",
+ skb->len, skb_headlen(skb), nfrags, skb->ip_summed);
+#endif
+ priv->tx_skbuff[entry] = skb;
+ if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
+ entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion);
+ desc = priv->dma_tx + entry;
+ } else {
+ unsigned int nopaged_len = skb_headlen(skb);
+ desc->des2 = dma_map_single(priv->device, skb->data,
+ nopaged_len, DMA_TO_DEVICE);
+ priv->mac_type->ops->prepare_tx_desc(desc, 1, nopaged_len,
+ csum_insertion);
+ }
+
+ for (i = 0; i < nfrags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ int len = frag->size;
+
+ entry = (++priv->cur_tx) % txsize;
+ desc = priv->dma_tx + entry;
+
+ TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
+ desc->des2 = dma_map_page(priv->device, frag->page,
+ frag->page_offset,
+ len, DMA_TO_DEVICE);
+ priv->tx_skbuff[entry] = NULL;
+ priv->mac_type->ops->prepare_tx_desc(desc, 0, len,
+ csum_insertion);
+ priv->mac_type->ops->set_tx_owner(desc);
+ }
+
+ /* Interrupt on completition only for the latest segment */
+ priv->mac_type->ops->close_tx_desc(desc);
+
+#ifdef CONFIG_STMMAC_TIMER
+ /* Clean IC while using timer */
+ if (likely(priv->tm->enable))
+ priv->mac_type->ops->clear_tx_ic(desc);
+#endif
+ /* To avoid raise condition */
+ priv->mac_type->ops->set_tx_owner(first);
+
+ priv->cur_tx++;
+
+#ifdef STMMAC_XMIT_DEBUG
+ if (netif_msg_pktdata(priv)) {
+ pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, "
+ "first=%p, nfrags=%d\n",
+ (priv->cur_tx % txsize), (priv->dirty_tx % txsize),
+ entry, first, nfrags);
+ display_ring(priv->dma_tx, txsize);
+ pr_info(">>> frame to be transmitted: ");
+ print_pkt(skb->data, skb->len);
+ }
+#endif
+ if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
+ TX_DBG("%s: stop transmitted packets\n", __func__);
+ netif_stop_queue(dev);
+ }
+
+ dev->stats.tx_bytes += skb->len;
+
+ /* CSR1 enables the transmit DMA to check for new descriptor */
+ writel(1, dev->base_addr + DMA_XMT_POLL_DEMAND);
+
+ return NETDEV_TX_OK;
+}
+
+static inline void stmmac_rx_refill(struct stmmac_priv *priv)
+{
+ unsigned int rxsize = priv->dma_rx_size;
+ int bfsize = priv->dma_buf_sz;
+ struct dma_desc *p = priv->dma_rx;
+
+ for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
+ unsigned int entry = priv->dirty_rx % rxsize;
+ if (likely(priv->rx_skbuff[entry] == NULL)) {
+ struct sk_buff *skb;
+
+ skb = __skb_dequeue(&priv->rx_recycle);
+ if (skb == NULL)
+ skb = netdev_alloc_skb_ip_align(priv->dev,
+ bfsize);
+
+ if (unlikely(skb == NULL))
+ break;
+
+ priv->rx_skbuff[entry] = skb;
+ priv->rx_skbuff_dma[entry] =
+ dma_map_single(priv->device, skb->data, bfsize,
+ DMA_FROM_DEVICE);
+
+ (p + entry)->des2 = priv->rx_skbuff_dma[entry];
+ if (unlikely(priv->is_gmac)) {
+ if (bfsize >= BUF_SIZE_8KiB)
+ (p + entry)->des3 =
+ (p + entry)->des2 + BUF_SIZE_8KiB;
+ }
+ RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
+ }
+ priv->mac_type->ops->set_rx_owner(p + entry);
+ }
+ return;
+}
+
+static int stmmac_rx(struct stmmac_priv *priv, int limit)
+{
+ unsigned int rxsize = priv->dma_rx_size;
+ unsigned int entry = priv->cur_rx % rxsize;
+ unsigned int next_entry;
+ unsigned int count = 0;
+ struct dma_desc *p = priv->dma_rx + entry;
+ struct dma_desc *p_next;
+
+#ifdef STMMAC_RX_DEBUG
+ if (netif_msg_hw(priv)) {
+ pr_debug(">>> stmmac_rx: descriptor ring:\n");
+ display_ring(priv->dma_rx, rxsize);
+ }
+#endif
+ count = 0;
+ while (!priv->mac_type->ops->get_rx_owner(p)) {
+ int status;
+
+ if (count >= limit)
+ break;
+
+ count++;
+
+ next_entry = (++priv->cur_rx) % rxsize;
+ p_next = priv->dma_rx + next_entry;
+ prefetch(p_next);
+
+ /* read the status of the incoming frame */
+ status = (priv->mac_type->ops->rx_status(&priv->dev->stats,
+ &priv->xstats, p));
+ if (unlikely(status == discard_frame))
+ priv->dev->stats.rx_errors++;
+ else {
+ struct sk_buff *skb;
+ /* Length should omit the CRC */
+ int frame_len =
+ priv->mac_type->ops->get_rx_frame_len(p) - 4;
+
+#ifdef STMMAC_RX_DEBUG
+ if (frame_len > ETH_FRAME_LEN)
+ pr_debug("\tRX frame size %d, COE status: %d\n",
+ frame_len, status);
+
+ if (netif_msg_hw(priv))
+ pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
+ p, entry, p->des2);
+#endif
+ skb = priv->rx_skbuff[entry];
+ if (unlikely(!skb)) {
+ pr_err("%s: Inconsistent Rx descriptor chain\n",
+ priv->dev->name);
+ priv->dev->stats.rx_dropped++;
+ break;
+ }
+ prefetch(skb->data - NET_IP_ALIGN);
+ priv->rx_skbuff[entry] = NULL;
+
+ skb_put(skb, frame_len);
+ dma_unmap_single(priv->device,
+ priv->rx_skbuff_dma[entry],
+ priv->dma_buf_sz, DMA_FROM_DEVICE);
+#ifdef STMMAC_RX_DEBUG
+ if (netif_msg_pktdata(priv)) {
+ pr_info(" frame received (%dbytes)", frame_len);
+ print_pkt(skb->data, frame_len);
+ }
+#endif
+ skb->protocol = eth_type_trans(skb, priv->dev);
+
+ if (unlikely(status == csum_none)) {
+ /* always for the old mac 10/100 */
+ skb->ip_summed = CHECKSUM_NONE;
+ netif_receive_skb(skb);
+ } else {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ napi_gro_receive(&priv->napi, skb);
+ }
+
+ priv->dev->stats.rx_packets++;
+ priv->dev->stats.rx_bytes += frame_len;
+ priv->dev->last_rx = jiffies;
+ }
+ entry = next_entry;
+ p = p_next; /* use prefetched values */
+ }
+
+ stmmac_rx_refill(priv);
+
+ priv->xstats.rx_pkt_n += count;
+
+ return count;
+}
+
+/**
+ * stmmac_poll - stmmac poll method (NAPI)
+ * @napi : pointer to the napi structure.
+ * @budget : maximum number of packets that the current CPU can receive from
+ * all interfaces.
+ * Description :
+ * This function implements the the reception process.
+ * Also it runs the TX completion thread
+ */
+static int stmmac_poll(struct napi_struct *napi, int budget)
+{
+ struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
+ int work_done = 0;
+
+ priv->xstats.poll_n++;
+ stmmac_tx(priv);
+ work_done = stmmac_rx(priv, budget);
+
+ if (work_done < budget) {
+ napi_complete(napi);
+ stmmac_enable_irq(priv);
+ }
+ return work_done;
+}
+
+/**
+ * stmmac_tx_timeout
+ * @dev : Pointer to net device structure
+ * Description: this function is called when a packet transmission fails to
+ * complete within a reasonable tmrate. The driver will mark the error in the
+ * netdev structure and arrange for the device to be reset to a sane state
+ * in order to transmit a new packet.
+ */
+static void stmmac_tx_timeout(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ /* Clear Tx resources and restart transmitting again */
+ stmmac_tx_err(priv);
+ return;
+}
+
+/* Configuration changes (passed on by ifconfig) */
+static int stmmac_config(struct net_device *dev, struct ifmap *map)
+{
+ if (dev->flags & IFF_UP) /* can't act on a running interface */
+ return -EBUSY;
+
+ /* Don't allow changing the I/O address */
+ if (map->base_addr != dev->base_addr) {
+ pr_warning("%s: can't change I/O address\n", dev->name);
+ return -EOPNOTSUPP;
+ }
+
+ /* Don't allow changing the IRQ */
+ if (map->irq != dev->irq) {
+ pr_warning("%s: can't change IRQ number %d\n",
+ dev->name, dev->irq);
+ return -EOPNOTSUPP;
+ }
+
+ /* ignore other fields */
+ return 0;
+}
+
+/**
+ * stmmac_multicast_list - entry point for multicast addressing
+ * @dev : pointer to the device structure
+ * Description:
+ * This function is a driver entry point which gets called by the kernel
+ * whenever multicast addresses must be enabled/disabled.
+ * Return value:
+ * void.
+ */
+static void stmmac_multicast_list(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ spin_lock(&priv->lock);
+ priv->mac_type->ops->set_filter(dev);
+ spin_unlock(&priv->lock);
+ return;
+}
+
+/**
+ * stmmac_change_mtu - entry point to change MTU size for the device.
+ * @dev : device pointer.
+ * @new_mtu : the new MTU size for the device.
+ * Description: the Maximum Transfer Unit (MTU) is used by the network layer
+ * to drive packet transmission. Ethernet has an MTU of 1500 octets
+ * (ETH_DATA_LEN). This value can be changed with ifconfig.
+ * Return value:
+ * 0 on success and an appropriate (-)ve integer as defined in errno.h
+ * file on failure.
+ */
+static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ int max_mtu;
+
+ if (netif_running(dev)) {
+ pr_err("%s: must be stopped to change its MTU\n", dev->name);
+ return -EBUSY;
+ }
+
+ if (priv->is_gmac)
+ max_mtu = JUMBO_LEN;
+ else
+ max_mtu = ETH_DATA_LEN;
+
+ if ((new_mtu < 46) || (new_mtu > max_mtu)) {
+ pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
+ return -EINVAL;
+ }
+
+ dev->mtu = new_mtu;
+
+ return 0;
+}
+
+static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ if (unlikely(!dev)) {
+ pr_err("%s: invalid dev pointer\n", __func__);
+ return IRQ_NONE;
+ }
+
+ if (priv->is_gmac) {
+ unsigned long ioaddr = dev->base_addr;
+ /* To handle GMAC own interrupts */
+ priv->mac_type->ops->host_irq_status(ioaddr);
+ }
+ stmmac_dma_interrupt(dev);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/* Polling receive - used by NETCONSOLE and other diagnostic tools
+ * to allow network I/O with interrupts disabled. */
+static void stmmac_poll_controller(struct net_device *dev)
+{
+ disable_irq(dev->irq);
+ stmmac_interrupt(dev->irq, dev);
+ enable_irq(dev->irq);
+}
+#endif
+
+/**
+ * stmmac_ioctl - Entry point for the Ioctl
+ * @dev: Device pointer.
+ * @rq: An IOCTL specefic structure, that can contain a pointer to
+ * a proprietary structure used to pass information to the driver.
+ * @cmd: IOCTL command
+ * Description:
+ * Currently there are no special functionality supported in IOCTL, just the
+ * phy_mii_ioctl(...) can be invoked.
+ */
+static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ int ret = -EOPNOTSUPP;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ if (!priv->phydev)
+ return -EINVAL;
+
+ spin_lock(&priv->lock);
+ ret = phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+ spin_unlock(&priv->lock);
+ default:
+ break;
+ }
+ return ret;
+}
+
+#ifdef STMMAC_VLAN_TAG_USED
+static void stmmac_vlan_rx_register(struct net_device *dev,
+ struct vlan_group *grp)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ DBG(probe, INFO, "%s: Setting vlgrp to %p\n", dev->name, grp);
+
+ spin_lock(&priv->lock);
+ priv->vlgrp = grp;
+ spin_unlock(&priv->lock);
+
+ return;
+}
+#endif
+
+static const struct net_device_ops stmmac_netdev_ops = {
+ .ndo_open = stmmac_open,
+ .ndo_start_xmit = stmmac_xmit,
+ .ndo_stop = stmmac_release,
+ .ndo_change_mtu = stmmac_change_mtu,
+ .ndo_set_multicast_list = stmmac_multicast_list,
+ .ndo_tx_timeout = stmmac_tx_timeout,
+ .ndo_do_ioctl = stmmac_ioctl,
+ .ndo_set_config = stmmac_config,
+#ifdef STMMAC_VLAN_TAG_USED
+ .ndo_vlan_rx_register = stmmac_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = stmmac_poll_controller,
+#endif
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
+/**
+ * stmmac_probe - Initialization of the adapter .
+ * @dev : device pointer
+ * Description: The function initializes the network device structure for
+ * the STMMAC driver. It also calls the low level routines
+ * in order to init the HW (i.e. the DMA engine)
+ */
+static int stmmac_probe(struct net_device *dev)
+{
+ int ret = 0;
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ ether_setup(dev);
+
+ dev->netdev_ops = &stmmac_netdev_ops;
+ stmmac_set_ethtool_ops(dev);
+
+ dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA);
+ dev->watchdog_timeo = msecs_to_jiffies(watchdog);
+#ifdef STMMAC_VLAN_TAG_USED
+ /* Both mac100 and gmac support receive VLAN tag detection */
+ dev->features |= NETIF_F_HW_VLAN_RX;
+#endif
+ priv->msg_enable = netif_msg_init(debug, default_msg_level);
+
+ if (priv->is_gmac)
+ priv->rx_csum = 1;
+
+ if (flow_ctrl)
+ priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
+
+ priv->pause = pause;
+ netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
+
+ /* Get the MAC address */
+ priv->mac_type->ops->get_umac_addr(dev->base_addr, dev->dev_addr, 0);
+
+ if (!is_valid_ether_addr(dev->dev_addr))
+ pr_warning("\tno valid MAC address;"
+ "please, use ifconfig or nwhwconfig!\n");
+
+ ret = register_netdev(dev);
+ if (ret) {
+ pr_err("%s: ERROR %i registering the device\n",
+ __func__, ret);
+ return -ENODEV;
+ }
+
+ DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
+ dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
+ (dev->features & NETIF_F_HW_CSUM) ? "on" : "off");
+
+ spin_lock_init(&priv->lock);
+
+ return ret;
+}
+
+/**
+ * stmmac_mac_device_setup
+ * @dev : device pointer
+ * Description: select and initialise the mac device (mac100 or Gmac).
+ */
+static int stmmac_mac_device_setup(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+ unsigned long ioaddr = dev->base_addr;
+
+ struct mac_device_info *device;
+
+ if (priv->is_gmac)
+ device = gmac_setup(ioaddr);
+ else
+ device = mac100_setup(ioaddr);
+
+ if (!device)
+ return -ENOMEM;
+
+ priv->mac_type = device;
+
+ priv->wolenabled = priv->mac_type->hw.pmt; /* PMT supported */
+ if (priv->wolenabled == PMT_SUPPORTED)
+ priv->wolopts = WAKE_MAGIC; /* Magic Frame */
+
+ return 0;
+}
+
+static int stmmacphy_dvr_probe(struct platform_device *pdev)
+{
+ struct plat_stmmacphy_data *plat_dat;
+ plat_dat = (struct plat_stmmacphy_data *)((pdev->dev).platform_data);
+
+ pr_debug("stmmacphy_dvr_probe: added phy for bus %d\n",
+ plat_dat->bus_id);
+
+ return 0;
+}
+
+static int stmmacphy_dvr_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver stmmacphy_driver = {
+ .driver = {
+ .name = PHY_RESOURCE_NAME,
+ },
+ .probe = stmmacphy_dvr_probe,
+ .remove = stmmacphy_dvr_remove,
+};
+
+/**
+ * stmmac_associate_phy
+ * @dev: pointer to device structure
+ * @data: points to the private structure.
+ * Description: Scans through all the PHYs we have registered and checks if
+ * any are associated with our MAC. If so, then just fill in
+ * the blanks in our local context structure
+ */
+static int stmmac_associate_phy(struct device *dev, void *data)
+{
+ struct stmmac_priv *priv = (struct stmmac_priv *)data;
+ struct plat_stmmacphy_data *plat_dat;
+
+ plat_dat = (struct plat_stmmacphy_data *)(dev->platform_data);
+
+ DBG(probe, DEBUG, "%s: checking phy for bus %d\n", __func__,
+ plat_dat->bus_id);
+
+ /* Check that this phy is for the MAC being initialised */
+ if (priv->bus_id != plat_dat->bus_id)
+ return 0;
+
+ /* OK, this PHY is connected to the MAC.
+ Go ahead and get the parameters */
+ DBG(probe, DEBUG, "%s: OK. Found PHY config\n", __func__);
+ priv->phy_irq =
+ platform_get_irq_byname(to_platform_device(dev), "phyirq");
+ DBG(probe, DEBUG, "%s: PHY irq on bus %d is %d\n", __func__,
+ plat_dat->bus_id, priv->phy_irq);
+
+ /* Override with kernel parameters if supplied XXX CRS XXX
+ * this needs to have multiple instances */
+ if ((phyaddr >= 0) && (phyaddr <= 31))
+ plat_dat->phy_addr = phyaddr;
+
+ priv->phy_addr = plat_dat->phy_addr;
+ priv->phy_mask = plat_dat->phy_mask;
+ priv->phy_interface = plat_dat->interface;
+ priv->phy_reset = plat_dat->phy_reset;
+
+ DBG(probe, DEBUG, "%s: exiting\n", __func__);
+ return 1; /* forces exit of driver_for_each_device() */
+}
+
+/**
+ * stmmac_dvr_probe
+ * @pdev: platform device pointer
+ * Description: the driver is initialized through platform_device.
+ */
+static int stmmac_dvr_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct resource *res;
+ unsigned int *addr = NULL;
+ struct net_device *ndev = NULL;
+ struct stmmac_priv *priv;
+ struct plat_stmmacenet_data *plat_dat;
+
+ pr_info("STMMAC driver:\n\tplatform registration... ");
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENODEV;
+ goto out;
+ }
+ pr_info("done!\n");
+
+ if (!request_mem_region(res->start, (res->end - res->start),
+ pdev->name)) {
+ pr_err("%s: ERROR: memory allocation failed"
+ "cannot get the I/O addr 0x%x\n",
+ __func__, (unsigned int)res->start);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ addr = ioremap(res->start, (res->end - res->start));
+ if (!addr) {
+ pr_err("%s: ERROR: memory mapping failed \n", __func__);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ndev = alloc_etherdev(sizeof(struct stmmac_priv));
+ if (!ndev) {
+ pr_err("%s: ERROR: allocating the device\n", __func__);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ /* Get the MAC information */
+ ndev->irq = platform_get_irq_byname(pdev, "macirq");
+ if (ndev->irq == -ENXIO) {
+ pr_err("%s: ERROR: MAC IRQ configuration "
+ "information not found\n", __func__);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ priv = netdev_priv(ndev);
+ priv->device = &(pdev->dev);
+ priv->dev = ndev;
+ plat_dat = (struct plat_stmmacenet_data *)((pdev->dev).platform_data);
+ priv->bus_id = plat_dat->bus_id;
+ priv->pbl = plat_dat->pbl; /* TLI */
+ priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */
+
+ platform_set_drvdata(pdev, ndev);
+
+ /* Set the I/O base addr */
+ ndev->base_addr = (unsigned long)addr;
+
+ /* MAC HW revice detection */
+ ret = stmmac_mac_device_setup(ndev);
+ if (ret < 0)
+ goto out;
+
+ /* Network Device Registration */
+ ret = stmmac_probe(ndev);
+ if (ret < 0)
+ goto out;
+
+ /* associate a PHY - it is provided by another platform bus */
+ if (!driver_for_each_device
+ (&(stmmacphy_driver.driver), NULL, (void *)priv,
+ stmmac_associate_phy)) {
+ pr_err("No PHY device is associated with this MAC!\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ priv->fix_mac_speed = plat_dat->fix_mac_speed;
+ priv->bsp_priv = plat_dat->bsp_priv;
+
+ pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
+ "\tIO base addr: 0x%08x)\n", ndev->name, pdev->name,
+ pdev->id, ndev->irq, (unsigned int)addr);
+
+ /* MDIO bus Registration */
+ pr_debug("\tMDIO bus (id: %d)...", priv->bus_id);
+ ret = stmmac_mdio_register(ndev);
+ if (ret < 0)
+ goto out;
+ pr_debug("registered!\n");
+
+out:
+ if (ret < 0) {
+ platform_set_drvdata(pdev, NULL);
+ release_mem_region(res->start, (res->end - res->start));
+ if (addr != NULL)
+ iounmap(addr);
+ }
+
+ return ret;
+}
+
+/**
+ * stmmac_dvr_remove
+ * @pdev: platform device pointer
+ * Description: this function resets the TX/RX processes, disables the MAC RX/TX
+ * changes the link status, releases the DMA descriptor rings,
+ * unregisters the MDIO bus and unmaps the allocated memory.
+ */
+static int stmmac_dvr_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct resource *res;
+
+ pr_info("%s:\n\tremoving driver", __func__);
+
+ stmmac_dma_stop_rx(ndev->base_addr);
+ stmmac_dma_stop_tx(ndev->base_addr);
+
+ stmmac_mac_disable_rx(ndev->base_addr);
+ stmmac_mac_disable_tx(ndev->base_addr);
+
+ netif_carrier_off(ndev);
+
+ stmmac_mdio_unregister(ndev);
+
+ platform_set_drvdata(pdev, NULL);
+ unregister_netdev(ndev);
+
+ iounmap((void *)ndev->base_addr);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, (res->end - res->start));
+
+ free_netdev(ndev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct stmmac_priv *priv = netdev_priv(dev);
+ int dis_ic = 0;
+
+ if (!dev || !netif_running(dev))
+ return 0;
+
+ spin_lock(&priv->lock);
+
+ if (state.event == PM_EVENT_SUSPEND) {
+ netif_device_detach(dev);
+ netif_stop_queue(dev);
+ if (priv->phydev)
+ phy_stop(priv->phydev);
+
+#ifdef CONFIG_STMMAC_TIMER
+ priv->tm->timer_stop();
+ if (likely(priv->tm->enable))
+ dis_ic = 1;
+#endif
+ napi_disable(&priv->napi);
+
+ /* Stop TX/RX DMA */
+ stmmac_dma_stop_tx(dev->base_addr);
+ stmmac_dma_stop_rx(dev->base_addr);
+ /* Clear the Rx/Tx descriptors */
+ priv->mac_type->ops->init_rx_desc(priv->dma_rx,
+ priv->dma_rx_size, dis_ic);
+ priv->mac_type->ops->init_tx_desc(priv->dma_tx,
+ priv->dma_tx_size);
+
+ stmmac_mac_disable_tx(dev->base_addr);
+
+ if (device_may_wakeup(&(pdev->dev))) {
+ /* Enable Power down mode by programming the PMT regs */
+ if (priv->wolenabled == PMT_SUPPORTED)
+ priv->mac_type->ops->pmt(dev->base_addr,
+ priv->wolopts);
+ } else {
+ stmmac_mac_disable_rx(dev->base_addr);
+ }
+ } else {
+ priv->shutdown = 1;
+ /* Although this can appear slightly redundant it actually
+ * makes fast the standby operation and guarantees the driver
+ * working if hibernation is on media. */
+ stmmac_release(dev);
+ }
+
+ spin_unlock(&priv->lock);
+ return 0;
+}
+
+static int stmmac_resume(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct stmmac_priv *priv = netdev_priv(dev);
+ unsigned long ioaddr = dev->base_addr;
+
+ if (!netif_running(dev))
+ return 0;
+
+ spin_lock(&priv->lock);
+
+ if (priv->shutdown) {
+ /* Re-open the interface and re-init the MAC/DMA
+ and the rings. */
+ stmmac_open(dev);
+ goto out_resume;
+ }
+
+ /* Power Down bit, into the PM register, is cleared
+ * automatically as soon as a magic packet or a Wake-up frame
+ * is received. Anyway, it's better to manually clear
+ * this bit because it can generate problems while resuming
+ * from another devices (e.g. serial console). */
+ if (device_may_wakeup(&(pdev->dev)))
+ if (priv->wolenabled == PMT_SUPPORTED)
+ priv->mac_type->ops->pmt(dev->base_addr, 0);
+
+ netif_device_attach(dev);
+
+ /* Enable the MAC and DMA */
+ stmmac_mac_enable_rx(ioaddr);
+ stmmac_mac_enable_tx(ioaddr);
+ stmmac_dma_start_tx(ioaddr);
+ stmmac_dma_start_rx(ioaddr);
+
+#ifdef CONFIG_STMMAC_TIMER
+ priv->tm->timer_start(tmrate);
+#endif
+ napi_enable(&priv->napi);
+
+ if (priv->phydev)
+ phy_start(priv->phydev);
+
+ netif_start_queue(dev);
+
+out_resume:
+ spin_unlock(&priv->lock);
+ return 0;
+}
+#endif
+
+static struct platform_driver stmmac_driver = {
+ .driver = {
+ .name = STMMAC_RESOURCE_NAME,
+ },
+ .probe = stmmac_dvr_probe,
+ .remove = stmmac_dvr_remove,
+#ifdef CONFIG_PM
+ .suspend = stmmac_suspend,
+ .resume = stmmac_resume,
+#endif
+
+};
+
+/**
+ * stmmac_init_module - Entry point for the driver
+ * Description: This function is the entry point for the driver.
+ */
+static int __init stmmac_init_module(void)
+{
+ int ret;
+
+ if (platform_driver_register(&stmmacphy_driver)) {
+ pr_err("No PHY devices registered!\n");
+ return -ENODEV;
+ }
+
+ ret = platform_driver_register(&stmmac_driver);
+ return ret;
+}
+
+/**
+ * stmmac_cleanup_module - Cleanup routine for the driver
+ * Description: This function is the cleanup routine for the driver.
+ */
+static void __exit stmmac_cleanup_module(void)
+{
+ platform_driver_unregister(&stmmacphy_driver);
+ platform_driver_unregister(&stmmac_driver);
+}
+
+#ifndef MODULE
+static int __init stmmac_cmdline_opt(char *str)
+{
+ char *opt;
+
+ if (!str || !*str)
+ return -EINVAL;
+ while ((opt = strsep(&str, ",")) != NULL) {
+ if (!strncmp(opt, "debug:", 6))
+ strict_strtoul(opt + 6, 0, (unsigned long *)&debug);
+ else if (!strncmp(opt, "phyaddr:", 8))
+ strict_strtoul(opt + 8, 0, (unsigned long *)&phyaddr);
+ else if (!strncmp(opt, "dma_txsize:", 11))
+ strict_strtoul(opt + 11, 0,
+ (unsigned long *)&dma_txsize);
+ else if (!strncmp(opt, "dma_rxsize:", 11))
+ strict_strtoul(opt + 11, 0,
+ (unsigned long *)&dma_rxsize);
+ else if (!strncmp(opt, "buf_sz:", 7))
+ strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz);
+ else if (!strncmp(opt, "tc:", 3))
+ strict_strtoul(opt + 3, 0, (unsigned long *)&tc);
+ else if (!strncmp(opt, "tx_coe:", 7))
+ strict_strtoul(opt + 7, 0, (unsigned long *)&tx_coe);
+ else if (!strncmp(opt, "watchdog:", 9))
+ strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog);
+ else if (!strncmp(opt, "flow_ctrl:", 10))
+ strict_strtoul(opt + 10, 0,
+ (unsigned long *)&flow_ctrl);
+ else if (!strncmp(opt, "pause:", 6))
+ strict_strtoul(opt + 6, 0, (unsigned long *)&pause);
+#ifdef CONFIG_STMMAC_TIMER
+ else if (!strncmp(opt, "tmrate:", 7))
+ strict_strtoul(opt + 7, 0, (unsigned long *)&tmrate);
+#endif
+ }
+ return 0;
+}
+
+__setup("stmmaceth=", stmmac_cmdline_opt);
+#endif
+
+module_init(stmmac_init_module);
+module_exit(stmmac_cleanup_module);
+
+MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet driver");
+MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c
new file mode 100644
index 000000000000..8498552a22fc
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_mdio.c
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ STMMAC Ethernet Driver -- MDIO bus implementation
+ Provides Bus interface for MII registers
+
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Carl Shaw <carl.shaw@st.com>
+ Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/netdevice.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include "stmmac.h"
+
+#define MII_BUSY 0x00000001
+#define MII_WRITE 0x00000002
+
+/**
+ * stmmac_mdio_read
+ * @bus: points to the mii_bus structure
+ * @phyaddr: MII addr reg bits 15-11
+ * @phyreg: MII addr reg bits 10-6
+ * Description: it reads data from the MII register from within the phy device.
+ * For the 7111 GMAC, we must set the bit 0 in the MII address register while
+ * accessing the PHY registers.
+ * Fortunately, it seems this has no drawback for the 7109 MAC.
+ */
+static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
+{
+ struct net_device *ndev = bus->priv;
+ struct stmmac_priv *priv = netdev_priv(ndev);
+ unsigned long ioaddr = ndev->base_addr;
+ unsigned int mii_address = priv->mac_type->hw.mii.addr;
+ unsigned int mii_data = priv->mac_type->hw.mii.data;
+
+ int data;
+ u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
+ ((phyreg << 6) & (0x000007C0)));
+ regValue |= MII_BUSY; /* in case of GMAC */
+
+ do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+ writel(regValue, ioaddr + mii_address);
+ do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+
+ /* Read the data from the MII data register */
+ data = (int)readl(ioaddr + mii_data);
+
+ return data;
+}
+
+/**
+ * stmmac_mdio_write
+ * @bus: points to the mii_bus structure
+ * @phyaddr: MII addr reg bits 15-11
+ * @phyreg: MII addr reg bits 10-6
+ * @phydata: phy data
+ * Description: it writes the data into the MII register from within the device.
+ */
+static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
+ u16 phydata)
+{
+ struct net_device *ndev = bus->priv;
+ struct stmmac_priv *priv = netdev_priv(ndev);
+ unsigned long ioaddr = ndev->base_addr;
+ unsigned int mii_address = priv->mac_type->hw.mii.addr;
+ unsigned int mii_data = priv->mac_type->hw.mii.data;
+
+ u16 value =
+ (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
+ | MII_WRITE;
+
+ value |= MII_BUSY;
+
+ /* Wait until any existing MII operation is complete */
+ do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+
+ /* Set the MII address register to write */
+ writel(phydata, ioaddr + mii_data);
+ writel(value, ioaddr + mii_address);
+
+ /* Wait until any existing MII operation is complete */
+ do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+
+ return 0;
+}
+
+/**
+ * stmmac_mdio_reset
+ * @bus: points to the mii_bus structure
+ * Description: reset the MII bus
+ */
+static int stmmac_mdio_reset(struct mii_bus *bus)
+{
+ struct net_device *ndev = bus->priv;
+ struct stmmac_priv *priv = netdev_priv(ndev);
+ unsigned long ioaddr = ndev->base_addr;
+ unsigned int mii_address = priv->mac_type->hw.mii.addr;
+
+ if (priv->phy_reset) {
+ pr_debug("stmmac_mdio_reset: calling phy_reset\n");
+ priv->phy_reset(priv->bsp_priv);
+ }
+
+ /* This is a workaround for problems with the STE101P PHY.
+ * It doesn't complete its reset until at least one clock cycle
+ * on MDC, so perform a dummy mdio read.
+ */
+ writel(0, ioaddr + mii_address);
+
+ return 0;
+}
+
+/**
+ * stmmac_mdio_register
+ * @ndev: net device structure
+ * Description: it registers the MII bus
+ */
+int stmmac_mdio_register(struct net_device *ndev)
+{
+ int err = 0;
+ struct mii_bus *new_bus;
+ int *irqlist;
+ struct stmmac_priv *priv = netdev_priv(ndev);
+ int addr, found;
+
+ new_bus = mdiobus_alloc();
+ if (new_bus == NULL)
+ return -ENOMEM;
+
+ irqlist = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (irqlist == NULL) {
+ err = -ENOMEM;
+ goto irqlist_alloc_fail;
+ }
+
+ /* Assign IRQ to phy at address phy_addr */
+ if (priv->phy_addr != -1)
+ irqlist[priv->phy_addr] = priv->phy_irq;
+
+ new_bus->name = "STMMAC MII Bus";
+ new_bus->read = &stmmac_mdio_read;
+ new_bus->write = &stmmac_mdio_write;
+ new_bus->reset = &stmmac_mdio_reset;
+ snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->bus_id);
+ new_bus->priv = ndev;
+ new_bus->irq = irqlist;
+ new_bus->phy_mask = priv->phy_mask;
+ new_bus->parent = priv->device;
+ err = mdiobus_register(new_bus);
+ if (err != 0) {
+ pr_err("%s: Cannot register as MDIO bus\n", new_bus->name);
+ goto bus_register_fail;
+ }
+
+ priv->mii = new_bus;
+
+ found = 0;
+ for (addr = 0; addr < 32; addr++) {
+ struct phy_device *phydev = new_bus->phy_map[addr];
+ if (phydev) {
+ if (priv->phy_addr == -1) {
+ priv->phy_addr = addr;
+ phydev->irq = priv->phy_irq;
+ irqlist[addr] = priv->phy_irq;
+ }
+ pr_info("%s: PHY ID %08x at %d IRQ %d (%s)%s\n",
+ ndev->name, phydev->phy_id, addr,
+ phydev->irq, dev_name(&phydev->dev),
+ (addr == priv->phy_addr) ? " active" : "");
+ found = 1;
+ }
+ }
+
+ if (!found)
+ pr_warning("%s: No PHY found\n", ndev->name);
+
+ return 0;
+bus_register_fail:
+ kfree(irqlist);
+irqlist_alloc_fail:
+ kfree(new_bus);
+ return err;
+}
+
+/**
+ * stmmac_mdio_unregister
+ * @ndev: net device structure
+ * Description: it unregisters the MII bus
+ */
+int stmmac_mdio_unregister(struct net_device *ndev)
+{
+ struct stmmac_priv *priv = netdev_priv(ndev);
+
+ mdiobus_unregister(priv->mii);
+ priv->mii->priv = NULL;
+ kfree(priv->mii);
+
+ return 0;
+}
diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c
new file mode 100644
index 000000000000..679f61ffb1f8
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_timer.c
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ STMMAC external timer support.
+
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/etherdevice.h>
+#include "stmmac_timer.h"
+
+static void stmmac_timer_handler(void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+
+ stmmac_schedule(dev);
+
+ return;
+}
+
+#define STMMAC_TIMER_MSG(timer, freq) \
+printk(KERN_INFO "stmmac_timer: %s Timer ON (freq %dHz)\n", timer, freq);
+
+#if defined(CONFIG_STMMAC_RTC_TIMER)
+#include <linux/rtc.h>
+static struct rtc_device *stmmac_rtc;
+static rtc_task_t stmmac_task;
+
+static void stmmac_rtc_start(unsigned int new_freq)
+{
+ rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq);
+ rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1);
+ return;
+}
+
+static void stmmac_rtc_stop(void)
+{
+ rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
+ return;
+}
+
+int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
+{
+ stmmac_task.private_data = dev;
+ stmmac_task.func = stmmac_timer_handler;
+
+ stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+ if (stmmac_rtc == NULL) {
+ pr_err("open rtc device failed\n");
+ return -ENODEV;
+ }
+
+ rtc_irq_register(stmmac_rtc, &stmmac_task);
+
+ /* Periodic mode is not supported */
+ if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
+ pr_err("set periodic failed\n");
+ rtc_irq_unregister(stmmac_rtc, &stmmac_task);
+ rtc_class_close(stmmac_rtc);
+ return -1;
+ }
+
+ STMMAC_TIMER_MSG(CONFIG_RTC_HCTOSYS_DEVICE, tm->freq);
+
+ tm->timer_start = stmmac_rtc_start;
+ tm->timer_stop = stmmac_rtc_stop;
+
+ return 0;
+}
+
+int stmmac_close_ext_timer(void)
+{
+ rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
+ rtc_irq_unregister(stmmac_rtc, &stmmac_task);
+ rtc_class_close(stmmac_rtc);
+ return 0;
+}
+
+#elif defined(CONFIG_STMMAC_TMU_TIMER)
+#include <linux/clk.h>
+#define TMU_CHANNEL "tmu2_clk"
+static struct clk *timer_clock;
+
+static void stmmac_tmu_start(unsigned int new_freq)
+{
+ clk_set_rate(timer_clock, new_freq);
+ clk_enable(timer_clock);
+ return;
+}
+
+static void stmmac_tmu_stop(void)
+{
+ clk_disable(timer_clock);
+ return;
+}
+
+int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
+{
+ timer_clock = clk_get(NULL, TMU_CHANNEL);
+
+ if (timer_clock == NULL)
+ return -1;
+
+ if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
+ timer_clock = NULL;
+ return -1;
+ }
+
+ STMMAC_TIMER_MSG("TMU2", tm->freq);
+ tm->timer_start = stmmac_tmu_start;
+ tm->timer_stop = stmmac_tmu_stop;
+
+ return 0;
+}
+
+int stmmac_close_ext_timer(void)
+{
+ clk_disable(timer_clock);
+ tmu2_unregister_user();
+ clk_put(timer_clock);
+ return 0;
+}
+#endif
diff --git a/drivers/net/stmmac/stmmac_timer.h b/drivers/net/stmmac/stmmac_timer.h
new file mode 100644
index 000000000000..6863590d184b
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_timer.h
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ STMMAC external timer Header File.
+
+ Copyright (C) 2007-2009 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+struct stmmac_timer {
+ void (*timer_start) (unsigned int new_freq);
+ void (*timer_stop) (void);
+ unsigned int freq;
+ unsigned int enable;
+};
+
+/* Open the HW timer device and return 0 in case of success */
+int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm);
+/* Stop the timer and release it */
+int stmmac_close_ext_timer(void);
+/* Function used for scheduling task within the stmmac */
+void stmmac_schedule(struct net_device *dev);
+
+#if defined(CONFIG_STMMAC_TMU_TIMER)
+extern int tmu2_register_user(void *fnt, void *data);
+extern void tmu2_unregister_user(void);
+#endif
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 7019a0d1a82b..61640b99b705 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2063,7 +2063,15 @@ static int gem_check_invariants(struct gem *gp)
mif_cfg &= ~MIF_CFG_PSELECT;
writel(mif_cfg, gp->regs + MIF_CFG);
} else {
- gp->phy_type = phy_serialink;
+#ifdef CONFIG_SPARC
+ const char *p;
+
+ p = of_get_property(gp->of_node, "shared-pins", NULL);
+ if (p && !strcmp(p, "serdes"))
+ gp->phy_type = phy_serdes;
+ else
+#endif
+ gp->phy_type = phy_serialink;
}
if (gp->phy_type == phy_mii_mdio1 ||
gp->phy_type == phy_mii_mdio0) {
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index 36cb2423bcf1..75fa32e34fd0 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -1144,9 +1144,16 @@ static void dir_open_adapter (struct net_device *dev)
} else {
char **prphase = printphase;
char **prerror = printerror;
+ int pnr = err / 16 - 1;
+ int enr = err % 16 - 1;
DPRINTK("TR Adapter misc open failure, error code = ");
- printk("0x%x, Phase: %s, Error: %s\n",
- err, prphase[err/16 -1], prerror[err%16 -1]);
+ if (pnr < 0 || pnr >= ARRAY_SIZE(printphase) ||
+ enr < 0 ||
+ enr >= ARRAY_SIZE(printerror))
+ printk("0x%x, invalid Phase/Error.", err);
+ else
+ printk("0x%x, Phase: %s, Error: %s\n", err,
+ prphase[pnr], prerror[enr]);
printk(" retrying after %ds delay...\n",
TR_RETRY_INTERVAL/HZ);
}
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index c47237c2d638..32d93564a74d 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -174,7 +174,7 @@ config USB_NET_CDCETHER
* Ericsson Mobile Broadband Module (all variants)
* Motorola (DM100 and SB4100)
* Broadcom Cable Modem (reference design)
- * Toshiba (PCX1100U and F3507g)
+ * Toshiba (PCX1100U and F3507g/F3607gw)
* ...
This driver creates an interface named "ethX", where X depends on
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 4a6aff579403..21e1ba160008 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -544,20 +544,60 @@ static const struct usb_device_id products [] = {
USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &cdc_info,
}, {
- /* Ericsson F3307 */
+ /* Ericsson F3607gw ver 2 */
+ USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
+}, {
+ /* Ericsson F3607gw ver 3 */
USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM,
USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &cdc_info,
}, {
+ /* Ericsson F3307 */
+ USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
+}, {
+ /* Ericsson F3307 ver 2 */
+ USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
+}, {
+ /* Ericsson C3607w */
+ USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
+}, {
/* Toshiba F3507g */
USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,
USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &cdc_info,
}, {
+ /* Toshiba F3607gw */
+ USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
+}, {
+ /* Toshiba F3607gw ver 2 */
+ USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
+}, {
/* Dell F3507g */
USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM,
USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &cdc_info,
+}, {
+ /* Dell F3607gw */
+ USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
+}, {
+ /* Dell F3607gw ver 2 */
+ USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
},
{ }, // END
};
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 72470f77f556..a2b30a10064f 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -649,6 +649,10 @@ static const struct usb_device_id products[] = {
USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */
.driver_info = (unsigned long)&dm9601_info,
},
+ {
+ USB_DEVICE(0x0a46, 0x9000), /* DM9000E */
+ .driver_info = (unsigned long)&dm9601_info,
+ },
{}, // END
};
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index fa4e58196c21..43bc3fcc0d85 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -378,7 +378,7 @@ static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
}
#define DUMP(buf_, len_) \
- dbg_dump(__LINE__, __func__, buf_, len_)
+ dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_)
#define DUMP1(buf_, len_) \
do { \
@@ -1363,7 +1363,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
/* reset the rts and dtr */
/* do the actual close */
serial->open_count--;
- kref_put(&serial->parent->ref, hso_serial_ref_free);
+
if (serial->open_count <= 0) {
serial->open_count = 0;
spin_lock_irq(&serial->serial_lock);
@@ -1383,6 +1383,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
usb_autopm_put_interface(serial->parent->interface);
mutex_unlock(&serial->parent->mutex);
+
+ kref_put(&serial->parent->ref, hso_serial_ref_free);
}
/* close the requested serial port */
@@ -1527,7 +1529,7 @@ static void tiocmget_intr_callback(struct urb *urb)
dev_warn(&usb->dev,
"hso received invalid serial state notification\n");
DUMP(serial_state_notification,
- sizeof(hso_serial_state_notifation))
+ sizeof(struct hso_serial_state_notification));
} else {
UART_state_bitmap = le16_to_cpu(serial_state_notification->
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 6fdaba8674b9..ed4a508ef262 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -62,8 +62,11 @@ static char *devid=NULL;
static struct usb_eth_dev usb_dev_id[] = {
#define PEGASUS_DEV(pn, vid, pid, flags) \
{.name = pn, .vendor = vid, .device = pid, .private = flags},
+#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
+ PEGASUS_DEV(pn, vid, pid, flags)
#include "pegasus.h"
#undef PEGASUS_DEV
+#undef PEGASUS_DEV_CLASS
{NULL, 0, 0, 0},
{NULL, 0, 0, 0}
};
@@ -71,8 +74,18 @@ static struct usb_eth_dev usb_dev_id[] = {
static struct usb_device_id pegasus_ids[] = {
#define PEGASUS_DEV(pn, vid, pid, flags) \
{.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
+/*
+ * The Belkin F8T012xx1 bluetooth adaptor has the same vendor and product
+ * IDs as the Belkin F5D5050, so we need to teach the pegasus driver to
+ * ignore adaptors belonging to the "Wireless" class 0xE0. For this one
+ * case anyway, seeing as the pegasus is for "Wired" adaptors.
+ */
+#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
+ {.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS), \
+ .idVendor = vid, .idProduct = pid, .bDeviceClass = dclass},
#include "pegasus.h"
#undef PEGASUS_DEV
+#undef PEGASUS_DEV_CLASS
{},
{}
};
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h
index f968c834ff63..5d02f0200737 100644
--- a/drivers/net/usb/pegasus.h
+++ b/drivers/net/usb/pegasus.h
@@ -202,7 +202,11 @@ PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121,
+/*
+ * Distinguish between this Belkin adaptor and the Belkin bluetooth adaptors
+ * with the same product IDs by checking the device class too.
+ */
+PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
DEFAULT_GPIO_RESET )
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 0caa8008c51c..f56dec6119c3 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -362,12 +362,12 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
retval = -EINVAL;
goto halt_fail_and_release;
}
- dev->hard_mtu = tmp;
- net->mtu = dev->hard_mtu - net->hard_header_len;
dev_warn(&intf->dev,
"dev can't take %u byte packets (max %u), "
"adjusting MTU to %u\n",
- dev->hard_mtu, tmp, net->mtu);
+ dev->hard_mtu, tmp, tmp - net->hard_header_len);
+ dev->hard_mtu = tmp;
+ net->mtu = dev->hard_mtu - net->hard_header_len;
}
/* REVISIT: peripheral "alignment" request is ignored ... */
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index ade5b344f75d..52af5017c46b 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -210,32 +210,29 @@ rx_drop:
static struct net_device_stats *veth_get_stats(struct net_device *dev)
{
struct veth_priv *priv;
- struct net_device_stats *dev_stats;
int cpu;
- struct veth_net_stats *stats;
+ struct veth_net_stats *stats, total = {0};
priv = netdev_priv(dev);
- dev_stats = &dev->stats;
-
- dev_stats->rx_packets = 0;
- dev_stats->tx_packets = 0;
- dev_stats->rx_bytes = 0;
- dev_stats->tx_bytes = 0;
- dev_stats->tx_dropped = 0;
- dev_stats->rx_dropped = 0;
- for_each_online_cpu(cpu) {
+ for_each_possible_cpu(cpu) {
stats = per_cpu_ptr(priv->stats, cpu);
- dev_stats->rx_packets += stats->rx_packets;
- dev_stats->tx_packets += stats->tx_packets;
- dev_stats->rx_bytes += stats->rx_bytes;
- dev_stats->tx_bytes += stats->tx_bytes;
- dev_stats->tx_dropped += stats->tx_dropped;
- dev_stats->rx_dropped += stats->rx_dropped;
+ total.rx_packets += stats->rx_packets;
+ total.tx_packets += stats->tx_packets;
+ total.rx_bytes += stats->rx_bytes;
+ total.tx_bytes += stats->tx_bytes;
+ total.tx_dropped += stats->tx_dropped;
+ total.rx_dropped += stats->rx_dropped;
}
-
- return dev_stats;
+ dev->stats.rx_packets = total.rx_packets;
+ dev->stats.tx_packets = total.tx_packets;
+ dev->stats.rx_bytes = total.rx_bytes;
+ dev->stats.tx_bytes = total.tx_bytes;
+ dev->stats.tx_dropped = total.tx_dropped;
+ dev->stats.rx_dropped = total.rx_dropped;
+
+ return &dev->stats;
}
static int veth_open(struct net_device *dev)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 8d009760277c..b9e002fccbca 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -22,7 +22,6 @@
#include <linux/ethtool.h>
#include <linux/module.h>
#include <linux/virtio.h>
-#include <linux/virtio_ids.h>
#include <linux/virtio_net.h>
#include <linux/scatterlist.h>
#include <linux/if_vlan.h>
@@ -454,7 +453,7 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
vi->dev->stats.tx_bytes += skb->len;
vi->dev->stats.tx_packets++;
tot_sgs += skb_vnet_hdr(skb)->num_sg;
- kfree_skb(skb);
+ dev_kfree_skb_any(skb);
}
return tot_sgs;
}
@@ -517,8 +516,7 @@ again:
/* Free up any pending old buffers before queueing new ones. */
free_old_xmit_skbs(vi);
- /* Put new one in send queue and do transmit */
- __skb_queue_head(&vi->send, skb);
+ /* Try to transmit */
capacity = xmit_skb(vi, skb);
/* This can happen with OOM and indirect buffers. */
@@ -532,8 +530,17 @@ again:
}
return NETDEV_TX_BUSY;
}
-
vi->svq->vq_ops->kick(vi->svq);
+
+ /*
+ * Put new one in send queue. You'd expect we'd need this before
+ * xmit_skb calls add_buf(), since the callback can be triggered
+ * immediately after that. But since the callback just triggers
+ * another call back here, normal network xmit locking prevents the
+ * race.
+ */
+ __skb_queue_head(&vi->send, skb);
+
/* Don't wait up for transmitted skbs to be freed. */
skb_orphan(skb);
nf_reset(skb);
@@ -991,7 +998,7 @@ static unsigned int features[] = {
VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
};
-static struct virtio_driver virtio_net = {
+static struct virtio_driver virtio_net_driver = {
.feature_table = features,
.feature_table_size = ARRAY_SIZE(features),
.driver.name = KBUILD_MODNAME,
@@ -1004,12 +1011,12 @@ static struct virtio_driver virtio_net = {
static int __init init(void)
{
- return register_virtio_driver(&virtio_net);
+ return register_virtio_driver(&virtio_net_driver);
}
static void __exit fini(void)
{
- unregister_virtio_driver(&virtio_net);
+ unregister_virtio_driver(&virtio_net_driver);
}
module_init(init);
module_exit(fini);
diff --git a/drivers/net/vmxnet3/Makefile b/drivers/net/vmxnet3/Makefile
new file mode 100644
index 000000000000..880f5098eac9
--- /dev/null
+++ b/drivers/net/vmxnet3/Makefile
@@ -0,0 +1,35 @@
+################################################################################
+#
+# Linux driver for VMware's vmxnet3 ethernet NIC.
+#
+# Copyright (C) 2007-2009, VMware, 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; version 2 of the License and no 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, GOOD TITLE or
+# NON INFRINGEMENT. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+#
+#
+################################################################################
+
+#
+# Makefile for the VMware vmxnet3 ethernet NIC driver
+#
+
+obj-$(CONFIG_VMXNET3) += vmxnet3.o
+
+vmxnet3-objs := vmxnet3_drv.o vmxnet3_ethtool.o
diff --git a/drivers/net/vmxnet3/upt1_defs.h b/drivers/net/vmxnet3/upt1_defs.h
new file mode 100644
index 000000000000..37108fb226d3
--- /dev/null
+++ b/drivers/net/vmxnet3/upt1_defs.h
@@ -0,0 +1,96 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, 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; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+#ifndef _UPT1_DEFS_H
+#define _UPT1_DEFS_H
+
+struct UPT1_TxStats {
+ u64 TSOPktsTxOK; /* TSO pkts post-segmentation */
+ u64 TSOBytesTxOK;
+ u64 ucastPktsTxOK;
+ u64 ucastBytesTxOK;
+ u64 mcastPktsTxOK;
+ u64 mcastBytesTxOK;
+ u64 bcastPktsTxOK;
+ u64 bcastBytesTxOK;
+ u64 pktsTxError;
+ u64 pktsTxDiscard;
+};
+
+struct UPT1_RxStats {
+ u64 LROPktsRxOK; /* LRO pkts */
+ u64 LROBytesRxOK; /* bytes from LRO pkts */
+ /* the following counters are for pkts from the wire, i.e., pre-LRO */
+ u64 ucastPktsRxOK;
+ u64 ucastBytesRxOK;
+ u64 mcastPktsRxOK;
+ u64 mcastBytesRxOK;
+ u64 bcastPktsRxOK;
+ u64 bcastBytesRxOK;
+ u64 pktsRxOutOfBuf;
+ u64 pktsRxError;
+};
+
+/* interrupt moderation level */
+enum {
+ UPT1_IML_NONE = 0, /* no interrupt moderation */
+ UPT1_IML_HIGHEST = 7, /* least intr generated */
+ UPT1_IML_ADAPTIVE = 8, /* adpative intr moderation */
+};
+/* values for UPT1_RSSConf.hashFunc */
+enum {
+ UPT1_RSS_HASH_TYPE_NONE = 0x0,
+ UPT1_RSS_HASH_TYPE_IPV4 = 0x01,
+ UPT1_RSS_HASH_TYPE_TCP_IPV4 = 0x02,
+ UPT1_RSS_HASH_TYPE_IPV6 = 0x04,
+ UPT1_RSS_HASH_TYPE_TCP_IPV6 = 0x08,
+};
+
+enum {
+ UPT1_RSS_HASH_FUNC_NONE = 0x0,
+ UPT1_RSS_HASH_FUNC_TOEPLITZ = 0x01,
+};
+
+#define UPT1_RSS_MAX_KEY_SIZE 40
+#define UPT1_RSS_MAX_IND_TABLE_SIZE 128
+
+struct UPT1_RSSConf {
+ u16 hashType;
+ u16 hashFunc;
+ u16 hashKeySize;
+ u16 indTableSize;
+ u8 hashKey[UPT1_RSS_MAX_KEY_SIZE];
+ u8 indTable[UPT1_RSS_MAX_IND_TABLE_SIZE];
+};
+
+/* features */
+enum {
+ UPT1_F_RXCSUM = 0x0001, /* rx csum verification */
+ UPT1_F_RSS = 0x0002,
+ UPT1_F_RXVLAN = 0x0004, /* VLAN tag stripping */
+ UPT1_F_LRO = 0x0008,
+};
+#endif
diff --git a/drivers/net/vmxnet3/vmxnet3_defs.h b/drivers/net/vmxnet3/vmxnet3_defs.h
new file mode 100644
index 000000000000..dc8ee4438a4f
--- /dev/null
+++ b/drivers/net/vmxnet3/vmxnet3_defs.h
@@ -0,0 +1,535 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, 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; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+#ifndef _VMXNET3_DEFS_H_
+#define _VMXNET3_DEFS_H_
+
+#include "upt1_defs.h"
+
+/* all registers are 32 bit wide */
+/* BAR 1 */
+enum {
+ VMXNET3_REG_VRRS = 0x0, /* Vmxnet3 Revision Report Selection */
+ VMXNET3_REG_UVRS = 0x8, /* UPT Version Report Selection */
+ VMXNET3_REG_DSAL = 0x10, /* Driver Shared Address Low */
+ VMXNET3_REG_DSAH = 0x18, /* Driver Shared Address High */
+ VMXNET3_REG_CMD = 0x20, /* Command */
+ VMXNET3_REG_MACL = 0x28, /* MAC Address Low */
+ VMXNET3_REG_MACH = 0x30, /* MAC Address High */
+ VMXNET3_REG_ICR = 0x38, /* Interrupt Cause Register */
+ VMXNET3_REG_ECR = 0x40 /* Event Cause Register */
+};
+
+/* BAR 0 */
+enum {
+ VMXNET3_REG_IMR = 0x0, /* Interrupt Mask Register */
+ VMXNET3_REG_TXPROD = 0x600, /* Tx Producer Index */
+ VMXNET3_REG_RXPROD = 0x800, /* Rx Producer Index for ring 1 */
+ VMXNET3_REG_RXPROD2 = 0xA00 /* Rx Producer Index for ring 2 */
+};
+
+#define VMXNET3_PT_REG_SIZE 4096 /* BAR 0 */
+#define VMXNET3_VD_REG_SIZE 4096 /* BAR 1 */
+
+#define VMXNET3_REG_ALIGN 8 /* All registers are 8-byte aligned. */
+#define VMXNET3_REG_ALIGN_MASK 0x7
+
+/* I/O Mapped access to registers */
+#define VMXNET3_IO_TYPE_PT 0
+#define VMXNET3_IO_TYPE_VD 1
+#define VMXNET3_IO_ADDR(type, reg) (((type) << 24) | ((reg) & 0xFFFFFF))
+#define VMXNET3_IO_TYPE(addr) ((addr) >> 24)
+#define VMXNET3_IO_REG(addr) ((addr) & 0xFFFFFF)
+
+enum {
+ VMXNET3_CMD_FIRST_SET = 0xCAFE0000,
+ VMXNET3_CMD_ACTIVATE_DEV = VMXNET3_CMD_FIRST_SET,
+ VMXNET3_CMD_QUIESCE_DEV,
+ VMXNET3_CMD_RESET_DEV,
+ VMXNET3_CMD_UPDATE_RX_MODE,
+ VMXNET3_CMD_UPDATE_MAC_FILTERS,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS,
+ VMXNET3_CMD_UPDATE_RSSIDT,
+ VMXNET3_CMD_UPDATE_IML,
+ VMXNET3_CMD_UPDATE_PMCFG,
+ VMXNET3_CMD_UPDATE_FEATURE,
+ VMXNET3_CMD_LOAD_PLUGIN,
+
+ VMXNET3_CMD_FIRST_GET = 0xF00D0000,
+ VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
+ VMXNET3_CMD_GET_STATS,
+ VMXNET3_CMD_GET_LINK,
+ VMXNET3_CMD_GET_PERM_MAC_LO,
+ VMXNET3_CMD_GET_PERM_MAC_HI,
+ VMXNET3_CMD_GET_DID_LO,
+ VMXNET3_CMD_GET_DID_HI,
+ VMXNET3_CMD_GET_DEV_EXTRA_INFO,
+ VMXNET3_CMD_GET_CONF_INTR
+};
+
+struct Vmxnet3_TxDesc {
+ u64 addr;
+
+ u32 len:14;
+ u32 gen:1; /* generation bit */
+ u32 rsvd:1;
+ u32 dtype:1; /* descriptor type */
+ u32 ext1:1;
+ u32 msscof:14; /* MSS, checksum offset, flags */
+
+ u32 hlen:10; /* header len */
+ u32 om:2; /* offload mode */
+ u32 eop:1; /* End Of Packet */
+ u32 cq:1; /* completion request */
+ u32 ext2:1;
+ u32 ti:1; /* VLAN Tag Insertion */
+ u32 tci:16; /* Tag to Insert */
+};
+
+/* TxDesc.OM values */
+#define VMXNET3_OM_NONE 0
+#define VMXNET3_OM_CSUM 2
+#define VMXNET3_OM_TSO 3
+
+/* fields in TxDesc we access w/o using bit fields */
+#define VMXNET3_TXD_EOP_SHIFT 12
+#define VMXNET3_TXD_CQ_SHIFT 13
+#define VMXNET3_TXD_GEN_SHIFT 14
+
+#define VMXNET3_TXD_CQ (1 << VMXNET3_TXD_CQ_SHIFT)
+#define VMXNET3_TXD_EOP (1 << VMXNET3_TXD_EOP_SHIFT)
+#define VMXNET3_TXD_GEN (1 << VMXNET3_TXD_GEN_SHIFT)
+
+#define VMXNET3_HDR_COPY_SIZE 128
+
+
+struct Vmxnet3_TxDataDesc {
+ u8 data[VMXNET3_HDR_COPY_SIZE];
+};
+
+
+struct Vmxnet3_TxCompDesc {
+ u32 txdIdx:12; /* Index of the EOP TxDesc */
+ u32 ext1:20;
+
+ u32 ext2;
+ u32 ext3;
+
+ u32 rsvd:24;
+ u32 type:7; /* completion type */
+ u32 gen:1; /* generation bit */
+};
+
+
+struct Vmxnet3_RxDesc {
+ u64 addr;
+
+ u32 len:14;
+ u32 btype:1; /* Buffer Type */
+ u32 dtype:1; /* Descriptor type */
+ u32 rsvd:15;
+ u32 gen:1; /* Generation bit */
+
+ u32 ext1;
+};
+
+/* values of RXD.BTYPE */
+#define VMXNET3_RXD_BTYPE_HEAD 0 /* head only */
+#define VMXNET3_RXD_BTYPE_BODY 1 /* body only */
+
+/* fields in RxDesc we access w/o using bit fields */
+#define VMXNET3_RXD_BTYPE_SHIFT 14
+#define VMXNET3_RXD_GEN_SHIFT 31
+
+
+struct Vmxnet3_RxCompDesc {
+ u32 rxdIdx:12; /* Index of the RxDesc */
+ u32 ext1:2;
+ u32 eop:1; /* End of Packet */
+ u32 sop:1; /* Start of Packet */
+ u32 rqID:10; /* rx queue/ring ID */
+ u32 rssType:4; /* RSS hash type used */
+ u32 cnc:1; /* Checksum Not Calculated */
+ u32 ext2:1;
+
+ u32 rssHash; /* RSS hash value */
+
+ u32 len:14; /* data length */
+ u32 err:1; /* Error */
+ u32 ts:1; /* Tag is stripped */
+ u32 tci:16; /* Tag stripped */
+
+ u32 csum:16;
+ u32 tuc:1; /* TCP/UDP Checksum Correct */
+ u32 udp:1; /* UDP packet */
+ u32 tcp:1; /* TCP packet */
+ u32 ipc:1; /* IP Checksum Correct */
+ u32 v6:1; /* IPv6 */
+ u32 v4:1; /* IPv4 */
+ u32 frg:1; /* IP Fragment */
+ u32 fcs:1; /* Frame CRC correct */
+ u32 type:7; /* completion type */
+ u32 gen:1; /* generation bit */
+};
+
+/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
+#define VMXNET3_RCD_TUC_SHIFT 16
+#define VMXNET3_RCD_IPC_SHIFT 19
+
+/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.qword[1] */
+#define VMXNET3_RCD_TYPE_SHIFT 56
+#define VMXNET3_RCD_GEN_SHIFT 63
+
+/* csum OK for TCP/UDP pkts over IP */
+#define VMXNET3_RCD_CSUM_OK (1 << VMXNET3_RCD_TUC_SHIFT | \
+ 1 << VMXNET3_RCD_IPC_SHIFT)
+
+/* value of RxCompDesc.rssType */
+enum {
+ VMXNET3_RCD_RSS_TYPE_NONE = 0,
+ VMXNET3_RCD_RSS_TYPE_IPV4 = 1,
+ VMXNET3_RCD_RSS_TYPE_TCPIPV4 = 2,
+ VMXNET3_RCD_RSS_TYPE_IPV6 = 3,
+ VMXNET3_RCD_RSS_TYPE_TCPIPV6 = 4,
+};
+
+
+/* a union for accessing all cmd/completion descriptors */
+union Vmxnet3_GenericDesc {
+ u64 qword[2];
+ u32 dword[4];
+ u16 word[8];
+ struct Vmxnet3_TxDesc txd;
+ struct Vmxnet3_RxDesc rxd;
+ struct Vmxnet3_TxCompDesc tcd;
+ struct Vmxnet3_RxCompDesc rcd;
+};
+
+#define VMXNET3_INIT_GEN 1
+
+/* Max size of a single tx buffer */
+#define VMXNET3_MAX_TX_BUF_SIZE (1 << 14)
+
+/* # of tx desc needed for a tx buffer size */
+#define VMXNET3_TXD_NEEDED(size) (((size) + VMXNET3_MAX_TX_BUF_SIZE - 1) / \
+ VMXNET3_MAX_TX_BUF_SIZE)
+
+/* max # of tx descs for a non-tso pkt */
+#define VMXNET3_MAX_TXD_PER_PKT 16
+
+/* Max size of a single rx buffer */
+#define VMXNET3_MAX_RX_BUF_SIZE ((1 << 14) - 1)
+/* Minimum size of a type 0 buffer */
+#define VMXNET3_MIN_T0_BUF_SIZE 128
+#define VMXNET3_MAX_CSUM_OFFSET 1024
+
+/* Ring base address alignment */
+#define VMXNET3_RING_BA_ALIGN 512
+#define VMXNET3_RING_BA_MASK (VMXNET3_RING_BA_ALIGN - 1)
+
+/* Ring size must be a multiple of 32 */
+#define VMXNET3_RING_SIZE_ALIGN 32
+#define VMXNET3_RING_SIZE_MASK (VMXNET3_RING_SIZE_ALIGN - 1)
+
+/* Max ring size */
+#define VMXNET3_TX_RING_MAX_SIZE 4096
+#define VMXNET3_TC_RING_MAX_SIZE 4096
+#define VMXNET3_RX_RING_MAX_SIZE 4096
+#define VMXNET3_RC_RING_MAX_SIZE 8192
+
+/* a list of reasons for queue stop */
+
+enum {
+ VMXNET3_ERR_NOEOP = 0x80000000, /* cannot find the EOP desc of a pkt */
+ VMXNET3_ERR_TXD_REUSE = 0x80000001, /* reuse TxDesc before tx completion */
+ VMXNET3_ERR_BIG_PKT = 0x80000002, /* too many TxDesc for a pkt */
+ VMXNET3_ERR_DESC_NOT_SPT = 0x80000003, /* descriptor type not supported */
+ VMXNET3_ERR_SMALL_BUF = 0x80000004, /* type 0 buffer too small */
+ VMXNET3_ERR_STRESS = 0x80000005, /* stress option firing in vmkernel */
+ VMXNET3_ERR_SWITCH = 0x80000006, /* mode switch failure */
+ VMXNET3_ERR_TXD_INVALID = 0x80000007, /* invalid TxDesc */
+};
+
+/* completion descriptor types */
+#define VMXNET3_CDTYPE_TXCOMP 0 /* Tx Completion Descriptor */
+#define VMXNET3_CDTYPE_RXCOMP 3 /* Rx Completion Descriptor */
+
+enum {
+ VMXNET3_GOS_BITS_UNK = 0, /* unknown */
+ VMXNET3_GOS_BITS_32 = 1,
+ VMXNET3_GOS_BITS_64 = 2,
+};
+
+#define VMXNET3_GOS_TYPE_LINUX 1
+
+
+struct Vmxnet3_GOSInfo {
+ u32 gosBits:2; /* 32-bit or 64-bit? */
+ u32 gosType:4; /* which guest */
+ u32 gosVer:16; /* gos version */
+ u32 gosMisc:10; /* other info about gos */
+};
+
+
+struct Vmxnet3_DriverInfo {
+ u32 version;
+ struct Vmxnet3_GOSInfo gos;
+ u32 vmxnet3RevSpt;
+ u32 uptVerSpt;
+};
+
+
+#define VMXNET3_REV1_MAGIC 0xbabefee1
+
+/*
+ * QueueDescPA must be 128 bytes aligned. It points to an array of
+ * Vmxnet3_TxQueueDesc followed by an array of Vmxnet3_RxQueueDesc.
+ * The number of Vmxnet3_TxQueueDesc/Vmxnet3_RxQueueDesc are specified by
+ * Vmxnet3_MiscConf.numTxQueues/numRxQueues, respectively.
+ */
+#define VMXNET3_QUEUE_DESC_ALIGN 128
+
+
+struct Vmxnet3_MiscConf {
+ struct Vmxnet3_DriverInfo driverInfo;
+ u64 uptFeatures;
+ u64 ddPA; /* driver data PA */
+ u64 queueDescPA; /* queue descriptor table PA */
+ u32 ddLen; /* driver data len */
+ u32 queueDescLen; /* queue desc. table len in bytes */
+ u32 mtu;
+ u16 maxNumRxSG;
+ u8 numTxQueues;
+ u8 numRxQueues;
+ u32 reserved[4];
+};
+
+
+struct Vmxnet3_TxQueueConf {
+ u64 txRingBasePA;
+ u64 dataRingBasePA;
+ u64 compRingBasePA;
+ u64 ddPA; /* driver data */
+ u64 reserved;
+ u32 txRingSize; /* # of tx desc */
+ u32 dataRingSize; /* # of data desc */
+ u32 compRingSize; /* # of comp desc */
+ u32 ddLen; /* size of driver data */
+ u8 intrIdx;
+ u8 _pad[7];
+};
+
+
+struct Vmxnet3_RxQueueConf {
+ u64 rxRingBasePA[2];
+ u64 compRingBasePA;
+ u64 ddPA; /* driver data */
+ u64 reserved;
+ u32 rxRingSize[2]; /* # of rx desc */
+ u32 compRingSize; /* # of rx comp desc */
+ u32 ddLen; /* size of driver data */
+ u8 intrIdx;
+ u8 _pad[7];
+};
+
+
+enum vmxnet3_intr_mask_mode {
+ VMXNET3_IMM_AUTO = 0,
+ VMXNET3_IMM_ACTIVE = 1,
+ VMXNET3_IMM_LAZY = 2
+};
+
+enum vmxnet3_intr_type {
+ VMXNET3_IT_AUTO = 0,
+ VMXNET3_IT_INTX = 1,
+ VMXNET3_IT_MSI = 2,
+ VMXNET3_IT_MSIX = 3
+};
+
+#define VMXNET3_MAX_TX_QUEUES 8
+#define VMXNET3_MAX_RX_QUEUES 16
+/* addition 1 for events */
+#define VMXNET3_MAX_INTRS 25
+
+
+struct Vmxnet3_IntrConf {
+ bool autoMask;
+ u8 numIntrs; /* # of interrupts */
+ u8 eventIntrIdx;
+ u8 modLevels[VMXNET3_MAX_INTRS]; /* moderation level for
+ * each intr */
+ u32 reserved[3];
+};
+
+/* one bit per VLAN ID, the size is in the units of u32 */
+#define VMXNET3_VFT_SIZE (4096 / (sizeof(u32) * 8))
+
+
+struct Vmxnet3_QueueStatus {
+ bool stopped;
+ u8 _pad[3];
+ u32 error;
+};
+
+
+struct Vmxnet3_TxQueueCtrl {
+ u32 txNumDeferred;
+ u32 txThreshold;
+ u64 reserved;
+};
+
+
+struct Vmxnet3_RxQueueCtrl {
+ bool updateRxProd;
+ u8 _pad[7];
+ u64 reserved;
+};
+
+enum {
+ VMXNET3_RXM_UCAST = 0x01, /* unicast only */
+ VMXNET3_RXM_MCAST = 0x02, /* multicast passing the filters */
+ VMXNET3_RXM_BCAST = 0x04, /* broadcast only */
+ VMXNET3_RXM_ALL_MULTI = 0x08, /* all multicast */
+ VMXNET3_RXM_PROMISC = 0x10 /* promiscuous */
+};
+
+struct Vmxnet3_RxFilterConf {
+ u32 rxMode; /* VMXNET3_RXM_xxx */
+ u16 mfTableLen; /* size of the multicast filter table */
+ u16 _pad1;
+ u64 mfTablePA; /* PA of the multicast filters table */
+ u32 vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */
+};
+
+
+#define VMXNET3_PM_MAX_FILTERS 6
+#define VMXNET3_PM_MAX_PATTERN_SIZE 128
+#define VMXNET3_PM_MAX_MASK_SIZE (VMXNET3_PM_MAX_PATTERN_SIZE / 8)
+
+#define VMXNET3_PM_WAKEUP_MAGIC 0x01 /* wake up on magic pkts */
+#define VMXNET3_PM_WAKEUP_FILTER 0x02 /* wake up on pkts matching
+ * filters */
+
+
+struct Vmxnet3_PM_PktFilter {
+ u8 maskSize;
+ u8 patternSize;
+ u8 mask[VMXNET3_PM_MAX_MASK_SIZE];
+ u8 pattern[VMXNET3_PM_MAX_PATTERN_SIZE];
+ u8 pad[6];
+};
+
+
+struct Vmxnet3_PMConf {
+ u16 wakeUpEvents; /* VMXNET3_PM_WAKEUP_xxx */
+ u8 numFilters;
+ u8 pad[5];
+ struct Vmxnet3_PM_PktFilter filters[VMXNET3_PM_MAX_FILTERS];
+};
+
+
+struct Vmxnet3_VariableLenConfDesc {
+ u32 confVer;
+ u32 confLen;
+ u64 confPA;
+};
+
+
+struct Vmxnet3_TxQueueDesc {
+ struct Vmxnet3_TxQueueCtrl ctrl;
+ struct Vmxnet3_TxQueueConf conf;
+
+ /* Driver read after a GET command */
+ struct Vmxnet3_QueueStatus status;
+ struct UPT1_TxStats stats;
+ u8 _pad[88]; /* 128 aligned */
+};
+
+
+struct Vmxnet3_RxQueueDesc {
+ struct Vmxnet3_RxQueueCtrl ctrl;
+ struct Vmxnet3_RxQueueConf conf;
+ /* Driver read after a GET commad */
+ struct Vmxnet3_QueueStatus status;
+ struct UPT1_RxStats stats;
+ u8 __pad[88]; /* 128 aligned */
+};
+
+
+struct Vmxnet3_DSDevRead {
+ /* read-only region for device, read by dev in response to a SET cmd */
+ struct Vmxnet3_MiscConf misc;
+ struct Vmxnet3_IntrConf intrConf;
+ struct Vmxnet3_RxFilterConf rxFilterConf;
+ struct Vmxnet3_VariableLenConfDesc rssConfDesc;
+ struct Vmxnet3_VariableLenConfDesc pmConfDesc;
+ struct Vmxnet3_VariableLenConfDesc pluginConfDesc;
+};
+
+/* All structures in DriverShared are padded to multiples of 8 bytes */
+struct Vmxnet3_DriverShared {
+ u32 magic;
+ /* make devRead start at 64bit boundaries */
+ u32 pad;
+ struct Vmxnet3_DSDevRead devRead;
+ u32 ecr;
+ u32 reserved[5];
+};
+
+
+#define VMXNET3_ECR_RQERR (1 << 0)
+#define VMXNET3_ECR_TQERR (1 << 1)
+#define VMXNET3_ECR_LINK (1 << 2)
+#define VMXNET3_ECR_DIC (1 << 3)
+#define VMXNET3_ECR_DEBUG (1 << 4)
+
+/* flip the gen bit of a ring */
+#define VMXNET3_FLIP_RING_GEN(gen) ((gen) = (gen) ^ 0x1)
+
+/* only use this if moving the idx won't affect the gen bit */
+#define VMXNET3_INC_RING_IDX_ONLY(idx, ring_size) \
+ do {\
+ (idx)++;\
+ if (unlikely((idx) == (ring_size))) {\
+ (idx) = 0;\
+ } \
+ } while (0)
+
+#define VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid) \
+ (vfTable[vid >> 5] |= (1 << (vid & 31)))
+#define VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid) \
+ (vfTable[vid >> 5] &= ~(1 << (vid & 31)))
+
+#define VMXNET3_VFTABLE_ENTRY_IS_SET(vfTable, vid) \
+ ((vfTable[vid >> 5] & (1 << (vid & 31))) != 0)
+
+#define VMXNET3_MAX_MTU 9000
+#define VMXNET3_MIN_MTU 60
+
+#define VMXNET3_LINK_UP (10000 << 16 | 1) /* 10 Gbps, up */
+#define VMXNET3_LINK_DOWN 0
+
+#endif /* _VMXNET3_DEFS_H_ */
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
new file mode 100644
index 000000000000..004353a46af0
--- /dev/null
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -0,0 +1,2574 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, 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; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+#include "vmxnet3_int.h"
+
+char vmxnet3_driver_name[] = "vmxnet3";
+#define VMXNET3_DRIVER_DESC "VMware vmxnet3 virtual NIC driver"
+
+
+/*
+ * PCI Device ID Table
+ * Last entry must be all 0s
+ */
+static const struct pci_device_id vmxnet3_pciid_table[] = {
+ {PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_VMXNET3)},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, vmxnet3_pciid_table);
+
+static atomic_t devices_found;
+
+
+/*
+ * Enable/Disable the given intr
+ */
+static void
+vmxnet3_enable_intr(struct vmxnet3_adapter *adapter, unsigned intr_idx)
+{
+ VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_IMR + intr_idx * 8, 0);
+}
+
+
+static void
+vmxnet3_disable_intr(struct vmxnet3_adapter *adapter, unsigned intr_idx)
+{
+ VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_IMR + intr_idx * 8, 1);
+}
+
+
+/*
+ * Enable/Disable all intrs used by the device
+ */
+static void
+vmxnet3_enable_all_intrs(struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->intr.num_intrs; i++)
+ vmxnet3_enable_intr(adapter, i);
+}
+
+
+static void
+vmxnet3_disable_all_intrs(struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->intr.num_intrs; i++)
+ vmxnet3_disable_intr(adapter, i);
+}
+
+
+static void
+vmxnet3_ack_events(struct vmxnet3_adapter *adapter, u32 events)
+{
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_ECR, events);
+}
+
+
+static bool
+vmxnet3_tq_stopped(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
+{
+ return netif_queue_stopped(adapter->netdev);
+}
+
+
+static void
+vmxnet3_tq_start(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
+{
+ tq->stopped = false;
+ netif_start_queue(adapter->netdev);
+}
+
+
+static void
+vmxnet3_tq_wake(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
+{
+ tq->stopped = false;
+ netif_wake_queue(adapter->netdev);
+}
+
+
+static void
+vmxnet3_tq_stop(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
+{
+ tq->stopped = true;
+ tq->num_stop++;
+ netif_stop_queue(adapter->netdev);
+}
+
+
+/*
+ * Check the link state. This may start or stop the tx queue.
+ */
+static void
+vmxnet3_check_link(struct vmxnet3_adapter *adapter)
+{
+ u32 ret;
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
+ ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+ adapter->link_speed = ret >> 16;
+ if (ret & 1) { /* Link is up. */
+ printk(KERN_INFO "%s: NIC Link is Up %d Mbps\n",
+ adapter->netdev->name, adapter->link_speed);
+ if (!netif_carrier_ok(adapter->netdev))
+ netif_carrier_on(adapter->netdev);
+
+ vmxnet3_tq_start(&adapter->tx_queue, adapter);
+ } else {
+ printk(KERN_INFO "%s: NIC Link is Down\n",
+ adapter->netdev->name);
+ if (netif_carrier_ok(adapter->netdev))
+ netif_carrier_off(adapter->netdev);
+
+ vmxnet3_tq_stop(&adapter->tx_queue, adapter);
+ }
+}
+
+
+static void
+vmxnet3_process_events(struct vmxnet3_adapter *adapter)
+{
+ u32 events = adapter->shared->ecr;
+ if (!events)
+ return;
+
+ vmxnet3_ack_events(adapter, events);
+
+ /* Check if link state has changed */
+ if (events & VMXNET3_ECR_LINK)
+ vmxnet3_check_link(adapter);
+
+ /* Check if there is an error on xmit/recv queues */
+ if (events & (VMXNET3_ECR_TQERR | VMXNET3_ECR_RQERR)) {
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_GET_QUEUE_STATUS);
+
+ if (adapter->tqd_start->status.stopped) {
+ printk(KERN_ERR "%s: tq error 0x%x\n",
+ adapter->netdev->name,
+ adapter->tqd_start->status.error);
+ }
+ if (adapter->rqd_start->status.stopped) {
+ printk(KERN_ERR "%s: rq error 0x%x\n",
+ adapter->netdev->name,
+ adapter->rqd_start->status.error);
+ }
+
+ schedule_work(&adapter->work);
+ }
+}
+
+
+static void
+vmxnet3_unmap_tx_buf(struct vmxnet3_tx_buf_info *tbi,
+ struct pci_dev *pdev)
+{
+ if (tbi->map_type == VMXNET3_MAP_SINGLE)
+ pci_unmap_single(pdev, tbi->dma_addr, tbi->len,
+ PCI_DMA_TODEVICE);
+ else if (tbi->map_type == VMXNET3_MAP_PAGE)
+ pci_unmap_page(pdev, tbi->dma_addr, tbi->len,
+ PCI_DMA_TODEVICE);
+ else
+ BUG_ON(tbi->map_type != VMXNET3_MAP_NONE);
+
+ tbi->map_type = VMXNET3_MAP_NONE; /* to help debugging */
+}
+
+
+static int
+vmxnet3_unmap_pkt(u32 eop_idx, struct vmxnet3_tx_queue *tq,
+ struct pci_dev *pdev, struct vmxnet3_adapter *adapter)
+{
+ struct sk_buff *skb;
+ int entries = 0;
+
+ /* no out of order completion */
+ BUG_ON(tq->buf_info[eop_idx].sop_idx != tq->tx_ring.next2comp);
+ BUG_ON(tq->tx_ring.base[eop_idx].txd.eop != 1);
+
+ skb = tq->buf_info[eop_idx].skb;
+ BUG_ON(skb == NULL);
+ tq->buf_info[eop_idx].skb = NULL;
+
+ VMXNET3_INC_RING_IDX_ONLY(eop_idx, tq->tx_ring.size);
+
+ while (tq->tx_ring.next2comp != eop_idx) {
+ vmxnet3_unmap_tx_buf(tq->buf_info + tq->tx_ring.next2comp,
+ pdev);
+
+ /* update next2comp w/o tx_lock. Since we are marking more,
+ * instead of less, tx ring entries avail, the worst case is
+ * that the tx routine incorrectly re-queues a pkt due to
+ * insufficient tx ring entries.
+ */
+ vmxnet3_cmd_ring_adv_next2comp(&tq->tx_ring);
+ entries++;
+ }
+
+ dev_kfree_skb_any(skb);
+ return entries;
+}
+
+
+static int
+vmxnet3_tq_tx_complete(struct vmxnet3_tx_queue *tq,
+ struct vmxnet3_adapter *adapter)
+{
+ int completed = 0;
+ union Vmxnet3_GenericDesc *gdesc;
+
+ gdesc = tq->comp_ring.base + tq->comp_ring.next2proc;
+ while (gdesc->tcd.gen == tq->comp_ring.gen) {
+ completed += vmxnet3_unmap_pkt(gdesc->tcd.txdIdx, tq,
+ adapter->pdev, adapter);
+
+ vmxnet3_comp_ring_adv_next2proc(&tq->comp_ring);
+ gdesc = tq->comp_ring.base + tq->comp_ring.next2proc;
+ }
+
+ if (completed) {
+ spin_lock(&tq->tx_lock);
+ if (unlikely(vmxnet3_tq_stopped(tq, adapter) &&
+ vmxnet3_cmd_ring_desc_avail(&tq->tx_ring) >
+ VMXNET3_WAKE_QUEUE_THRESHOLD(tq) &&
+ netif_carrier_ok(adapter->netdev))) {
+ vmxnet3_tq_wake(tq, adapter);
+ }
+ spin_unlock(&tq->tx_lock);
+ }
+ return completed;
+}
+
+
+static void
+vmxnet3_tq_cleanup(struct vmxnet3_tx_queue *tq,
+ struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ while (tq->tx_ring.next2comp != tq->tx_ring.next2fill) {
+ struct vmxnet3_tx_buf_info *tbi;
+ union Vmxnet3_GenericDesc *gdesc;
+
+ tbi = tq->buf_info + tq->tx_ring.next2comp;
+ gdesc = tq->tx_ring.base + tq->tx_ring.next2comp;
+
+ vmxnet3_unmap_tx_buf(tbi, adapter->pdev);
+ if (tbi->skb) {
+ dev_kfree_skb_any(tbi->skb);
+ tbi->skb = NULL;
+ }
+ vmxnet3_cmd_ring_adv_next2comp(&tq->tx_ring);
+ }
+
+ /* sanity check, verify all buffers are indeed unmapped and freed */
+ for (i = 0; i < tq->tx_ring.size; i++) {
+ BUG_ON(tq->buf_info[i].skb != NULL ||
+ tq->buf_info[i].map_type != VMXNET3_MAP_NONE);
+ }
+
+ tq->tx_ring.gen = VMXNET3_INIT_GEN;
+ tq->tx_ring.next2fill = tq->tx_ring.next2comp = 0;
+
+ tq->comp_ring.gen = VMXNET3_INIT_GEN;
+ tq->comp_ring.next2proc = 0;
+}
+
+
+void
+vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
+ struct vmxnet3_adapter *adapter)
+{
+ if (tq->tx_ring.base) {
+ pci_free_consistent(adapter->pdev, tq->tx_ring.size *
+ sizeof(struct Vmxnet3_TxDesc),
+ tq->tx_ring.base, tq->tx_ring.basePA);
+ tq->tx_ring.base = NULL;
+ }
+ if (tq->data_ring.base) {
+ pci_free_consistent(adapter->pdev, tq->data_ring.size *
+ sizeof(struct Vmxnet3_TxDataDesc),
+ tq->data_ring.base, tq->data_ring.basePA);
+ tq->data_ring.base = NULL;
+ }
+ if (tq->comp_ring.base) {
+ pci_free_consistent(adapter->pdev, tq->comp_ring.size *
+ sizeof(struct Vmxnet3_TxCompDesc),
+ tq->comp_ring.base, tq->comp_ring.basePA);
+ tq->comp_ring.base = NULL;
+ }
+ kfree(tq->buf_info);
+ tq->buf_info = NULL;
+}
+
+
+static void
+vmxnet3_tq_init(struct vmxnet3_tx_queue *tq,
+ struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ /* reset the tx ring contents to 0 and reset the tx ring states */
+ memset(tq->tx_ring.base, 0, tq->tx_ring.size *
+ sizeof(struct Vmxnet3_TxDesc));
+ tq->tx_ring.next2fill = tq->tx_ring.next2comp = 0;
+ tq->tx_ring.gen = VMXNET3_INIT_GEN;
+
+ memset(tq->data_ring.base, 0, tq->data_ring.size *
+ sizeof(struct Vmxnet3_TxDataDesc));
+
+ /* reset the tx comp ring contents to 0 and reset comp ring states */
+ memset(tq->comp_ring.base, 0, tq->comp_ring.size *
+ sizeof(struct Vmxnet3_TxCompDesc));
+ tq->comp_ring.next2proc = 0;
+ tq->comp_ring.gen = VMXNET3_INIT_GEN;
+
+ /* reset the bookkeeping data */
+ memset(tq->buf_info, 0, sizeof(tq->buf_info[0]) * tq->tx_ring.size);
+ for (i = 0; i < tq->tx_ring.size; i++)
+ tq->buf_info[i].map_type = VMXNET3_MAP_NONE;
+
+ /* stats are not reset */
+}
+
+
+static int
+vmxnet3_tq_create(struct vmxnet3_tx_queue *tq,
+ struct vmxnet3_adapter *adapter)
+{
+ BUG_ON(tq->tx_ring.base || tq->data_ring.base ||
+ tq->comp_ring.base || tq->buf_info);
+
+ tq->tx_ring.base = pci_alloc_consistent(adapter->pdev, tq->tx_ring.size
+ * sizeof(struct Vmxnet3_TxDesc),
+ &tq->tx_ring.basePA);
+ if (!tq->tx_ring.base) {
+ printk(KERN_ERR "%s: failed to allocate tx ring\n",
+ adapter->netdev->name);
+ goto err;
+ }
+
+ tq->data_ring.base = pci_alloc_consistent(adapter->pdev,
+ tq->data_ring.size *
+ sizeof(struct Vmxnet3_TxDataDesc),
+ &tq->data_ring.basePA);
+ if (!tq->data_ring.base) {
+ printk(KERN_ERR "%s: failed to allocate data ring\n",
+ adapter->netdev->name);
+ goto err;
+ }
+
+ tq->comp_ring.base = pci_alloc_consistent(adapter->pdev,
+ tq->comp_ring.size *
+ sizeof(struct Vmxnet3_TxCompDesc),
+ &tq->comp_ring.basePA);
+ if (!tq->comp_ring.base) {
+ printk(KERN_ERR "%s: failed to allocate tx comp ring\n",
+ adapter->netdev->name);
+ goto err;
+ }
+
+ tq->buf_info = kcalloc(tq->tx_ring.size, sizeof(tq->buf_info[0]),
+ GFP_KERNEL);
+ if (!tq->buf_info) {
+ printk(KERN_ERR "%s: failed to allocate tx bufinfo\n",
+ adapter->netdev->name);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ vmxnet3_tq_destroy(tq, adapter);
+ return -ENOMEM;
+}
+
+
+/*
+ * starting from ring->next2fill, allocate rx buffers for the given ring
+ * of the rx queue and update the rx desc. stop after @num_to_alloc buffers
+ * are allocated or allocation fails
+ */
+
+static int
+vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
+ int num_to_alloc, struct vmxnet3_adapter *adapter)
+{
+ int num_allocated = 0;
+ struct vmxnet3_rx_buf_info *rbi_base = rq->buf_info[ring_idx];
+ struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx];
+ u32 val;
+
+ while (num_allocated < num_to_alloc) {
+ struct vmxnet3_rx_buf_info *rbi;
+ union Vmxnet3_GenericDesc *gd;
+
+ rbi = rbi_base + ring->next2fill;
+ gd = ring->base + ring->next2fill;
+
+ if (rbi->buf_type == VMXNET3_RX_BUF_SKB) {
+ if (rbi->skb == NULL) {
+ rbi->skb = dev_alloc_skb(rbi->len +
+ NET_IP_ALIGN);
+ if (unlikely(rbi->skb == NULL)) {
+ rq->stats.rx_buf_alloc_failure++;
+ break;
+ }
+ rbi->skb->dev = adapter->netdev;
+
+ skb_reserve(rbi->skb, NET_IP_ALIGN);
+ rbi->dma_addr = pci_map_single(adapter->pdev,
+ rbi->skb->data, rbi->len,
+ PCI_DMA_FROMDEVICE);
+ } else {
+ /* rx buffer skipped by the device */
+ }
+ val = VMXNET3_RXD_BTYPE_HEAD << VMXNET3_RXD_BTYPE_SHIFT;
+ } else {
+ BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_PAGE ||
+ rbi->len != PAGE_SIZE);
+
+ if (rbi->page == NULL) {
+ rbi->page = alloc_page(GFP_ATOMIC);
+ if (unlikely(rbi->page == NULL)) {
+ rq->stats.rx_buf_alloc_failure++;
+ break;
+ }
+ rbi->dma_addr = pci_map_page(adapter->pdev,
+ rbi->page, 0, PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
+ } else {
+ /* rx buffers skipped by the device */
+ }
+ val = VMXNET3_RXD_BTYPE_BODY << VMXNET3_RXD_BTYPE_SHIFT;
+ }
+
+ BUG_ON(rbi->dma_addr == 0);
+ gd->rxd.addr = rbi->dma_addr;
+ gd->dword[2] = (ring->gen << VMXNET3_RXD_GEN_SHIFT) | val |
+ rbi->len;
+
+ num_allocated++;
+ vmxnet3_cmd_ring_adv_next2fill(ring);
+ }
+ rq->uncommitted[ring_idx] += num_allocated;
+
+ dev_dbg(&adapter->netdev->dev,
+ "alloc_rx_buf: %d allocated, next2fill %u, next2comp "
+ "%u, uncommited %u\n", num_allocated, ring->next2fill,
+ ring->next2comp, rq->uncommitted[ring_idx]);
+
+ /* so that the device can distinguish a full ring and an empty ring */
+ BUG_ON(num_allocated != 0 && ring->next2fill == ring->next2comp);
+
+ return num_allocated;
+}
+
+
+static void
+vmxnet3_append_frag(struct sk_buff *skb, struct Vmxnet3_RxCompDesc *rcd,
+ struct vmxnet3_rx_buf_info *rbi)
+{
+ struct skb_frag_struct *frag = skb_shinfo(skb)->frags +
+ skb_shinfo(skb)->nr_frags;
+
+ BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS);
+
+ frag->page = rbi->page;
+ frag->page_offset = 0;
+ frag->size = rcd->len;
+ skb->data_len += frag->size;
+ skb_shinfo(skb)->nr_frags++;
+}
+
+
+static void
+vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
+ struct vmxnet3_tx_queue *tq, struct pci_dev *pdev,
+ struct vmxnet3_adapter *adapter)
+{
+ u32 dw2, len;
+ unsigned long buf_offset;
+ int i;
+ union Vmxnet3_GenericDesc *gdesc;
+ struct vmxnet3_tx_buf_info *tbi = NULL;
+
+ BUG_ON(ctx->copy_size > skb_headlen(skb));
+
+ /* use the previous gen bit for the SOP desc */
+ dw2 = (tq->tx_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
+
+ ctx->sop_txd = tq->tx_ring.base + tq->tx_ring.next2fill;
+ gdesc = ctx->sop_txd; /* both loops below can be skipped */
+
+ /* no need to map the buffer if headers are copied */
+ if (ctx->copy_size) {
+ ctx->sop_txd->txd.addr = tq->data_ring.basePA +
+ tq->tx_ring.next2fill *
+ sizeof(struct Vmxnet3_TxDataDesc);
+ ctx->sop_txd->dword[2] = dw2 | ctx->copy_size;
+ ctx->sop_txd->dword[3] = 0;
+
+ tbi = tq->buf_info + tq->tx_ring.next2fill;
+ tbi->map_type = VMXNET3_MAP_NONE;
+
+ dev_dbg(&adapter->netdev->dev,
+ "txd[%u]: 0x%Lx 0x%x 0x%x\n",
+ tq->tx_ring.next2fill, ctx->sop_txd->txd.addr,
+ ctx->sop_txd->dword[2], ctx->sop_txd->dword[3]);
+ vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
+
+ /* use the right gen for non-SOP desc */
+ dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+ }
+
+ /* linear part can use multiple tx desc if it's big */
+ len = skb_headlen(skb) - ctx->copy_size;
+ buf_offset = ctx->copy_size;
+ while (len) {
+ u32 buf_size;
+
+ buf_size = len > VMXNET3_MAX_TX_BUF_SIZE ?
+ VMXNET3_MAX_TX_BUF_SIZE : len;
+
+ tbi = tq->buf_info + tq->tx_ring.next2fill;
+ tbi->map_type = VMXNET3_MAP_SINGLE;
+ tbi->dma_addr = pci_map_single(adapter->pdev,
+ skb->data + buf_offset, buf_size,
+ PCI_DMA_TODEVICE);
+
+ tbi->len = buf_size; /* this automatically convert 2^14 to 0 */
+
+ gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
+ BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
+
+ gdesc->txd.addr = tbi->dma_addr;
+ gdesc->dword[2] = dw2 | buf_size;
+ gdesc->dword[3] = 0;
+
+ dev_dbg(&adapter->netdev->dev,
+ "txd[%u]: 0x%Lx 0x%x 0x%x\n",
+ tq->tx_ring.next2fill, gdesc->txd.addr,
+ gdesc->dword[2], gdesc->dword[3]);
+ vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
+ dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+
+ len -= buf_size;
+ buf_offset += buf_size;
+ }
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+
+ tbi = tq->buf_info + tq->tx_ring.next2fill;
+ tbi->map_type = VMXNET3_MAP_PAGE;
+ tbi->dma_addr = pci_map_page(adapter->pdev, frag->page,
+ frag->page_offset, frag->size,
+ PCI_DMA_TODEVICE);
+
+ tbi->len = frag->size;
+
+ gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
+ BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
+
+ gdesc->txd.addr = tbi->dma_addr;
+ gdesc->dword[2] = dw2 | frag->size;
+ gdesc->dword[3] = 0;
+
+ dev_dbg(&adapter->netdev->dev,
+ "txd[%u]: 0x%llu %u %u\n",
+ tq->tx_ring.next2fill, gdesc->txd.addr,
+ gdesc->dword[2], gdesc->dword[3]);
+ vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
+ dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+ }
+
+ ctx->eop_txd = gdesc;
+
+ /* set the last buf_info for the pkt */
+ tbi->skb = skb;
+ tbi->sop_idx = ctx->sop_txd - tq->tx_ring.base;
+}
+
+
+/*
+ * parse and copy relevant protocol headers:
+ * For a tso pkt, relevant headers are L2/3/4 including options
+ * For a pkt requesting csum offloading, they are L2/3 and may include L4
+ * if it's a TCP/UDP pkt
+ *
+ * Returns:
+ * -1: error happens during parsing
+ * 0: protocol headers parsed, but too big to be copied
+ * 1: protocol headers parsed and copied
+ *
+ * Other effects:
+ * 1. related *ctx fields are updated.
+ * 2. ctx->copy_size is # of bytes copied
+ * 3. the portion copied is guaranteed to be in the linear part
+ *
+ */
+static int
+vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
+ struct vmxnet3_tx_ctx *ctx,
+ struct vmxnet3_adapter *adapter)
+{
+ struct Vmxnet3_TxDataDesc *tdd;
+
+ if (ctx->mss) {
+ ctx->eth_ip_hdr_size = skb_transport_offset(skb);
+ ctx->l4_hdr_size = ((struct tcphdr *)
+ skb_transport_header(skb))->doff * 4;
+ ctx->copy_size = ctx->eth_ip_hdr_size + ctx->l4_hdr_size;
+ } else {
+ unsigned int pull_size;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ ctx->eth_ip_hdr_size = skb_transport_offset(skb);
+
+ if (ctx->ipv4) {
+ struct iphdr *iph = (struct iphdr *)
+ skb_network_header(skb);
+ if (iph->protocol == IPPROTO_TCP) {
+ pull_size = ctx->eth_ip_hdr_size +
+ sizeof(struct tcphdr);
+
+ if (unlikely(!pskb_may_pull(skb,
+ pull_size))) {
+ goto err;
+ }
+ ctx->l4_hdr_size = ((struct tcphdr *)
+ skb_transport_header(skb))->doff * 4;
+ } else if (iph->protocol == IPPROTO_UDP) {
+ ctx->l4_hdr_size =
+ sizeof(struct udphdr);
+ } else {
+ ctx->l4_hdr_size = 0;
+ }
+ } else {
+ /* for simplicity, don't copy L4 headers */
+ ctx->l4_hdr_size = 0;
+ }
+ ctx->copy_size = ctx->eth_ip_hdr_size +
+ ctx->l4_hdr_size;
+ } else {
+ ctx->eth_ip_hdr_size = 0;
+ ctx->l4_hdr_size = 0;
+ /* copy as much as allowed */
+ ctx->copy_size = min((unsigned int)VMXNET3_HDR_COPY_SIZE
+ , skb_headlen(skb));
+ }
+
+ /* make sure headers are accessible directly */
+ if (unlikely(!pskb_may_pull(skb, ctx->copy_size)))
+ goto err;
+ }
+
+ if (unlikely(ctx->copy_size > VMXNET3_HDR_COPY_SIZE)) {
+ tq->stats.oversized_hdr++;
+ ctx->copy_size = 0;
+ return 0;
+ }
+
+ tdd = tq->data_ring.base + tq->tx_ring.next2fill;
+
+ memcpy(tdd->data, skb->data, ctx->copy_size);
+ dev_dbg(&adapter->netdev->dev,
+ "copy %u bytes to dataRing[%u]\n",
+ ctx->copy_size, tq->tx_ring.next2fill);
+ return 1;
+
+err:
+ return -1;
+}
+
+
+static void
+vmxnet3_prepare_tso(struct sk_buff *skb,
+ struct vmxnet3_tx_ctx *ctx)
+{
+ struct tcphdr *tcph = (struct tcphdr *)skb_transport_header(skb);
+ if (ctx->ipv4) {
+ struct iphdr *iph = (struct iphdr *)skb_network_header(skb);
+ iph->check = 0;
+ tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0,
+ IPPROTO_TCP, 0);
+ } else {
+ struct ipv6hdr *iph = (struct ipv6hdr *)skb_network_header(skb);
+ tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0,
+ IPPROTO_TCP, 0);
+ }
+}
+
+
+/*
+ * Transmits a pkt thru a given tq
+ * Returns:
+ * NETDEV_TX_OK: descriptors are setup successfully
+ * NETDEV_TX_OK: error occured, the pkt is dropped
+ * NETDEV_TX_BUSY: tx ring is full, queue is stopped
+ *
+ * Side-effects:
+ * 1. tx ring may be changed
+ * 2. tq stats may be updated accordingly
+ * 3. shared->txNumDeferred may be updated
+ */
+
+static int
+vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
+ struct vmxnet3_adapter *adapter, struct net_device *netdev)
+{
+ int ret;
+ u32 count;
+ unsigned long flags;
+ struct vmxnet3_tx_ctx ctx;
+ union Vmxnet3_GenericDesc *gdesc;
+
+ /* conservatively estimate # of descriptors to use */
+ count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) +
+ skb_shinfo(skb)->nr_frags + 1;
+
+ ctx.ipv4 = (skb->protocol == __constant_ntohs(ETH_P_IP));
+
+ ctx.mss = skb_shinfo(skb)->gso_size;
+ if (ctx.mss) {
+ if (skb_header_cloned(skb)) {
+ if (unlikely(pskb_expand_head(skb, 0, 0,
+ GFP_ATOMIC) != 0)) {
+ tq->stats.drop_tso++;
+ goto drop_pkt;
+ }
+ tq->stats.copy_skb_header++;
+ }
+ vmxnet3_prepare_tso(skb, &ctx);
+ } else {
+ if (unlikely(count > VMXNET3_MAX_TXD_PER_PKT)) {
+
+ /* non-tso pkts must not use more than
+ * VMXNET3_MAX_TXD_PER_PKT entries
+ */
+ if (skb_linearize(skb) != 0) {
+ tq->stats.drop_too_many_frags++;
+ goto drop_pkt;
+ }
+ tq->stats.linearized++;
+
+ /* recalculate the # of descriptors to use */
+ count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1;
+ }
+ }
+
+ ret = vmxnet3_parse_and_copy_hdr(skb, tq, &ctx, adapter);
+ if (ret >= 0) {
+ BUG_ON(ret <= 0 && ctx.copy_size != 0);
+ /* hdrs parsed, check against other limits */
+ if (ctx.mss) {
+ if (unlikely(ctx.eth_ip_hdr_size + ctx.l4_hdr_size >
+ VMXNET3_MAX_TX_BUF_SIZE)) {
+ goto hdr_too_big;
+ }
+ } else {
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ if (unlikely(ctx.eth_ip_hdr_size +
+ skb->csum_offset >
+ VMXNET3_MAX_CSUM_OFFSET)) {
+ goto hdr_too_big;
+ }
+ }
+ }
+ } else {
+ tq->stats.drop_hdr_inspect_err++;
+ goto drop_pkt;
+ }
+
+ spin_lock_irqsave(&tq->tx_lock, flags);
+
+ if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) {
+ tq->stats.tx_ring_full++;
+ dev_dbg(&adapter->netdev->dev,
+ "tx queue stopped on %s, next2comp %u"
+ " next2fill %u\n", adapter->netdev->name,
+ tq->tx_ring.next2comp, tq->tx_ring.next2fill);
+
+ vmxnet3_tq_stop(tq, adapter);
+ spin_unlock_irqrestore(&tq->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+
+ /* fill tx descs related to addr & len */
+ vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter);
+
+ /* setup the EOP desc */
+ ctx.eop_txd->dword[3] = VMXNET3_TXD_CQ | VMXNET3_TXD_EOP;
+
+ /* setup the SOP desc */
+ gdesc = ctx.sop_txd;
+ if (ctx.mss) {
+ gdesc->txd.hlen = ctx.eth_ip_hdr_size + ctx.l4_hdr_size;
+ gdesc->txd.om = VMXNET3_OM_TSO;
+ gdesc->txd.msscof = ctx.mss;
+ tq->shared->txNumDeferred += (skb->len - gdesc->txd.hlen +
+ ctx.mss - 1) / ctx.mss;
+ } else {
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ gdesc->txd.hlen = ctx.eth_ip_hdr_size;
+ gdesc->txd.om = VMXNET3_OM_CSUM;
+ gdesc->txd.msscof = ctx.eth_ip_hdr_size +
+ skb->csum_offset;
+ } else {
+ gdesc->txd.om = 0;
+ gdesc->txd.msscof = 0;
+ }
+ tq->shared->txNumDeferred++;
+ }
+
+ if (vlan_tx_tag_present(skb)) {
+ gdesc->txd.ti = 1;
+ gdesc->txd.tci = vlan_tx_tag_get(skb);
+ }
+
+ wmb();
+
+ /* finally flips the GEN bit of the SOP desc */
+ gdesc->dword[2] ^= VMXNET3_TXD_GEN;
+ dev_dbg(&adapter->netdev->dev,
+ "txd[%u]: SOP 0x%Lx 0x%x 0x%x\n",
+ (u32)((union Vmxnet3_GenericDesc *)ctx.sop_txd -
+ tq->tx_ring.base), gdesc->txd.addr, gdesc->dword[2],
+ gdesc->dword[3]);
+
+ spin_unlock_irqrestore(&tq->tx_lock, flags);
+
+ if (tq->shared->txNumDeferred >= tq->shared->txThreshold) {
+ tq->shared->txNumDeferred = 0;
+ VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_TXPROD,
+ tq->tx_ring.next2fill);
+ }
+ netdev->trans_start = jiffies;
+
+ return NETDEV_TX_OK;
+
+hdr_too_big:
+ tq->stats.drop_oversized_hdr++;
+drop_pkt:
+ tq->stats.drop_total++;
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
+
+static netdev_tx_t
+vmxnet3_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ struct vmxnet3_tx_queue *tq = &adapter->tx_queue;
+
+ return vmxnet3_tq_xmit(skb, tq, adapter, netdev);
+}
+
+
+static void
+vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
+ struct sk_buff *skb,
+ union Vmxnet3_GenericDesc *gdesc)
+{
+ if (!gdesc->rcd.cnc && adapter->rxcsum) {
+ /* typical case: TCP/UDP over IP and both csums are correct */
+ if ((gdesc->dword[3] & VMXNET3_RCD_CSUM_OK) ==
+ VMXNET3_RCD_CSUM_OK) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp));
+ BUG_ON(!(gdesc->rcd.v4 || gdesc->rcd.v6));
+ BUG_ON(gdesc->rcd.frg);
+ } else {
+ if (gdesc->rcd.csum) {
+ skb->csum = htons(gdesc->rcd.csum);
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ }
+ }
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ }
+}
+
+
+static void
+vmxnet3_rx_error(struct vmxnet3_rx_queue *rq, struct Vmxnet3_RxCompDesc *rcd,
+ struct vmxnet3_rx_ctx *ctx, struct vmxnet3_adapter *adapter)
+{
+ rq->stats.drop_err++;
+ if (!rcd->fcs)
+ rq->stats.drop_fcs++;
+
+ rq->stats.drop_total++;
+
+ /*
+ * We do not unmap and chain the rx buffer to the skb.
+ * We basically pretend this buffer is not used and will be recycled
+ * by vmxnet3_rq_alloc_rx_buf()
+ */
+
+ /*
+ * ctx->skb may be NULL if this is the first and the only one
+ * desc for the pkt
+ */
+ if (ctx->skb)
+ dev_kfree_skb_irq(ctx->skb);
+
+ ctx->skb = NULL;
+}
+
+
+static int
+vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+ struct vmxnet3_adapter *adapter, int quota)
+{
+ static u32 rxprod_reg[2] = {VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2};
+ u32 num_rxd = 0;
+ struct Vmxnet3_RxCompDesc *rcd;
+ struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
+
+ rcd = &rq->comp_ring.base[rq->comp_ring.next2proc].rcd;
+ while (rcd->gen == rq->comp_ring.gen) {
+ struct vmxnet3_rx_buf_info *rbi;
+ struct sk_buff *skb;
+ int num_to_alloc;
+ struct Vmxnet3_RxDesc *rxd;
+ u32 idx, ring_idx;
+
+ if (num_rxd >= quota) {
+ /* we may stop even before we see the EOP desc of
+ * the current pkt
+ */
+ break;
+ }
+ num_rxd++;
+
+ idx = rcd->rxdIdx;
+ ring_idx = rcd->rqID == rq->qid ? 0 : 1;
+
+ rxd = &rq->rx_ring[ring_idx].base[idx].rxd;
+ rbi = rq->buf_info[ring_idx] + idx;
+
+ BUG_ON(rxd->addr != rbi->dma_addr || rxd->len != rbi->len);
+
+ if (unlikely(rcd->eop && rcd->err)) {
+ vmxnet3_rx_error(rq, rcd, ctx, adapter);
+ goto rcd_done;
+ }
+
+ if (rcd->sop) { /* first buf of the pkt */
+ BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_HEAD ||
+ rcd->rqID != rq->qid);
+
+ BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_SKB);
+ BUG_ON(ctx->skb != NULL || rbi->skb == NULL);
+
+ if (unlikely(rcd->len == 0)) {
+ /* Pretend the rx buffer is skipped. */
+ BUG_ON(!(rcd->sop && rcd->eop));
+ dev_dbg(&adapter->netdev->dev,
+ "rxRing[%u][%u] 0 length\n",
+ ring_idx, idx);
+ goto rcd_done;
+ }
+
+ ctx->skb = rbi->skb;
+ rbi->skb = NULL;
+
+ pci_unmap_single(adapter->pdev, rbi->dma_addr, rbi->len,
+ PCI_DMA_FROMDEVICE);
+
+ skb_put(ctx->skb, rcd->len);
+ } else {
+ BUG_ON(ctx->skb == NULL);
+ /* non SOP buffer must be type 1 in most cases */
+ if (rbi->buf_type == VMXNET3_RX_BUF_PAGE) {
+ BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY);
+
+ if (rcd->len) {
+ pci_unmap_page(adapter->pdev,
+ rbi->dma_addr, rbi->len,
+ PCI_DMA_FROMDEVICE);
+
+ vmxnet3_append_frag(ctx->skb, rcd, rbi);
+ rbi->page = NULL;
+ }
+ } else {
+ /*
+ * The only time a non-SOP buffer is type 0 is
+ * when it's EOP and error flag is raised, which
+ * has already been handled.
+ */
+ BUG_ON(true);
+ }
+ }
+
+ skb = ctx->skb;
+ if (rcd->eop) {
+ skb->len += skb->data_len;
+ skb->truesize += skb->data_len;
+
+ vmxnet3_rx_csum(adapter, skb,
+ (union Vmxnet3_GenericDesc *)rcd);
+ skb->protocol = eth_type_trans(skb, adapter->netdev);
+
+ if (unlikely(adapter->vlan_grp && rcd->ts)) {
+ vlan_hwaccel_receive_skb(skb,
+ adapter->vlan_grp, rcd->tci);
+ } else {
+ netif_receive_skb(skb);
+ }
+
+ adapter->netdev->last_rx = jiffies;
+ ctx->skb = NULL;
+ }
+
+rcd_done:
+ /* device may skip some rx descs */
+ rq->rx_ring[ring_idx].next2comp = idx;
+ VMXNET3_INC_RING_IDX_ONLY(rq->rx_ring[ring_idx].next2comp,
+ rq->rx_ring[ring_idx].size);
+
+ /* refill rx buffers frequently to avoid starving the h/w */
+ num_to_alloc = vmxnet3_cmd_ring_desc_avail(rq->rx_ring +
+ ring_idx);
+ if (unlikely(num_to_alloc > VMXNET3_RX_ALLOC_THRESHOLD(rq,
+ ring_idx, adapter))) {
+ vmxnet3_rq_alloc_rx_buf(rq, ring_idx, num_to_alloc,
+ adapter);
+
+ /* if needed, update the register */
+ if (unlikely(rq->shared->updateRxProd)) {
+ VMXNET3_WRITE_BAR0_REG(adapter,
+ rxprod_reg[ring_idx] + rq->qid * 8,
+ rq->rx_ring[ring_idx].next2fill);
+ rq->uncommitted[ring_idx] = 0;
+ }
+ }
+
+ vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring);
+ rcd = &rq->comp_ring.base[rq->comp_ring.next2proc].rcd;
+ }
+
+ return num_rxd;
+}
+
+
+static void
+vmxnet3_rq_cleanup(struct vmxnet3_rx_queue *rq,
+ struct vmxnet3_adapter *adapter)
+{
+ u32 i, ring_idx;
+ struct Vmxnet3_RxDesc *rxd;
+
+ for (ring_idx = 0; ring_idx < 2; ring_idx++) {
+ for (i = 0; i < rq->rx_ring[ring_idx].size; i++) {
+ rxd = &rq->rx_ring[ring_idx].base[i].rxd;
+
+ if (rxd->btype == VMXNET3_RXD_BTYPE_HEAD &&
+ rq->buf_info[ring_idx][i].skb) {
+ pci_unmap_single(adapter->pdev, rxd->addr,
+ rxd->len, PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(rq->buf_info[ring_idx][i].skb);
+ rq->buf_info[ring_idx][i].skb = NULL;
+ } else if (rxd->btype == VMXNET3_RXD_BTYPE_BODY &&
+ rq->buf_info[ring_idx][i].page) {
+ pci_unmap_page(adapter->pdev, rxd->addr,
+ rxd->len, PCI_DMA_FROMDEVICE);
+ put_page(rq->buf_info[ring_idx][i].page);
+ rq->buf_info[ring_idx][i].page = NULL;
+ }
+ }
+
+ rq->rx_ring[ring_idx].gen = VMXNET3_INIT_GEN;
+ rq->rx_ring[ring_idx].next2fill =
+ rq->rx_ring[ring_idx].next2comp = 0;
+ rq->uncommitted[ring_idx] = 0;
+ }
+
+ rq->comp_ring.gen = VMXNET3_INIT_GEN;
+ rq->comp_ring.next2proc = 0;
+}
+
+
+void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
+ struct vmxnet3_adapter *adapter)
+{
+ int i;
+ int j;
+
+ /* all rx buffers must have already been freed */
+ for (i = 0; i < 2; i++) {
+ if (rq->buf_info[i]) {
+ for (j = 0; j < rq->rx_ring[i].size; j++)
+ BUG_ON(rq->buf_info[i][j].page != NULL);
+ }
+ }
+
+
+ kfree(rq->buf_info[0]);
+
+ for (i = 0; i < 2; i++) {
+ if (rq->rx_ring[i].base) {
+ pci_free_consistent(adapter->pdev, rq->rx_ring[i].size
+ * sizeof(struct Vmxnet3_RxDesc),
+ rq->rx_ring[i].base,
+ rq->rx_ring[i].basePA);
+ rq->rx_ring[i].base = NULL;
+ }
+ rq->buf_info[i] = NULL;
+ }
+
+ if (rq->comp_ring.base) {
+ pci_free_consistent(adapter->pdev, rq->comp_ring.size *
+ sizeof(struct Vmxnet3_RxCompDesc),
+ rq->comp_ring.base, rq->comp_ring.basePA);
+ rq->comp_ring.base = NULL;
+ }
+}
+
+
+static int
+vmxnet3_rq_init(struct vmxnet3_rx_queue *rq,
+ struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ /* initialize buf_info */
+ for (i = 0; i < rq->rx_ring[0].size; i++) {
+
+ /* 1st buf for a pkt is skbuff */
+ if (i % adapter->rx_buf_per_pkt == 0) {
+ rq->buf_info[0][i].buf_type = VMXNET3_RX_BUF_SKB;
+ rq->buf_info[0][i].len = adapter->skb_buf_size;
+ } else { /* subsequent bufs for a pkt is frag */
+ rq->buf_info[0][i].buf_type = VMXNET3_RX_BUF_PAGE;
+ rq->buf_info[0][i].len = PAGE_SIZE;
+ }
+ }
+ for (i = 0; i < rq->rx_ring[1].size; i++) {
+ rq->buf_info[1][i].buf_type = VMXNET3_RX_BUF_PAGE;
+ rq->buf_info[1][i].len = PAGE_SIZE;
+ }
+
+ /* reset internal state and allocate buffers for both rings */
+ for (i = 0; i < 2; i++) {
+ rq->rx_ring[i].next2fill = rq->rx_ring[i].next2comp = 0;
+ rq->uncommitted[i] = 0;
+
+ memset(rq->rx_ring[i].base, 0, rq->rx_ring[i].size *
+ sizeof(struct Vmxnet3_RxDesc));
+ rq->rx_ring[i].gen = VMXNET3_INIT_GEN;
+ }
+ if (vmxnet3_rq_alloc_rx_buf(rq, 0, rq->rx_ring[0].size - 1,
+ adapter) == 0) {
+ /* at least has 1 rx buffer for the 1st ring */
+ return -ENOMEM;
+ }
+ vmxnet3_rq_alloc_rx_buf(rq, 1, rq->rx_ring[1].size - 1, adapter);
+
+ /* reset the comp ring */
+ rq->comp_ring.next2proc = 0;
+ memset(rq->comp_ring.base, 0, rq->comp_ring.size *
+ sizeof(struct Vmxnet3_RxCompDesc));
+ rq->comp_ring.gen = VMXNET3_INIT_GEN;
+
+ /* reset rxctx */
+ rq->rx_ctx.skb = NULL;
+
+ /* stats are not reset */
+ return 0;
+}
+
+
+static int
+vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter)
+{
+ int i;
+ size_t sz;
+ struct vmxnet3_rx_buf_info *bi;
+
+ for (i = 0; i < 2; i++) {
+
+ sz = rq->rx_ring[i].size * sizeof(struct Vmxnet3_RxDesc);
+ rq->rx_ring[i].base = pci_alloc_consistent(adapter->pdev, sz,
+ &rq->rx_ring[i].basePA);
+ if (!rq->rx_ring[i].base) {
+ printk(KERN_ERR "%s: failed to allocate rx ring %d\n",
+ adapter->netdev->name, i);
+ goto err;
+ }
+ }
+
+ sz = rq->comp_ring.size * sizeof(struct Vmxnet3_RxCompDesc);
+ rq->comp_ring.base = pci_alloc_consistent(adapter->pdev, sz,
+ &rq->comp_ring.basePA);
+ if (!rq->comp_ring.base) {
+ printk(KERN_ERR "%s: failed to allocate rx comp ring\n",
+ adapter->netdev->name);
+ goto err;
+ }
+
+ sz = sizeof(struct vmxnet3_rx_buf_info) * (rq->rx_ring[0].size +
+ rq->rx_ring[1].size);
+ bi = kmalloc(sz, GFP_KERNEL);
+ if (!bi) {
+ printk(KERN_ERR "%s: failed to allocate rx bufinfo\n",
+ adapter->netdev->name);
+ goto err;
+ }
+ memset(bi, 0, sz);
+ rq->buf_info[0] = bi;
+ rq->buf_info[1] = bi + rq->rx_ring[0].size;
+
+ return 0;
+
+err:
+ vmxnet3_rq_destroy(rq, adapter);
+ return -ENOMEM;
+}
+
+
+static int
+vmxnet3_do_poll(struct vmxnet3_adapter *adapter, int budget)
+{
+ if (unlikely(adapter->shared->ecr))
+ vmxnet3_process_events(adapter);
+
+ vmxnet3_tq_tx_complete(&adapter->tx_queue, adapter);
+ return vmxnet3_rq_rx_complete(&adapter->rx_queue, adapter, budget);
+}
+
+
+static int
+vmxnet3_poll(struct napi_struct *napi, int budget)
+{
+ struct vmxnet3_adapter *adapter = container_of(napi,
+ struct vmxnet3_adapter, napi);
+ int rxd_done;
+
+ rxd_done = vmxnet3_do_poll(adapter, budget);
+
+ if (rxd_done < budget) {
+ napi_complete(napi);
+ vmxnet3_enable_intr(adapter, 0);
+ }
+ return rxd_done;
+}
+
+
+/* Interrupt handler for vmxnet3 */
+static irqreturn_t
+vmxnet3_intr(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct vmxnet3_adapter *adapter = netdev_priv(dev);
+
+ if (unlikely(adapter->intr.type == VMXNET3_IT_INTX)) {
+ u32 icr = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ICR);
+ if (unlikely(icr == 0))
+ /* not ours */
+ return IRQ_NONE;
+ }
+
+
+ /* disable intr if needed */
+ if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE)
+ vmxnet3_disable_intr(adapter, 0);
+
+ napi_schedule(&adapter->napi);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+
+
+/* netpoll callback. */
+static void
+vmxnet3_netpoll(struct net_device *netdev)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ int irq;
+
+#ifdef CONFIG_PCI_MSI
+ if (adapter->intr.type == VMXNET3_IT_MSIX)
+ irq = adapter->intr.msix_entries[0].vector;
+ else
+#endif
+ irq = adapter->pdev->irq;
+
+ disable_irq(irq);
+ vmxnet3_intr(irq, netdev);
+ enable_irq(irq);
+}
+#endif
+
+static int
+vmxnet3_request_irqs(struct vmxnet3_adapter *adapter)
+{
+ int err;
+
+#ifdef CONFIG_PCI_MSI
+ if (adapter->intr.type == VMXNET3_IT_MSIX) {
+ /* we only use 1 MSI-X vector */
+ err = request_irq(adapter->intr.msix_entries[0].vector,
+ vmxnet3_intr, 0, adapter->netdev->name,
+ adapter->netdev);
+ } else
+#endif
+ if (adapter->intr.type == VMXNET3_IT_MSI) {
+ err = request_irq(adapter->pdev->irq, vmxnet3_intr, 0,
+ adapter->netdev->name, adapter->netdev);
+ } else {
+ err = request_irq(adapter->pdev->irq, vmxnet3_intr,
+ IRQF_SHARED, adapter->netdev->name,
+ adapter->netdev);
+ }
+
+ if (err)
+ printk(KERN_ERR "Failed to request irq %s (intr type:%d), error"
+ ":%d\n", adapter->netdev->name, adapter->intr.type, err);
+
+
+ if (!err) {
+ int i;
+ /* init our intr settings */
+ for (i = 0; i < adapter->intr.num_intrs; i++)
+ adapter->intr.mod_levels[i] = UPT1_IML_ADAPTIVE;
+
+ /* next setup intr index for all intr sources */
+ adapter->tx_queue.comp_ring.intr_idx = 0;
+ adapter->rx_queue.comp_ring.intr_idx = 0;
+ adapter->intr.event_intr_idx = 0;
+
+ printk(KERN_INFO "%s: intr type %u, mode %u, %u vectors "
+ "allocated\n", adapter->netdev->name, adapter->intr.type,
+ adapter->intr.mask_mode, adapter->intr.num_intrs);
+ }
+
+ return err;
+}
+
+
+static void
+vmxnet3_free_irqs(struct vmxnet3_adapter *adapter)
+{
+ BUG_ON(adapter->intr.type == VMXNET3_IT_AUTO ||
+ adapter->intr.num_intrs <= 0);
+
+ switch (adapter->intr.type) {
+#ifdef CONFIG_PCI_MSI
+ case VMXNET3_IT_MSIX:
+ {
+ int i;
+
+ for (i = 0; i < adapter->intr.num_intrs; i++)
+ free_irq(adapter->intr.msix_entries[i].vector,
+ adapter->netdev);
+ break;
+ }
+#endif
+ case VMXNET3_IT_MSI:
+ free_irq(adapter->pdev->irq, adapter->netdev);
+ break;
+ case VMXNET3_IT_INTX:
+ free_irq(adapter->pdev->irq, adapter->netdev);
+ break;
+ default:
+ BUG_ON(true);
+ }
+}
+
+
+static void
+vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ struct Vmxnet3_DriverShared *shared = adapter->shared;
+ u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+
+ if (grp) {
+ /* add vlan rx stripping. */
+ if (adapter->netdev->features & NETIF_F_HW_VLAN_RX) {
+ int i;
+ struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
+ adapter->vlan_grp = grp;
+
+ /* update FEATURES to device */
+ devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_FEATURE);
+ /*
+ * Clear entire vfTable; then enable untagged pkts.
+ * Note: setting one entry in vfTable to non-zero turns
+ * on VLAN rx filtering.
+ */
+ for (i = 0; i < VMXNET3_VFT_SIZE; i++)
+ vfTable[i] = 0;
+
+ VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0);
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+ } else {
+ printk(KERN_ERR "%s: vlan_rx_register when device has "
+ "no NETIF_F_HW_VLAN_RX\n", netdev->name);
+ }
+ } else {
+ /* remove vlan rx stripping. */
+ struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
+ adapter->vlan_grp = NULL;
+
+ if (devRead->misc.uptFeatures & UPT1_F_RXVLAN) {
+ int i;
+
+ for (i = 0; i < VMXNET3_VFT_SIZE; i++) {
+ /* clear entire vfTable; this also disables
+ * VLAN rx filtering
+ */
+ vfTable[i] = 0;
+ }
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+
+ /* update FEATURES to device */
+ devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN;
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_FEATURE);
+ }
+ }
+}
+
+
+static void
+vmxnet3_restore_vlan(struct vmxnet3_adapter *adapter)
+{
+ if (adapter->vlan_grp) {
+ u16 vid;
+ u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+ bool activeVlan = false;
+
+ for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ if (vlan_group_get_device(adapter->vlan_grp, vid)) {
+ VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
+ activeVlan = true;
+ }
+ }
+ if (activeVlan) {
+ /* continue to allow untagged pkts */
+ VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0);
+ }
+ }
+}
+
+
+static void
+vmxnet3_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+
+ VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+}
+
+
+static void
+vmxnet3_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+
+ VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid);
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+}
+
+
+static u8 *
+vmxnet3_copy_mc(struct net_device *netdev)
+{
+ u8 *buf = NULL;
+ u32 sz = netdev->mc_count * ETH_ALEN;
+
+ /* struct Vmxnet3_RxFilterConf.mfTableLen is u16. */
+ if (sz <= 0xffff) {
+ /* We may be called with BH disabled */
+ buf = kmalloc(sz, GFP_ATOMIC);
+ if (buf) {
+ int i;
+ struct dev_mc_list *mc = netdev->mc_list;
+
+ for (i = 0; i < netdev->mc_count; i++) {
+ BUG_ON(!mc);
+ memcpy(buf + i * ETH_ALEN, mc->dmi_addr,
+ ETH_ALEN);
+ mc = mc->next;
+ }
+ }
+ }
+ return buf;
+}
+
+
+static void
+vmxnet3_set_mc(struct net_device *netdev)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ struct Vmxnet3_RxFilterConf *rxConf =
+ &adapter->shared->devRead.rxFilterConf;
+ u8 *new_table = NULL;
+ u32 new_mode = VMXNET3_RXM_UCAST;
+
+ if (netdev->flags & IFF_PROMISC)
+ new_mode |= VMXNET3_RXM_PROMISC;
+
+ if (netdev->flags & IFF_BROADCAST)
+ new_mode |= VMXNET3_RXM_BCAST;
+
+ if (netdev->flags & IFF_ALLMULTI)
+ new_mode |= VMXNET3_RXM_ALL_MULTI;
+ else
+ if (netdev->mc_count > 0) {
+ new_table = vmxnet3_copy_mc(netdev);
+ if (new_table) {
+ new_mode |= VMXNET3_RXM_MCAST;
+ rxConf->mfTableLen = netdev->mc_count *
+ ETH_ALEN;
+ rxConf->mfTablePA = virt_to_phys(new_table);
+ } else {
+ printk(KERN_INFO "%s: failed to copy mcast list"
+ ", setting ALL_MULTI\n", netdev->name);
+ new_mode |= VMXNET3_RXM_ALL_MULTI;
+ }
+ }
+
+
+ if (!(new_mode & VMXNET3_RXM_MCAST)) {
+ rxConf->mfTableLen = 0;
+ rxConf->mfTablePA = 0;
+ }
+
+ if (new_mode != rxConf->rxMode) {
+ rxConf->rxMode = new_mode;
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_RX_MODE);
+ }
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_MAC_FILTERS);
+
+ kfree(new_table);
+}
+
+
+/*
+ * Set up driver_shared based on settings in adapter.
+ */
+
+static void
+vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
+{
+ struct Vmxnet3_DriverShared *shared = adapter->shared;
+ struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
+ struct Vmxnet3_TxQueueConf *tqc;
+ struct Vmxnet3_RxQueueConf *rqc;
+ int i;
+
+ memset(shared, 0, sizeof(*shared));
+
+ /* driver settings */
+ shared->magic = VMXNET3_REV1_MAGIC;
+ devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM;
+ devRead->misc.driverInfo.gos.gosBits = (sizeof(void *) == 4 ?
+ VMXNET3_GOS_BITS_32 : VMXNET3_GOS_BITS_64);
+ devRead->misc.driverInfo.gos.gosType = VMXNET3_GOS_TYPE_LINUX;
+ devRead->misc.driverInfo.vmxnet3RevSpt = 1;
+ devRead->misc.driverInfo.uptVerSpt = 1;
+
+ devRead->misc.ddPA = virt_to_phys(adapter);
+ devRead->misc.ddLen = sizeof(struct vmxnet3_adapter);
+
+ /* set up feature flags */
+ if (adapter->rxcsum)
+ devRead->misc.uptFeatures |= UPT1_F_RXCSUM;
+
+ if (adapter->lro) {
+ devRead->misc.uptFeatures |= UPT1_F_LRO;
+ devRead->misc.maxNumRxSG = 1 + MAX_SKB_FRAGS;
+ }
+ if ((adapter->netdev->features & NETIF_F_HW_VLAN_RX)
+ && adapter->vlan_grp) {
+ devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
+ }
+
+ devRead->misc.mtu = adapter->netdev->mtu;
+ devRead->misc.queueDescPA = adapter->queue_desc_pa;
+ devRead->misc.queueDescLen = sizeof(struct Vmxnet3_TxQueueDesc) +
+ sizeof(struct Vmxnet3_RxQueueDesc);
+
+ /* tx queue settings */
+ BUG_ON(adapter->tx_queue.tx_ring.base == NULL);
+
+ devRead->misc.numTxQueues = 1;
+ tqc = &adapter->tqd_start->conf;
+ tqc->txRingBasePA = adapter->tx_queue.tx_ring.basePA;
+ tqc->dataRingBasePA = adapter->tx_queue.data_ring.basePA;
+ tqc->compRingBasePA = adapter->tx_queue.comp_ring.basePA;
+ tqc->ddPA = virt_to_phys(adapter->tx_queue.buf_info);
+ tqc->txRingSize = adapter->tx_queue.tx_ring.size;
+ tqc->dataRingSize = adapter->tx_queue.data_ring.size;
+ tqc->compRingSize = adapter->tx_queue.comp_ring.size;
+ tqc->ddLen = sizeof(struct vmxnet3_tx_buf_info) *
+ tqc->txRingSize;
+ tqc->intrIdx = adapter->tx_queue.comp_ring.intr_idx;
+
+ /* rx queue settings */
+ devRead->misc.numRxQueues = 1;
+ rqc = &adapter->rqd_start->conf;
+ rqc->rxRingBasePA[0] = adapter->rx_queue.rx_ring[0].basePA;
+ rqc->rxRingBasePA[1] = adapter->rx_queue.rx_ring[1].basePA;
+ rqc->compRingBasePA = adapter->rx_queue.comp_ring.basePA;
+ rqc->ddPA = virt_to_phys(adapter->rx_queue.buf_info);
+ rqc->rxRingSize[0] = adapter->rx_queue.rx_ring[0].size;
+ rqc->rxRingSize[1] = adapter->rx_queue.rx_ring[1].size;
+ rqc->compRingSize = adapter->rx_queue.comp_ring.size;
+ rqc->ddLen = sizeof(struct vmxnet3_rx_buf_info) *
+ (rqc->rxRingSize[0] + rqc->rxRingSize[1]);
+ rqc->intrIdx = adapter->rx_queue.comp_ring.intr_idx;
+
+ /* intr settings */
+ devRead->intrConf.autoMask = adapter->intr.mask_mode ==
+ VMXNET3_IMM_AUTO;
+ devRead->intrConf.numIntrs = adapter->intr.num_intrs;
+ for (i = 0; i < adapter->intr.num_intrs; i++)
+ devRead->intrConf.modLevels[i] = adapter->intr.mod_levels[i];
+
+ devRead->intrConf.eventIntrIdx = adapter->intr.event_intr_idx;
+
+ /* rx filter settings */
+ devRead->rxFilterConf.rxMode = 0;
+ vmxnet3_restore_vlan(adapter);
+ /* the rest are already zeroed */
+}
+
+
+int
+vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
+{
+ int err;
+ u32 ret;
+
+ dev_dbg(&adapter->netdev->dev,
+ "%s: skb_buf_size %d, rx_buf_per_pkt %d, ring sizes"
+ " %u %u %u\n", adapter->netdev->name, adapter->skb_buf_size,
+ adapter->rx_buf_per_pkt, adapter->tx_queue.tx_ring.size,
+ adapter->rx_queue.rx_ring[0].size,
+ adapter->rx_queue.rx_ring[1].size);
+
+ vmxnet3_tq_init(&adapter->tx_queue, adapter);
+ err = vmxnet3_rq_init(&adapter->rx_queue, adapter);
+ if (err) {
+ printk(KERN_ERR "Failed to init rx queue for %s: error %d\n",
+ adapter->netdev->name, err);
+ goto rq_err;
+ }
+
+ err = vmxnet3_request_irqs(adapter);
+ if (err) {
+ printk(KERN_ERR "Failed to setup irq for %s: error %d\n",
+ adapter->netdev->name, err);
+ goto irq_err;
+ }
+
+ vmxnet3_setup_driver_shared(adapter);
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAL,
+ VMXNET3_GET_ADDR_LO(adapter->shared_pa));
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAH,
+ VMXNET3_GET_ADDR_HI(adapter->shared_pa));
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_ACTIVATE_DEV);
+ ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to activate dev %s: error %u\n",
+ adapter->netdev->name, ret);
+ err = -EINVAL;
+ goto activate_err;
+ }
+ VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD,
+ adapter->rx_queue.rx_ring[0].next2fill);
+ VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD2,
+ adapter->rx_queue.rx_ring[1].next2fill);
+
+ /* Apply the rx filter settins last. */
+ vmxnet3_set_mc(adapter->netdev);
+
+ /*
+ * Check link state when first activating device. It will start the
+ * tx queue if the link is up.
+ */
+ vmxnet3_check_link(adapter);
+
+ napi_enable(&adapter->napi);
+ vmxnet3_enable_all_intrs(adapter);
+ clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
+ return 0;
+
+activate_err:
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAL, 0);
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAH, 0);
+ vmxnet3_free_irqs(adapter);
+irq_err:
+rq_err:
+ /* free up buffers we allocated */
+ vmxnet3_rq_cleanup(&adapter->rx_queue, adapter);
+ return err;
+}
+
+
+void
+vmxnet3_reset_dev(struct vmxnet3_adapter *adapter)
+{
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
+}
+
+
+int
+vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter)
+{
+ if (test_and_set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state))
+ return 0;
+
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_QUIESCE_DEV);
+ vmxnet3_disable_all_intrs(adapter);
+
+ napi_disable(&adapter->napi);
+ netif_tx_disable(adapter->netdev);
+ adapter->link_speed = 0;
+ netif_carrier_off(adapter->netdev);
+
+ vmxnet3_tq_cleanup(&adapter->tx_queue, adapter);
+ vmxnet3_rq_cleanup(&adapter->rx_queue, adapter);
+ vmxnet3_free_irqs(adapter);
+ return 0;
+}
+
+
+static void
+vmxnet3_write_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)
+{
+ u32 tmp;
+
+ tmp = *(u32 *)mac;
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_MACL, tmp);
+
+ tmp = (mac[5] << 8) | mac[4];
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_MACH, tmp);
+}
+
+
+static int
+vmxnet3_set_mac_addr(struct net_device *netdev, void *p)
+{
+ struct sockaddr *addr = p;
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ vmxnet3_write_mac_addr(adapter, addr->sa_data);
+
+ return 0;
+}
+
+
+/* ==================== initialization and cleanup routines ============ */
+
+static int
+vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64)
+{
+ int err;
+ unsigned long mmio_start, mmio_len;
+ struct pci_dev *pdev = adapter->pdev;
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR "Failed to enable adapter %s: error %d\n",
+ pci_name(pdev), err);
+ return err;
+ }
+
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
+ printk(KERN_ERR "pci_set_consistent_dma_mask failed "
+ "for adapter %s\n", pci_name(pdev));
+ err = -EIO;
+ goto err_set_mask;
+ }
+ *dma64 = true;
+ } else {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
+ printk(KERN_ERR "pci_set_dma_mask failed for adapter "
+ "%s\n", pci_name(pdev));
+ err = -EIO;
+ goto err_set_mask;
+ }
+ *dma64 = false;
+ }
+
+ err = pci_request_selected_regions(pdev, (1 << 2) - 1,
+ vmxnet3_driver_name);
+ if (err) {
+ printk(KERN_ERR "Failed to request region for adapter %s: "
+ "error %d\n", pci_name(pdev), err);
+ goto err_set_mask;
+ }
+
+ pci_set_master(pdev);
+
+ mmio_start = pci_resource_start(pdev, 0);
+ mmio_len = pci_resource_len(pdev, 0);
+ adapter->hw_addr0 = ioremap(mmio_start, mmio_len);
+ if (!adapter->hw_addr0) {
+ printk(KERN_ERR "Failed to map bar0 for adapter %s\n",
+ pci_name(pdev));
+ err = -EIO;
+ goto err_ioremap;
+ }
+
+ mmio_start = pci_resource_start(pdev, 1);
+ mmio_len = pci_resource_len(pdev, 1);
+ adapter->hw_addr1 = ioremap(mmio_start, mmio_len);
+ if (!adapter->hw_addr1) {
+ printk(KERN_ERR "Failed to map bar1 for adapter %s\n",
+ pci_name(pdev));
+ err = -EIO;
+ goto err_bar1;
+ }
+ return 0;
+
+err_bar1:
+ iounmap(adapter->hw_addr0);
+err_ioremap:
+ pci_release_selected_regions(pdev, (1 << 2) - 1);
+err_set_mask:
+ pci_disable_device(pdev);
+ return err;
+}
+
+
+static void
+vmxnet3_free_pci_resources(struct vmxnet3_adapter *adapter)
+{
+ BUG_ON(!adapter->pdev);
+
+ iounmap(adapter->hw_addr0);
+ iounmap(adapter->hw_addr1);
+ pci_release_selected_regions(adapter->pdev, (1 << 2) - 1);
+ pci_disable_device(adapter->pdev);
+}
+
+
+static void
+vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
+{
+ size_t sz;
+
+ if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE -
+ VMXNET3_MAX_ETH_HDR_SIZE) {
+ adapter->skb_buf_size = adapter->netdev->mtu +
+ VMXNET3_MAX_ETH_HDR_SIZE;
+ if (adapter->skb_buf_size < VMXNET3_MIN_T0_BUF_SIZE)
+ adapter->skb_buf_size = VMXNET3_MIN_T0_BUF_SIZE;
+
+ adapter->rx_buf_per_pkt = 1;
+ } else {
+ adapter->skb_buf_size = VMXNET3_MAX_SKB_BUF_SIZE;
+ sz = adapter->netdev->mtu - VMXNET3_MAX_SKB_BUF_SIZE +
+ VMXNET3_MAX_ETH_HDR_SIZE;
+ adapter->rx_buf_per_pkt = 1 + (sz + PAGE_SIZE - 1) / PAGE_SIZE;
+ }
+
+ /*
+ * for simplicity, force the ring0 size to be a multiple of
+ * rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN
+ */
+ sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN;
+ adapter->rx_queue.rx_ring[0].size = (adapter->rx_queue.rx_ring[0].size +
+ sz - 1) / sz * sz;
+ adapter->rx_queue.rx_ring[0].size = min_t(u32,
+ adapter->rx_queue.rx_ring[0].size,
+ VMXNET3_RX_RING_MAX_SIZE / sz * sz);
+}
+
+
+int
+vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size,
+ u32 rx_ring_size, u32 rx_ring2_size)
+{
+ int err;
+
+ adapter->tx_queue.tx_ring.size = tx_ring_size;
+ adapter->tx_queue.data_ring.size = tx_ring_size;
+ adapter->tx_queue.comp_ring.size = tx_ring_size;
+ adapter->tx_queue.shared = &adapter->tqd_start->ctrl;
+ adapter->tx_queue.stopped = true;
+ err = vmxnet3_tq_create(&adapter->tx_queue, adapter);
+ if (err)
+ return err;
+
+ adapter->rx_queue.rx_ring[0].size = rx_ring_size;
+ adapter->rx_queue.rx_ring[1].size = rx_ring2_size;
+ vmxnet3_adjust_rx_ring_size(adapter);
+ adapter->rx_queue.comp_ring.size = adapter->rx_queue.rx_ring[0].size +
+ adapter->rx_queue.rx_ring[1].size;
+ adapter->rx_queue.qid = 0;
+ adapter->rx_queue.qid2 = 1;
+ adapter->rx_queue.shared = &adapter->rqd_start->ctrl;
+ err = vmxnet3_rq_create(&adapter->rx_queue, adapter);
+ if (err)
+ vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+
+ return err;
+}
+
+static int
+vmxnet3_open(struct net_device *netdev)
+{
+ struct vmxnet3_adapter *adapter;
+ int err;
+
+ adapter = netdev_priv(netdev);
+
+ spin_lock_init(&adapter->tx_queue.tx_lock);
+
+ err = vmxnet3_create_queues(adapter, VMXNET3_DEF_TX_RING_SIZE,
+ VMXNET3_DEF_RX_RING_SIZE,
+ VMXNET3_DEF_RX_RING_SIZE);
+ if (err)
+ goto queue_err;
+
+ err = vmxnet3_activate_dev(adapter);
+ if (err)
+ goto activate_err;
+
+ return 0;
+
+activate_err:
+ vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+ vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+queue_err:
+ return err;
+}
+
+
+static int
+vmxnet3_close(struct net_device *netdev)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ /*
+ * Reset_work may be in the middle of resetting the device, wait for its
+ * completion.
+ */
+ while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
+ msleep(1);
+
+ vmxnet3_quiesce_dev(adapter);
+
+ vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+ vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+
+ clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
+
+
+ return 0;
+}
+
+
+void
+vmxnet3_force_close(struct vmxnet3_adapter *adapter)
+{
+ /*
+ * we must clear VMXNET3_STATE_BIT_RESETTING, otherwise
+ * vmxnet3_close() will deadlock.
+ */
+ BUG_ON(test_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state));
+
+ /* we need to enable NAPI, otherwise dev_close will deadlock */
+ napi_enable(&adapter->napi);
+ dev_close(adapter->netdev);
+}
+
+
+static int
+vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ int err = 0;
+
+ if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU)
+ return -EINVAL;
+
+ if (new_mtu > 1500 && !adapter->jumbo_frame)
+ return -EINVAL;
+
+ netdev->mtu = new_mtu;
+
+ /*
+ * Reset_work may be in the middle of resetting the device, wait for its
+ * completion.
+ */
+ while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
+ msleep(1);
+
+ if (netif_running(netdev)) {
+ vmxnet3_quiesce_dev(adapter);
+ vmxnet3_reset_dev(adapter);
+
+ /* we need to re-create the rx queue based on the new mtu */
+ vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+ vmxnet3_adjust_rx_ring_size(adapter);
+ adapter->rx_queue.comp_ring.size =
+ adapter->rx_queue.rx_ring[0].size +
+ adapter->rx_queue.rx_ring[1].size;
+ err = vmxnet3_rq_create(&adapter->rx_queue, adapter);
+ if (err) {
+ printk(KERN_ERR "%s: failed to re-create rx queue,"
+ " error %d. Closing it.\n", netdev->name, err);
+ goto out;
+ }
+
+ err = vmxnet3_activate_dev(adapter);
+ if (err) {
+ printk(KERN_ERR "%s: failed to re-activate, error %d. "
+ "Closing it\n", netdev->name, err);
+ goto out;
+ }
+ }
+
+out:
+ clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
+ if (err)
+ vmxnet3_force_close(adapter);
+
+ return err;
+}
+
+
+static void
+vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ netdev->features = NETIF_F_SG |
+ NETIF_F_HW_CSUM |
+ NETIF_F_HW_VLAN_TX |
+ NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER |
+ NETIF_F_TSO |
+ NETIF_F_TSO6 |
+ NETIF_F_LRO;
+
+ printk(KERN_INFO "features: sg csum vlan jf tso tsoIPv6 lro");
+
+ adapter->rxcsum = true;
+ adapter->jumbo_frame = true;
+ adapter->lro = true;
+
+ if (dma64) {
+ netdev->features |= NETIF_F_HIGHDMA;
+ printk(" highDMA");
+ }
+
+ netdev->vlan_features = netdev->features;
+ printk("\n");
+}
+
+
+static void
+vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)
+{
+ u32 tmp;
+
+ tmp = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACL);
+ *(u32 *)mac = tmp;
+
+ tmp = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACH);
+ mac[4] = tmp & 0xff;
+ mac[5] = (tmp >> 8) & 0xff;
+}
+
+
+static void
+vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
+{
+ u32 cfg;
+
+ /* intr settings */
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_GET_CONF_INTR);
+ cfg = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+ adapter->intr.type = cfg & 0x3;
+ adapter->intr.mask_mode = (cfg >> 2) & 0x3;
+
+ if (adapter->intr.type == VMXNET3_IT_AUTO) {
+ int err;
+
+#ifdef CONFIG_PCI_MSI
+ adapter->intr.msix_entries[0].entry = 0;
+ err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries,
+ VMXNET3_LINUX_MAX_MSIX_VECT);
+ if (!err) {
+ adapter->intr.num_intrs = 1;
+ adapter->intr.type = VMXNET3_IT_MSIX;
+ return;
+ }
+#endif
+
+ err = pci_enable_msi(adapter->pdev);
+ if (!err) {
+ adapter->intr.num_intrs = 1;
+ adapter->intr.type = VMXNET3_IT_MSI;
+ return;
+ }
+ }
+
+ adapter->intr.type = VMXNET3_IT_INTX;
+
+ /* INT-X related setting */
+ adapter->intr.num_intrs = 1;
+}
+
+
+static void
+vmxnet3_free_intr_resources(struct vmxnet3_adapter *adapter)
+{
+ if (adapter->intr.type == VMXNET3_IT_MSIX)
+ pci_disable_msix(adapter->pdev);
+ else if (adapter->intr.type == VMXNET3_IT_MSI)
+ pci_disable_msi(adapter->pdev);
+ else
+ BUG_ON(adapter->intr.type != VMXNET3_IT_INTX);
+}
+
+
+static void
+vmxnet3_tx_timeout(struct net_device *netdev)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ adapter->tx_timeout_count++;
+
+ printk(KERN_ERR "%s: tx hang\n", adapter->netdev->name);
+ schedule_work(&adapter->work);
+}
+
+
+static void
+vmxnet3_reset_work(struct work_struct *data)
+{
+ struct vmxnet3_adapter *adapter;
+
+ adapter = container_of(data, struct vmxnet3_adapter, work);
+
+ /* if another thread is resetting the device, no need to proceed */
+ if (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
+ return;
+
+ /* if the device is closed, we must leave it alone */
+ if (netif_running(adapter->netdev)) {
+ printk(KERN_INFO "%s: resetting\n", adapter->netdev->name);
+ vmxnet3_quiesce_dev(adapter);
+ vmxnet3_reset_dev(adapter);
+ vmxnet3_activate_dev(adapter);
+ } else {
+ printk(KERN_INFO "%s: already closed\n", adapter->netdev->name);
+ }
+
+ clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
+}
+
+
+static int __devinit
+vmxnet3_probe_device(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ static const struct net_device_ops vmxnet3_netdev_ops = {
+ .ndo_open = vmxnet3_open,
+ .ndo_stop = vmxnet3_close,
+ .ndo_start_xmit = vmxnet3_xmit_frame,
+ .ndo_set_mac_address = vmxnet3_set_mac_addr,
+ .ndo_change_mtu = vmxnet3_change_mtu,
+ .ndo_get_stats = vmxnet3_get_stats,
+ .ndo_tx_timeout = vmxnet3_tx_timeout,
+ .ndo_set_multicast_list = vmxnet3_set_mc,
+ .ndo_vlan_rx_register = vmxnet3_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = vmxnet3_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = vmxnet3_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = vmxnet3_netpoll,
+#endif
+ };
+ int err;
+ bool dma64 = false; /* stupid gcc */
+ u32 ver;
+ struct net_device *netdev;
+ struct vmxnet3_adapter *adapter;
+ u8 mac[ETH_ALEN];
+
+ netdev = alloc_etherdev(sizeof(struct vmxnet3_adapter));
+ if (!netdev) {
+ printk(KERN_ERR "Failed to alloc ethernet device for adapter "
+ "%s\n", pci_name(pdev));
+ return -ENOMEM;
+ }
+
+ pci_set_drvdata(pdev, netdev);
+ adapter = netdev_priv(netdev);
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+
+ adapter->shared = pci_alloc_consistent(adapter->pdev,
+ sizeof(struct Vmxnet3_DriverShared),
+ &adapter->shared_pa);
+ if (!adapter->shared) {
+ printk(KERN_ERR "Failed to allocate memory for %s\n",
+ pci_name(pdev));
+ err = -ENOMEM;
+ goto err_alloc_shared;
+ }
+
+ adapter->tqd_start = pci_alloc_consistent(adapter->pdev,
+ sizeof(struct Vmxnet3_TxQueueDesc) +
+ sizeof(struct Vmxnet3_RxQueueDesc),
+ &adapter->queue_desc_pa);
+
+ if (!adapter->tqd_start) {
+ printk(KERN_ERR "Failed to allocate memory for %s\n",
+ pci_name(pdev));
+ err = -ENOMEM;
+ goto err_alloc_queue_desc;
+ }
+ adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start
+ + 1);
+
+ adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL);
+ if (adapter->pm_conf == NULL) {
+ printk(KERN_ERR "Failed to allocate memory for %s\n",
+ pci_name(pdev));
+ err = -ENOMEM;
+ goto err_alloc_pm;
+ }
+
+ err = vmxnet3_alloc_pci_resources(adapter, &dma64);
+ if (err < 0)
+ goto err_alloc_pci;
+
+ ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_VRRS);
+ if (ver & 1) {
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_VRRS, 1);
+ } else {
+ printk(KERN_ERR "Incompatible h/w version (0x%x) for adapter"
+ " %s\n", ver, pci_name(pdev));
+ err = -EBUSY;
+ goto err_ver;
+ }
+
+ ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_UVRS);
+ if (ver & 1) {
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_UVRS, 1);
+ } else {
+ printk(KERN_ERR "Incompatible upt version (0x%x) for "
+ "adapter %s\n", ver, pci_name(pdev));
+ err = -EBUSY;
+ goto err_ver;
+ }
+
+ vmxnet3_declare_features(adapter, dma64);
+
+ adapter->dev_number = atomic_read(&devices_found);
+ vmxnet3_alloc_intr_resources(adapter);
+
+ vmxnet3_read_mac_addr(adapter, mac);
+ memcpy(netdev->dev_addr, mac, netdev->addr_len);
+
+ netdev->netdev_ops = &vmxnet3_netdev_ops;
+ netdev->watchdog_timeo = 5 * HZ;
+ vmxnet3_set_ethtool_ops(netdev);
+
+ INIT_WORK(&adapter->work, vmxnet3_reset_work);
+
+ netif_napi_add(netdev, &adapter->napi, vmxnet3_poll, 64);
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ err = register_netdev(netdev);
+
+ if (err) {
+ printk(KERN_ERR "Failed to register adapter %s\n",
+ pci_name(pdev));
+ goto err_register;
+ }
+
+ set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
+ atomic_inc(&devices_found);
+ return 0;
+
+err_register:
+ vmxnet3_free_intr_resources(adapter);
+err_ver:
+ vmxnet3_free_pci_resources(adapter);
+err_alloc_pci:
+ kfree(adapter->pm_conf);
+err_alloc_pm:
+ pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) +
+ sizeof(struct Vmxnet3_RxQueueDesc),
+ adapter->tqd_start, adapter->queue_desc_pa);
+err_alloc_queue_desc:
+ pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared),
+ adapter->shared, adapter->shared_pa);
+err_alloc_shared:
+ pci_set_drvdata(pdev, NULL);
+ free_netdev(netdev);
+ return err;
+}
+
+
+static void __devexit
+vmxnet3_remove_device(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ flush_scheduled_work();
+
+ unregister_netdev(netdev);
+
+ vmxnet3_free_intr_resources(adapter);
+ vmxnet3_free_pci_resources(adapter);
+ kfree(adapter->pm_conf);
+ pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) +
+ sizeof(struct Vmxnet3_RxQueueDesc),
+ adapter->tqd_start, adapter->queue_desc_pa);
+ pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared),
+ adapter->shared, adapter->shared_pa);
+ free_netdev(netdev);
+}
+
+
+#ifdef CONFIG_PM
+
+static int
+vmxnet3_suspend(struct device *device)
+{
+ struct pci_dev *pdev = to_pci_dev(device);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ struct Vmxnet3_PMConf *pmConf;
+ struct ethhdr *ehdr;
+ struct arphdr *ahdr;
+ u8 *arpreq;
+ struct in_device *in_dev;
+ struct in_ifaddr *ifa;
+ int i = 0;
+
+ if (!netif_running(netdev))
+ return 0;
+
+ vmxnet3_disable_all_intrs(adapter);
+ vmxnet3_free_irqs(adapter);
+ vmxnet3_free_intr_resources(adapter);
+
+ netif_device_detach(netdev);
+ netif_stop_queue(netdev);
+
+ /* Create wake-up filters. */
+ pmConf = adapter->pm_conf;
+ memset(pmConf, 0, sizeof(*pmConf));
+
+ if (adapter->wol & WAKE_UCAST) {
+ pmConf->filters[i].patternSize = ETH_ALEN;
+ pmConf->filters[i].maskSize = 1;
+ memcpy(pmConf->filters[i].pattern, netdev->dev_addr, ETH_ALEN);
+ pmConf->filters[i].mask[0] = 0x3F; /* LSB ETH_ALEN bits */
+
+ pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
+ i++;
+ }
+
+ if (adapter->wol & WAKE_ARP) {
+ in_dev = in_dev_get(netdev);
+ if (!in_dev)
+ goto skip_arp;
+
+ ifa = (struct in_ifaddr *)in_dev->ifa_list;
+ if (!ifa)
+ goto skip_arp;
+
+ pmConf->filters[i].patternSize = ETH_HLEN + /* Ethernet header*/
+ sizeof(struct arphdr) + /* ARP header */
+ 2 * ETH_ALEN + /* 2 Ethernet addresses*/
+ 2 * sizeof(u32); /*2 IPv4 addresses */
+ pmConf->filters[i].maskSize =
+ (pmConf->filters[i].patternSize - 1) / 8 + 1;
+
+ /* ETH_P_ARP in Ethernet header. */
+ ehdr = (struct ethhdr *)pmConf->filters[i].pattern;
+ ehdr->h_proto = htons(ETH_P_ARP);
+
+ /* ARPOP_REQUEST in ARP header. */
+ ahdr = (struct arphdr *)&pmConf->filters[i].pattern[ETH_HLEN];
+ ahdr->ar_op = htons(ARPOP_REQUEST);
+ arpreq = (u8 *)(ahdr + 1);
+
+ /* The Unicast IPv4 address in 'tip' field. */
+ arpreq += 2 * ETH_ALEN + sizeof(u32);
+ *(u32 *)arpreq = ifa->ifa_address;
+
+ /* The mask for the relevant bits. */
+ pmConf->filters[i].mask[0] = 0x00;
+ pmConf->filters[i].mask[1] = 0x30; /* ETH_P_ARP */
+ pmConf->filters[i].mask[2] = 0x30; /* ARPOP_REQUEST */
+ pmConf->filters[i].mask[3] = 0x00;
+ pmConf->filters[i].mask[4] = 0xC0; /* IPv4 TIP */
+ pmConf->filters[i].mask[5] = 0x03; /* IPv4 TIP */
+ in_dev_put(in_dev);
+
+ pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
+ i++;
+ }
+
+skip_arp:
+ if (adapter->wol & WAKE_MAGIC)
+ pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_MAGIC;
+
+ pmConf->numFilters = i;
+
+ adapter->shared->devRead.pmConfDesc.confVer = 1;
+ adapter->shared->devRead.pmConfDesc.confLen = sizeof(*pmConf);
+ adapter->shared->devRead.pmConfDesc.confPA = virt_to_phys(pmConf);
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_PMCFG);
+
+ pci_save_state(pdev);
+ pci_enable_wake(pdev, pci_choose_state(pdev, PMSG_SUSPEND),
+ adapter->wol);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, PMSG_SUSPEND));
+
+ return 0;
+}
+
+
+static int
+vmxnet3_resume(struct device *device)
+{
+ int err;
+ struct pci_dev *pdev = to_pci_dev(device);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ struct Vmxnet3_PMConf *pmConf;
+
+ if (!netif_running(netdev))
+ return 0;
+
+ /* Destroy wake-up filters. */
+ pmConf = adapter->pm_conf;
+ memset(pmConf, 0, sizeof(*pmConf));
+
+ adapter->shared->devRead.pmConfDesc.confVer = 1;
+ adapter->shared->devRead.pmConfDesc.confLen = sizeof(*pmConf);
+ adapter->shared->devRead.pmConfDesc.confPA = virt_to_phys(pmConf);
+
+ netif_device_attach(netdev);
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ err = pci_enable_device_mem(pdev);
+ if (err != 0)
+ return err;
+
+ pci_enable_wake(pdev, PCI_D0, 0);
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_PMCFG);
+ vmxnet3_alloc_intr_resources(adapter);
+ vmxnet3_request_irqs(adapter);
+ vmxnet3_enable_all_intrs(adapter);
+
+ return 0;
+}
+
+static struct dev_pm_ops vmxnet3_pm_ops = {
+ .suspend = vmxnet3_suspend,
+ .resume = vmxnet3_resume,
+};
+#endif
+
+static struct pci_driver vmxnet3_driver = {
+ .name = vmxnet3_driver_name,
+ .id_table = vmxnet3_pciid_table,
+ .probe = vmxnet3_probe_device,
+ .remove = __devexit_p(vmxnet3_remove_device),
+#ifdef CONFIG_PM
+ .driver.pm = &vmxnet3_pm_ops,
+#endif
+};
+
+
+static int __init
+vmxnet3_init_module(void)
+{
+ printk(KERN_INFO "%s - version %s\n", VMXNET3_DRIVER_DESC,
+ VMXNET3_DRIVER_VERSION_REPORT);
+ return pci_register_driver(&vmxnet3_driver);
+}
+
+module_init(vmxnet3_init_module);
+
+
+static void
+vmxnet3_exit_module(void)
+{
+ pci_unregister_driver(&vmxnet3_driver);
+}
+
+module_exit(vmxnet3_exit_module);
+
+MODULE_AUTHOR("VMware, Inc.");
+MODULE_DESCRIPTION(VMXNET3_DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(VMXNET3_DRIVER_VERSION_STRING);
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
new file mode 100644
index 000000000000..c2c15e4cafc7
--- /dev/null
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -0,0 +1,566 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, 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; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+
+#include "vmxnet3_int.h"
+
+struct vmxnet3_stat_desc {
+ char desc[ETH_GSTRING_LEN];
+ int offset;
+};
+
+
+static u32
+vmxnet3_get_rx_csum(struct net_device *netdev)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ return adapter->rxcsum;
+}
+
+
+static int
+vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ if (adapter->rxcsum != val) {
+ adapter->rxcsum = val;
+ if (netif_running(netdev)) {
+ if (val)
+ adapter->shared->devRead.misc.uptFeatures |=
+ UPT1_F_RXCSUM;
+ else
+ adapter->shared->devRead.misc.uptFeatures &=
+ ~UPT1_F_RXCSUM;
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_FEATURE);
+ }
+ }
+ return 0;
+}
+
+
+/* per tq stats maintained by the device */
+static const struct vmxnet3_stat_desc
+vmxnet3_tq_dev_stats[] = {
+ /* description, offset */
+ { "TSO pkts tx", offsetof(struct UPT1_TxStats, TSOPktsTxOK) },
+ { "TSO bytes tx", offsetof(struct UPT1_TxStats, TSOBytesTxOK) },
+ { "ucast pkts tx", offsetof(struct UPT1_TxStats, ucastPktsTxOK) },
+ { "ucast bytes tx", offsetof(struct UPT1_TxStats, ucastBytesTxOK) },
+ { "mcast pkts tx", offsetof(struct UPT1_TxStats, mcastPktsTxOK) },
+ { "mcast bytes tx", offsetof(struct UPT1_TxStats, mcastBytesTxOK) },
+ { "bcast pkts tx", offsetof(struct UPT1_TxStats, bcastPktsTxOK) },
+ { "bcast bytes tx", offsetof(struct UPT1_TxStats, bcastBytesTxOK) },
+ { "pkts tx err", offsetof(struct UPT1_TxStats, pktsTxError) },
+ { "pkts tx discard", offsetof(struct UPT1_TxStats, pktsTxDiscard) },
+};
+
+/* per tq stats maintained by the driver */
+static const struct vmxnet3_stat_desc
+vmxnet3_tq_driver_stats[] = {
+ /* description, offset */
+ {"drv dropped tx total", offsetof(struct vmxnet3_tq_driver_stats,
+ drop_total) },
+ { " too many frags", offsetof(struct vmxnet3_tq_driver_stats,
+ drop_too_many_frags) },
+ { " giant hdr", offsetof(struct vmxnet3_tq_driver_stats,
+ drop_oversized_hdr) },
+ { " hdr err", offsetof(struct vmxnet3_tq_driver_stats,
+ drop_hdr_inspect_err) },
+ { " tso", offsetof(struct vmxnet3_tq_driver_stats,
+ drop_tso) },
+ { "ring full", offsetof(struct vmxnet3_tq_driver_stats,
+ tx_ring_full) },
+ { "pkts linearized", offsetof(struct vmxnet3_tq_driver_stats,
+ linearized) },
+ { "hdr cloned", offsetof(struct vmxnet3_tq_driver_stats,
+ copy_skb_header) },
+ { "giant hdr", offsetof(struct vmxnet3_tq_driver_stats,
+ oversized_hdr) },
+};
+
+/* per rq stats maintained by the device */
+static const struct vmxnet3_stat_desc
+vmxnet3_rq_dev_stats[] = {
+ { "LRO pkts rx", offsetof(struct UPT1_RxStats, LROPktsRxOK) },
+ { "LRO byte rx", offsetof(struct UPT1_RxStats, LROBytesRxOK) },
+ { "ucast pkts rx", offsetof(struct UPT1_RxStats, ucastPktsRxOK) },
+ { "ucast bytes rx", offsetof(struct UPT1_RxStats, ucastBytesRxOK) },
+ { "mcast pkts rx", offsetof(struct UPT1_RxStats, mcastPktsRxOK) },
+ { "mcast bytes rx", offsetof(struct UPT1_RxStats, mcastBytesRxOK) },
+ { "bcast pkts rx", offsetof(struct UPT1_RxStats, bcastPktsRxOK) },
+ { "bcast bytes rx", offsetof(struct UPT1_RxStats, bcastBytesRxOK) },
+ { "pkts rx out of buf", offsetof(struct UPT1_RxStats, pktsRxOutOfBuf) },
+ { "pkts rx err", offsetof(struct UPT1_RxStats, pktsRxError) },
+};
+
+/* per rq stats maintained by the driver */
+static const struct vmxnet3_stat_desc
+vmxnet3_rq_driver_stats[] = {
+ /* description, offset */
+ { "drv dropped rx total", offsetof(struct vmxnet3_rq_driver_stats,
+ drop_total) },
+ { " err", offsetof(struct vmxnet3_rq_driver_stats,
+ drop_err) },
+ { " fcs", offsetof(struct vmxnet3_rq_driver_stats,
+ drop_fcs) },
+ { "rx buf alloc fail", offsetof(struct vmxnet3_rq_driver_stats,
+ rx_buf_alloc_failure) },
+};
+
+/* gloabl stats maintained by the driver */
+static const struct vmxnet3_stat_desc
+vmxnet3_global_stats[] = {
+ /* description, offset */
+ { "tx timeout count", offsetof(struct vmxnet3_adapter,
+ tx_timeout_count) }
+};
+
+
+struct net_device_stats *
+vmxnet3_get_stats(struct net_device *netdev)
+{
+ struct vmxnet3_adapter *adapter;
+ struct vmxnet3_tq_driver_stats *drvTxStats;
+ struct vmxnet3_rq_driver_stats *drvRxStats;
+ struct UPT1_TxStats *devTxStats;
+ struct UPT1_RxStats *devRxStats;
+ struct net_device_stats *net_stats = &netdev->stats;
+
+ adapter = netdev_priv(netdev);
+
+ /* Collect the dev stats into the shared area */
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
+
+ /* Assuming that we have a single queue device */
+ devTxStats = &adapter->tqd_start->stats;
+ devRxStats = &adapter->rqd_start->stats;
+
+ /* Get access to the driver stats per queue */
+ drvTxStats = &adapter->tx_queue.stats;
+ drvRxStats = &adapter->rx_queue.stats;
+
+ memset(net_stats, 0, sizeof(*net_stats));
+
+ net_stats->rx_packets = devRxStats->ucastPktsRxOK +
+ devRxStats->mcastPktsRxOK +
+ devRxStats->bcastPktsRxOK;
+
+ net_stats->tx_packets = devTxStats->ucastPktsTxOK +
+ devTxStats->mcastPktsTxOK +
+ devTxStats->bcastPktsTxOK;
+
+ net_stats->rx_bytes = devRxStats->ucastBytesRxOK +
+ devRxStats->mcastBytesRxOK +
+ devRxStats->bcastBytesRxOK;
+
+ net_stats->tx_bytes = devTxStats->ucastBytesTxOK +
+ devTxStats->mcastBytesTxOK +
+ devTxStats->bcastBytesTxOK;
+
+ net_stats->rx_errors = devRxStats->pktsRxError;
+ net_stats->tx_errors = devTxStats->pktsTxError;
+ net_stats->rx_dropped = drvRxStats->drop_total;
+ net_stats->tx_dropped = drvTxStats->drop_total;
+ net_stats->multicast = devRxStats->mcastPktsRxOK;
+
+ return net_stats;
+}
+
+static int
+vmxnet3_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return ARRAY_SIZE(vmxnet3_tq_dev_stats) +
+ ARRAY_SIZE(vmxnet3_tq_driver_stats) +
+ ARRAY_SIZE(vmxnet3_rq_dev_stats) +
+ ARRAY_SIZE(vmxnet3_rq_driver_stats) +
+ ARRAY_SIZE(vmxnet3_global_stats);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+
+static int
+vmxnet3_get_regs_len(struct net_device *netdev)
+{
+ return 20 * sizeof(u32);
+}
+
+
+static void
+vmxnet3_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ strlcpy(drvinfo->driver, vmxnet3_driver_name, sizeof(drvinfo->driver));
+ drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
+
+ strlcpy(drvinfo->version, VMXNET3_DRIVER_VERSION_REPORT,
+ sizeof(drvinfo->version));
+ drvinfo->driver[sizeof(drvinfo->version) - 1] = '\0';
+
+ strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+ drvinfo->fw_version[sizeof(drvinfo->fw_version) - 1] = '\0';
+
+ strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ ETHTOOL_BUSINFO_LEN);
+ drvinfo->n_stats = vmxnet3_get_sset_count(netdev, ETH_SS_STATS);
+ drvinfo->testinfo_len = 0;
+ drvinfo->eedump_len = 0;
+ drvinfo->regdump_len = vmxnet3_get_regs_len(netdev);
+}
+
+
+static void
+vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
+{
+ if (stringset == ETH_SS_STATS) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++) {
+ memcpy(buf, vmxnet3_tq_dev_stats[i].desc,
+ ETH_GSTRING_LEN);
+ buf += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++) {
+ memcpy(buf, vmxnet3_tq_driver_stats[i].desc,
+ ETH_GSTRING_LEN);
+ buf += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++) {
+ memcpy(buf, vmxnet3_rq_dev_stats[i].desc,
+ ETH_GSTRING_LEN);
+ buf += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++) {
+ memcpy(buf, vmxnet3_rq_driver_stats[i].desc,
+ ETH_GSTRING_LEN);
+ buf += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++) {
+ memcpy(buf, vmxnet3_global_stats[i].desc,
+ ETH_GSTRING_LEN);
+ buf += ETH_GSTRING_LEN;
+ }
+ }
+}
+
+static u32
+vmxnet3_get_flags(struct net_device *netdev) {
+ return netdev->features;
+}
+
+static int
+vmxnet3_set_flags(struct net_device *netdev, u32 data) {
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
+ u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
+
+ if (lro_requested ^ lro_present) {
+ /* toggle the LRO feature*/
+ netdev->features ^= NETIF_F_LRO;
+
+ /* update harware LRO capability accordingly */
+ if (lro_requested)
+ adapter->shared->devRead.misc.uptFeatures &= UPT1_F_LRO;
+ else
+ adapter->shared->devRead.misc.uptFeatures &=
+ ~UPT1_F_LRO;
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_FEATURE);
+ }
+ return 0;
+}
+
+static void
+vmxnet3_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats, u64 *buf)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ u8 *base;
+ int i;
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
+
+ /* this does assume each counter is 64-bit wide */
+
+ base = (u8 *)&adapter->tqd_start->stats;
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
+ *buf++ = *(u64 *)(base + vmxnet3_tq_dev_stats[i].offset);
+
+ base = (u8 *)&adapter->tx_queue.stats;
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
+ *buf++ = *(u64 *)(base + vmxnet3_tq_driver_stats[i].offset);
+
+ base = (u8 *)&adapter->rqd_start->stats;
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
+ *buf++ = *(u64 *)(base + vmxnet3_rq_dev_stats[i].offset);
+
+ base = (u8 *)&adapter->rx_queue.stats;
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
+ *buf++ = *(u64 *)(base + vmxnet3_rq_driver_stats[i].offset);
+
+ base = (u8 *)adapter;
+ for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
+ *buf++ = *(u64 *)(base + vmxnet3_global_stats[i].offset);
+}
+
+
+static void
+vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ u32 *buf = p;
+
+ memset(p, 0, vmxnet3_get_regs_len(netdev));
+
+ regs->version = 1;
+
+ /* Update vmxnet3_get_regs_len if we want to dump more registers */
+
+ /* make each ring use multiple of 16 bytes */
+ buf[0] = adapter->tx_queue.tx_ring.next2fill;
+ buf[1] = adapter->tx_queue.tx_ring.next2comp;
+ buf[2] = adapter->tx_queue.tx_ring.gen;
+ buf[3] = 0;
+
+ buf[4] = adapter->tx_queue.comp_ring.next2proc;
+ buf[5] = adapter->tx_queue.comp_ring.gen;
+ buf[6] = adapter->tx_queue.stopped;
+ buf[7] = 0;
+
+ buf[8] = adapter->rx_queue.rx_ring[0].next2fill;
+ buf[9] = adapter->rx_queue.rx_ring[0].next2comp;
+ buf[10] = adapter->rx_queue.rx_ring[0].gen;
+ buf[11] = 0;
+
+ buf[12] = adapter->rx_queue.rx_ring[1].next2fill;
+ buf[13] = adapter->rx_queue.rx_ring[1].next2comp;
+ buf[14] = adapter->rx_queue.rx_ring[1].gen;
+ buf[15] = 0;
+
+ buf[16] = adapter->rx_queue.comp_ring.next2proc;
+ buf[17] = adapter->rx_queue.comp_ring.gen;
+ buf[18] = 0;
+ buf[19] = 0;
+}
+
+
+static void
+vmxnet3_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ wol->supported = WAKE_UCAST | WAKE_ARP | WAKE_MAGIC;
+ wol->wolopts = adapter->wol;
+}
+
+
+static int
+vmxnet3_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ if (wol->wolopts & (WAKE_PHY | WAKE_MCAST | WAKE_BCAST |
+ WAKE_MAGICSECURE)) {
+ return -EOPNOTSUPP;
+ }
+
+ adapter->wol = wol->wolopts;
+
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+ return 0;
+}
+
+
+static int
+vmxnet3_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ ecmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_1000baseT_Full |
+ SUPPORTED_TP;
+ ecmd->advertising = ADVERTISED_TP;
+ ecmd->port = PORT_TP;
+ ecmd->transceiver = XCVR_INTERNAL;
+
+ if (adapter->link_speed) {
+ ecmd->speed = adapter->link_speed;
+ ecmd->duplex = DUPLEX_FULL;
+ } else {
+ ecmd->speed = -1;
+ ecmd->duplex = -1;
+ }
+ return 0;
+}
+
+
+static void
+vmxnet3_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *param)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ param->rx_max_pending = VMXNET3_RX_RING_MAX_SIZE;
+ param->tx_max_pending = VMXNET3_TX_RING_MAX_SIZE;
+ param->rx_mini_max_pending = 0;
+ param->rx_jumbo_max_pending = 0;
+
+ param->rx_pending = adapter->rx_queue.rx_ring[0].size;
+ param->tx_pending = adapter->tx_queue.tx_ring.size;
+ param->rx_mini_pending = 0;
+ param->rx_jumbo_pending = 0;
+}
+
+
+static int
+vmxnet3_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *param)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ u32 new_tx_ring_size, new_rx_ring_size;
+ u32 sz;
+ int err = 0;
+
+ if (param->tx_pending == 0 || param->tx_pending >
+ VMXNET3_TX_RING_MAX_SIZE)
+ return -EINVAL;
+
+ if (param->rx_pending == 0 || param->rx_pending >
+ VMXNET3_RX_RING_MAX_SIZE)
+ return -EINVAL;
+
+
+ /* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */
+ new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) &
+ ~VMXNET3_RING_SIZE_MASK;
+ new_tx_ring_size = min_t(u32, new_tx_ring_size,
+ VMXNET3_TX_RING_MAX_SIZE);
+ if (new_tx_ring_size > VMXNET3_TX_RING_MAX_SIZE || (new_tx_ring_size %
+ VMXNET3_RING_SIZE_ALIGN) != 0)
+ return -EINVAL;
+
+ /* ring0 has to be a multiple of
+ * rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN
+ */
+ sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN;
+ new_rx_ring_size = (param->rx_pending + sz - 1) / sz * sz;
+ new_rx_ring_size = min_t(u32, new_rx_ring_size,
+ VMXNET3_RX_RING_MAX_SIZE / sz * sz);
+ if (new_rx_ring_size > VMXNET3_RX_RING_MAX_SIZE || (new_rx_ring_size %
+ sz) != 0)
+ return -EINVAL;
+
+ if (new_tx_ring_size == adapter->tx_queue.tx_ring.size &&
+ new_rx_ring_size == adapter->rx_queue.rx_ring[0].size) {
+ return 0;
+ }
+
+ /*
+ * Reset_work may be in the middle of resetting the device, wait for its
+ * completion.
+ */
+ while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
+ msleep(1);
+
+ if (netif_running(netdev)) {
+ vmxnet3_quiesce_dev(adapter);
+ vmxnet3_reset_dev(adapter);
+
+ /* recreate the rx queue and the tx queue based on the
+ * new sizes */
+ vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+ vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+
+ err = vmxnet3_create_queues(adapter, new_tx_ring_size,
+ new_rx_ring_size, VMXNET3_DEF_RX_RING_SIZE);
+ if (err) {
+ /* failed, most likely because of OOM, try default
+ * size */
+ printk(KERN_ERR "%s: failed to apply new sizes, try the"
+ " default ones\n", netdev->name);
+ err = vmxnet3_create_queues(adapter,
+ VMXNET3_DEF_TX_RING_SIZE,
+ VMXNET3_DEF_RX_RING_SIZE,
+ VMXNET3_DEF_RX_RING_SIZE);
+ if (err) {
+ printk(KERN_ERR "%s: failed to create queues "
+ "with default sizes. Closing it\n",
+ netdev->name);
+ goto out;
+ }
+ }
+
+ err = vmxnet3_activate_dev(adapter);
+ if (err)
+ printk(KERN_ERR "%s: failed to re-activate, error %d."
+ " Closing it\n", netdev->name, err);
+ }
+
+out:
+ clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
+ if (err)
+ vmxnet3_force_close(adapter);
+
+ return err;
+}
+
+
+static struct ethtool_ops vmxnet3_ethtool_ops = {
+ .get_settings = vmxnet3_get_settings,
+ .get_drvinfo = vmxnet3_get_drvinfo,
+ .get_regs_len = vmxnet3_get_regs_len,
+ .get_regs = vmxnet3_get_regs,
+ .get_wol = vmxnet3_get_wol,
+ .set_wol = vmxnet3_set_wol,
+ .get_link = ethtool_op_get_link,
+ .get_rx_csum = vmxnet3_get_rx_csum,
+ .set_rx_csum = vmxnet3_set_rx_csum,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_hw_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = ethtool_op_set_tso,
+ .get_strings = vmxnet3_get_strings,
+ .get_flags = vmxnet3_get_flags,
+ .set_flags = vmxnet3_set_flags,
+ .get_sset_count = vmxnet3_get_sset_count,
+ .get_ethtool_stats = vmxnet3_get_ethtool_stats,
+ .get_ringparam = vmxnet3_get_ringparam,
+ .set_ringparam = vmxnet3_set_ringparam,
+};
+
+void vmxnet3_set_ethtool_ops(struct net_device *netdev)
+{
+ SET_ETHTOOL_OPS(netdev, &vmxnet3_ethtool_ops);
+}
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
new file mode 100644
index 000000000000..3c0d70d58111
--- /dev/null
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -0,0 +1,389 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, 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; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+#ifndef _VMXNET3_INT_H
+#define _VMXNET3_INT_H
+
+#include <linux/types.h>
+#include <linux/ethtool.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/ethtool.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/uaccess.h>
+#include <asm/dma.h>
+#include <asm/page.h>
+
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/in.h>
+#include <linux/etherdevice.h>
+#include <asm/checksum.h>
+#include <linux/if_vlan.h>
+#include <linux/if_arp.h>
+#include <linux/inetdevice.h>
+
+#include "vmxnet3_defs.h"
+
+#ifdef DEBUG
+# define VMXNET3_DRIVER_VERSION_REPORT VMXNET3_DRIVER_VERSION_STRING"-NAPI(debug)"
+#else
+# define VMXNET3_DRIVER_VERSION_REPORT VMXNET3_DRIVER_VERSION_STRING"-NAPI"
+#endif
+
+
+/*
+ * Version numbers
+ */
+#define VMXNET3_DRIVER_VERSION_STRING "1.0.5.0-k"
+
+/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
+#define VMXNET3_DRIVER_VERSION_NUM 0x01000500
+
+
+/*
+ * Capabilities
+ */
+
+enum {
+ VMNET_CAP_SG = 0x0001, /* Can do scatter-gather transmits. */
+ VMNET_CAP_IP4_CSUM = 0x0002, /* Can checksum only TCP/UDP over
+ * IPv4 */
+ VMNET_CAP_HW_CSUM = 0x0004, /* Can checksum all packets. */
+ VMNET_CAP_HIGH_DMA = 0x0008, /* Can DMA to high memory. */
+ VMNET_CAP_TOE = 0x0010, /* Supports TCP/IP offload. */
+ VMNET_CAP_TSO = 0x0020, /* Supports TCP Segmentation
+ * offload */
+ VMNET_CAP_SW_TSO = 0x0040, /* Supports SW TCP Segmentation */
+ VMNET_CAP_VMXNET_APROM = 0x0080, /* Vmxnet APROM support */
+ VMNET_CAP_HW_TX_VLAN = 0x0100, /* Can we do VLAN tagging in HW */
+ VMNET_CAP_HW_RX_VLAN = 0x0200, /* Can we do VLAN untagging in HW */
+ VMNET_CAP_SW_VLAN = 0x0400, /* VLAN tagging/untagging in SW */
+ VMNET_CAP_WAKE_PCKT_RCV = 0x0800, /* Can wake on network packet recv? */
+ VMNET_CAP_ENABLE_INT_INLINE = 0x1000, /* Enable Interrupt Inline */
+ VMNET_CAP_ENABLE_HEADER_COPY = 0x2000, /* copy header for vmkernel */
+ VMNET_CAP_TX_CHAIN = 0x4000, /* Guest can use multiple tx entries
+ * for a pkt */
+ VMNET_CAP_RX_CHAIN = 0x8000, /* pkt can span multiple rx entries */
+ VMNET_CAP_LPD = 0x10000, /* large pkt delivery */
+ VMNET_CAP_BPF = 0x20000, /* BPF Support in VMXNET Virtual HW*/
+ VMNET_CAP_SG_SPAN_PAGES = 0x40000, /* Scatter-gather can span multiple*/
+ /* pages transmits */
+ VMNET_CAP_IP6_CSUM = 0x80000, /* Can do IPv6 csum offload. */
+ VMNET_CAP_TSO6 = 0x100000, /* TSO seg. offload for IPv6 pkts. */
+ VMNET_CAP_TSO256k = 0x200000, /* Can do TSO seg offload for */
+ /* pkts up to 256kB. */
+ VMNET_CAP_UPT = 0x400000 /* Support UPT */
+};
+
+/*
+ * PCI vendor and device IDs.
+ */
+#define PCI_VENDOR_ID_VMWARE 0x15AD
+#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
+#define MAX_ETHERNET_CARDS 10
+#define MAX_PCI_PASSTHRU_DEVICE 6
+
+struct vmxnet3_cmd_ring {
+ union Vmxnet3_GenericDesc *base;
+ u32 size;
+ u32 next2fill;
+ u32 next2comp;
+ u8 gen;
+ dma_addr_t basePA;
+};
+
+static inline void
+vmxnet3_cmd_ring_adv_next2fill(struct vmxnet3_cmd_ring *ring)
+{
+ ring->next2fill++;
+ if (unlikely(ring->next2fill == ring->size)) {
+ ring->next2fill = 0;
+ VMXNET3_FLIP_RING_GEN(ring->gen);
+ }
+}
+
+static inline void
+vmxnet3_cmd_ring_adv_next2comp(struct vmxnet3_cmd_ring *ring)
+{
+ VMXNET3_INC_RING_IDX_ONLY(ring->next2comp, ring->size);
+}
+
+static inline int
+vmxnet3_cmd_ring_desc_avail(struct vmxnet3_cmd_ring *ring)
+{
+ return (ring->next2comp > ring->next2fill ? 0 : ring->size) +
+ ring->next2comp - ring->next2fill - 1;
+}
+
+struct vmxnet3_comp_ring {
+ union Vmxnet3_GenericDesc *base;
+ u32 size;
+ u32 next2proc;
+ u8 gen;
+ u8 intr_idx;
+ dma_addr_t basePA;
+};
+
+static inline void
+vmxnet3_comp_ring_adv_next2proc(struct vmxnet3_comp_ring *ring)
+{
+ ring->next2proc++;
+ if (unlikely(ring->next2proc == ring->size)) {
+ ring->next2proc = 0;
+ VMXNET3_FLIP_RING_GEN(ring->gen);
+ }
+}
+
+struct vmxnet3_tx_data_ring {
+ struct Vmxnet3_TxDataDesc *base;
+ u32 size;
+ dma_addr_t basePA;
+};
+
+enum vmxnet3_buf_map_type {
+ VMXNET3_MAP_INVALID = 0,
+ VMXNET3_MAP_NONE,
+ VMXNET3_MAP_SINGLE,
+ VMXNET3_MAP_PAGE,
+};
+
+struct vmxnet3_tx_buf_info {
+ u32 map_type;
+ u16 len;
+ u16 sop_idx;
+ dma_addr_t dma_addr;
+ struct sk_buff *skb;
+};
+
+struct vmxnet3_tq_driver_stats {
+ u64 drop_total; /* # of pkts dropped by the driver, the
+ * counters below track droppings due to
+ * different reasons
+ */
+ u64 drop_too_many_frags;
+ u64 drop_oversized_hdr;
+ u64 drop_hdr_inspect_err;
+ u64 drop_tso;
+
+ u64 tx_ring_full;
+ u64 linearized; /* # of pkts linearized */
+ u64 copy_skb_header; /* # of times we have to copy skb header */
+ u64 oversized_hdr;
+};
+
+struct vmxnet3_tx_ctx {
+ bool ipv4;
+ u16 mss;
+ u32 eth_ip_hdr_size; /* only valid for pkts requesting tso or csum
+ * offloading
+ */
+ u32 l4_hdr_size; /* only valid if mss != 0 */
+ u32 copy_size; /* # of bytes copied into the data ring */
+ union Vmxnet3_GenericDesc *sop_txd;
+ union Vmxnet3_GenericDesc *eop_txd;
+};
+
+struct vmxnet3_tx_queue {
+ spinlock_t tx_lock;
+ struct vmxnet3_cmd_ring tx_ring;
+ struct vmxnet3_tx_buf_info *buf_info;
+ struct vmxnet3_tx_data_ring data_ring;
+ struct vmxnet3_comp_ring comp_ring;
+ struct Vmxnet3_TxQueueCtrl *shared;
+ struct vmxnet3_tq_driver_stats stats;
+ bool stopped;
+ int num_stop; /* # of times the queue is
+ * stopped */
+} __attribute__((__aligned__(SMP_CACHE_BYTES)));
+
+enum vmxnet3_rx_buf_type {
+ VMXNET3_RX_BUF_NONE = 0,
+ VMXNET3_RX_BUF_SKB = 1,
+ VMXNET3_RX_BUF_PAGE = 2
+};
+
+struct vmxnet3_rx_buf_info {
+ enum vmxnet3_rx_buf_type buf_type;
+ u16 len;
+ union {
+ struct sk_buff *skb;
+ struct page *page;
+ };
+ dma_addr_t dma_addr;
+};
+
+struct vmxnet3_rx_ctx {
+ struct sk_buff *skb;
+ u32 sop_idx;
+};
+
+struct vmxnet3_rq_driver_stats {
+ u64 drop_total;
+ u64 drop_err;
+ u64 drop_fcs;
+ u64 rx_buf_alloc_failure;
+};
+
+struct vmxnet3_rx_queue {
+ struct vmxnet3_cmd_ring rx_ring[2];
+ struct vmxnet3_comp_ring comp_ring;
+ struct vmxnet3_rx_ctx rx_ctx;
+ u32 qid; /* rqID in RCD for buffer from 1st ring */
+ u32 qid2; /* rqID in RCD for buffer from 2nd ring */
+ u32 uncommitted[2]; /* # of buffers allocated since last RXPROD
+ * update */
+ struct vmxnet3_rx_buf_info *buf_info[2];
+ struct Vmxnet3_RxQueueCtrl *shared;
+ struct vmxnet3_rq_driver_stats stats;
+} __attribute__((__aligned__(SMP_CACHE_BYTES)));
+
+#define VMXNET3_LINUX_MAX_MSIX_VECT 1
+
+struct vmxnet3_intr {
+ enum vmxnet3_intr_mask_mode mask_mode;
+ enum vmxnet3_intr_type type; /* MSI-X, MSI, or INTx? */
+ u8 num_intrs; /* # of intr vectors */
+ u8 event_intr_idx; /* idx of the intr vector for event */
+ u8 mod_levels[VMXNET3_LINUX_MAX_MSIX_VECT]; /* moderation level */
+#ifdef CONFIG_PCI_MSI
+ struct msix_entry msix_entries[VMXNET3_LINUX_MAX_MSIX_VECT];
+#endif
+};
+
+#define VMXNET3_STATE_BIT_RESETTING 0
+#define VMXNET3_STATE_BIT_QUIESCED 1
+struct vmxnet3_adapter {
+ struct vmxnet3_tx_queue tx_queue;
+ struct vmxnet3_rx_queue rx_queue;
+ struct napi_struct napi;
+ struct vlan_group *vlan_grp;
+
+ struct vmxnet3_intr intr;
+
+ struct Vmxnet3_DriverShared *shared;
+ struct Vmxnet3_PMConf *pm_conf;
+ struct Vmxnet3_TxQueueDesc *tqd_start; /* first tx queue desc */
+ struct Vmxnet3_RxQueueDesc *rqd_start; /* first rx queue desc */
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+
+ u8 *hw_addr0; /* for BAR 0 */
+ u8 *hw_addr1; /* for BAR 1 */
+
+ /* feature control */
+ bool rxcsum;
+ bool lro;
+ bool jumbo_frame;
+
+ /* rx buffer related */
+ unsigned skb_buf_size;
+ int rx_buf_per_pkt; /* only apply to the 1st ring */
+ dma_addr_t shared_pa;
+ dma_addr_t queue_desc_pa;
+
+ /* Wake-on-LAN */
+ u32 wol;
+
+ /* Link speed */
+ u32 link_speed; /* in mbps */
+
+ u64 tx_timeout_count;
+ struct work_struct work;
+
+ unsigned long state; /* VMXNET3_STATE_BIT_xxx */
+
+ int dev_number;
+};
+
+#define VMXNET3_WRITE_BAR0_REG(adapter, reg, val) \
+ writel((val), (adapter)->hw_addr0 + (reg))
+#define VMXNET3_READ_BAR0_REG(adapter, reg) \
+ readl((adapter)->hw_addr0 + (reg))
+
+#define VMXNET3_WRITE_BAR1_REG(adapter, reg, val) \
+ writel((val), (adapter)->hw_addr1 + (reg))
+#define VMXNET3_READ_BAR1_REG(adapter, reg) \
+ readl((adapter)->hw_addr1 + (reg))
+
+#define VMXNET3_WAKE_QUEUE_THRESHOLD(tq) (5)
+#define VMXNET3_RX_ALLOC_THRESHOLD(rq, ring_idx, adapter) \
+ ((rq)->rx_ring[ring_idx].size >> 3)
+
+#define VMXNET3_GET_ADDR_LO(dma) ((u32)(dma))
+#define VMXNET3_GET_ADDR_HI(dma) ((u32)(((u64)(dma)) >> 32))
+
+/* must be a multiple of VMXNET3_RING_SIZE_ALIGN */
+#define VMXNET3_DEF_TX_RING_SIZE 512
+#define VMXNET3_DEF_RX_RING_SIZE 256
+
+#define VMXNET3_MAX_ETH_HDR_SIZE 22
+#define VMXNET3_MAX_SKB_BUF_SIZE (3*1024)
+
+int
+vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter);
+
+int
+vmxnet3_activate_dev(struct vmxnet3_adapter *adapter);
+
+void
+vmxnet3_force_close(struct vmxnet3_adapter *adapter);
+
+void
+vmxnet3_reset_dev(struct vmxnet3_adapter *adapter);
+
+void
+vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
+ struct vmxnet3_adapter *adapter);
+
+void
+vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
+ struct vmxnet3_adapter *adapter);
+
+int
+vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
+ u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size);
+
+extern void vmxnet3_set_ethtool_ops(struct net_device *netdev);
+extern struct net_device_stats *vmxnet3_get_stats(struct net_device *netdev);
+
+extern char vmxnet3_driver_name[];
+#endif
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index e2c33c06190b..8e25ca7080c7 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -907,6 +907,7 @@ static ssize_t cosa_write(struct file *file,
current->state = TASK_RUNNING;
chan->tx_status = 1;
spin_unlock_irqrestore(&cosa->lock, flags);
+ up(&chan->wsem);
return -ERESTARTSYS;
}
}
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index cf5fd17ad707..f1bff98acd1f 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -58,8 +58,7 @@ struct cisco_state {
spinlock_t lock;
unsigned long last_poll;
int up;
- int request_sent;
- u32 txseq; /* TX sequence number */
+ u32 txseq; /* TX sequence number, 0 = none */
u32 rxseq; /* RX sequence number */
};
@@ -163,6 +162,7 @@ static int cisco_rx(struct sk_buff *skb)
struct cisco_packet *cisco_data;
struct in_device *in_dev;
__be32 addr, mask;
+ u32 ack;
if (skb->len < sizeof(struct hdlc_header))
goto rx_error;
@@ -223,8 +223,10 @@ static int cisco_rx(struct sk_buff *skb)
case CISCO_KEEPALIVE_REQ:
spin_lock(&st->lock);
st->rxseq = ntohl(cisco_data->par1);
- if (st->request_sent &&
- ntohl(cisco_data->par2) == st->txseq) {
+ ack = ntohl(cisco_data->par2);
+ if (ack && (ack == st->txseq ||
+ /* our current REQ may be in transit */
+ ack == st->txseq - 1)) {
st->last_poll = jiffies;
if (!st->up) {
u32 sec, min, hrs, days;
@@ -275,7 +277,6 @@ static void cisco_timer(unsigned long arg)
cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, htonl(++st->txseq),
htonl(st->rxseq));
- st->request_sent = 1;
spin_unlock(&st->lock);
st->timer.expires = jiffies + st->settings.interval * HZ;
@@ -293,9 +294,7 @@ static void cisco_start(struct net_device *dev)
unsigned long flags;
spin_lock_irqsave(&st->lock, flags);
- st->up = 0;
- st->request_sent = 0;
- st->txseq = st->rxseq = 0;
+ st->up = st->txseq = st->rxseq = 0;
spin_unlock_irqrestore(&st->lock, flags);
init_timer(&st->timer);
@@ -317,8 +316,7 @@ static void cisco_stop(struct net_device *dev)
spin_lock_irqsave(&st->lock, flags);
netif_dormant_on(dev);
- st->up = 0;
- st->request_sent = 0;
+ st->up = st->txseq = 0;
spin_unlock_irqrestore(&st->lock, flags);
}
diff --git a/drivers/net/wireless/adm8211.h b/drivers/net/wireless/adm8211.h
index 4f6ab1322189..b07e4d3a6b4d 100644
--- a/drivers/net/wireless/adm8211.h
+++ b/drivers/net/wireless/adm8211.h
@@ -266,7 +266,7 @@ do { \
#define ADM8211_SYNCTL_CS1 (1 << 28)
#define ADM8211_SYNCTL_CAL (1 << 27)
#define ADM8211_SYNCTL_SELCAL (1 << 26)
-#define ADM8211_SYNCTL_RFtype ((1 << 24) || (1 << 23) || (1 << 22))
+#define ADM8211_SYNCTL_RFtype ((1 << 24) | (1 << 23) | (1 << 22))
#define ADM8211_SYNCTL_RFMD (1 << 22)
#define ADM8211_SYNCTL_GENERAL (0x7 << 22)
/* SYNCTL 21:0 Data (Si4126: 18-bit data, 4-bit address) */
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 7116a1aa20ce..abf896a7390e 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4790,9 +4790,8 @@ static int proc_stats_rid_open( struct inode *inode,
static int get_dec_u16( char *buffer, int *start, int limit ) {
u16 value;
int valid = 0;
- for( value = 0; buffer[*start] >= '0' &&
- buffer[*start] <= '9' &&
- *start < limit; (*start)++ ) {
+ for (value = 0; *start < limit && buffer[*start] >= '0' &&
+ buffer[*start] <= '9'; (*start)++) {
valid = 1;
value *= 10;
value += buffer[*start] - '0';
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index d0593ed9170e..f6036fb42319 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -43,21 +43,6 @@
#include "airo.h"
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-static char *version = "$Revision: 1.2 $";
-#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args);
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -145,11 +130,10 @@ static int airo_probe(struct pcmcia_device *p_dev)
{
local_info_t *local;
- DEBUG(0, "airo_attach()\n");
+ dev_dbg(&p_dev->dev, "airo_attach()\n");
/* Interrupt setup */
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
p_dev->irq.Handler = NULL;
/*
@@ -184,7 +168,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
static void airo_detach(struct pcmcia_device *link)
{
- DEBUG(0, "airo_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "airo_detach\n");
airo_release(link);
@@ -204,9 +188,6 @@ static void airo_detach(struct pcmcia_device *link)
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int airo_cs_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
@@ -275,11 +256,11 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
req->Base = mem->win[0].host_addr;
req->Size = mem->win[0].len;
req->AccessSpeed = 0;
- if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
+ if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
return -ENODEV;
map.Page = 0;
map.CardOffset = mem->win[0].card_addr;
- if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+ if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
return -ENODEV;
}
/* If we got this far, we're cool! */
@@ -291,11 +272,11 @@ static int airo_config(struct pcmcia_device *link)
{
local_info_t *dev;
win_req_t *req;
- int last_fn, last_ret;
+ int ret;
dev = link->priv;
- DEBUG(0, "airo_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "airo_config\n");
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
if (!req)
@@ -315,8 +296,8 @@ static int airo_config(struct pcmcia_device *link)
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
- last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
- if (last_ret)
+ ret = pcmcia_loop_config(link, airo_cs_config_check, req);
+ if (ret)
goto failed;
/*
@@ -324,21 +305,25 @@ static int airo_config(struct pcmcia_device *link)
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
- if (link->conf.Attributes & CONF_ENABLE_IRQ)
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ }
/*
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- CS_CHECK(RequestConfiguration,
- pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
((local_info_t *)link->priv)->eth_dev =
init_airo_card(link->irq.AssignedIRQ,
- link->io.BasePort1, 1, &handle_to_dev(link));
+ link->io.BasePort1, 1, &link->dev);
if (!((local_info_t *)link->priv)->eth_dev)
- goto cs_failed;
+ goto failed;
/*
At this point, the dev_node_t structure(s) need to be
@@ -368,8 +353,6 @@ static int airo_config(struct pcmcia_device *link)
kfree(req);
return 0;
- cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
airo_release(link);
kfree(req);
@@ -386,7 +369,7 @@ static int airo_config(struct pcmcia_device *link)
static void airo_release(struct pcmcia_device *link)
{
- DEBUG(0, "airo_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "airo_release\n");
pcmcia_disable_device(link);
}
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 9c6ab5378f6e..95a8e232b58f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1125,7 +1125,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
/* configure operational mode */
ath5k_hw_set_opmode(ah);
- ath5k_hw_set_mcast_filter(ah, 0, 0);
ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
}
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index b767c3b67b24..b548c8eaaae1 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -63,12 +63,16 @@ static const struct pci_device_id ath5k_led_devices[] = {
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
/* E-machines E510 (tuliom@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
+ /* BenQ Joybook R55v (nowymarluk@wp.pl) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0100), ATH_LED(1, 0) },
/* Acer Extensa 5620z (nekoreeve@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
/* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */
{ ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) },
/* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */
{ ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) },
+ /* HP Compaq CQ60-206US (ddreggors@jumptv.com) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
/* HP Compaq C700 (nitrousnrg@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
/* IBM-specific AR5212 (all others) */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 52bed89063d4..43d2be9867fc 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1555,6 +1555,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
+ hw->wiphy->ps_default = false;
+
hw->queues = 4;
hw->max_rates = 4;
hw->channel_change_time = 5000;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 16a271787b85..1895d63aad0a 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -679,7 +679,7 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
return rate;
if (rate_table->info[rate].valid_single_stream &&
- !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG));
+ !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
return rate;
/* This should not happen */
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index ddaa859c3491..32407911842f 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -55,22 +55,6 @@
#include "atmel.h"
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-static char *version = "$Revision: 1.2 $";
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -155,11 +139,10 @@ static int atmel_probe(struct pcmcia_device *p_dev)
{
local_info_t *local;
- DEBUG(0, "atmel_attach()\n");
+ dev_dbg(&p_dev->dev, "atmel_attach()\n");
/* Interrupt setup */
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
p_dev->irq.Handler = NULL;
/*
@@ -194,7 +177,7 @@ static int atmel_probe(struct pcmcia_device *p_dev)
static void atmel_detach(struct pcmcia_device *link)
{
- DEBUG(0, "atmel_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "atmel_detach\n");
atmel_release(link);
@@ -209,9 +192,6 @@ static void atmel_detach(struct pcmcia_device *link)
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
/* Call-back function to interrogate PCMCIA-specific information
about the current existance of the card */
static int card_present(void *arg)
@@ -275,13 +255,13 @@ static int atmel_config_check(struct pcmcia_device *p_dev,
static int atmel_config(struct pcmcia_device *link)
{
local_info_t *dev;
- int last_fn, last_ret;
+ int ret;
struct pcmcia_device_id *did;
dev = link->priv;
- did = dev_get_drvdata(&handle_to_dev(link));
+ did = dev_get_drvdata(&link->dev);
- DEBUG(0, "atmel_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "atmel_config\n");
/*
In this loop, we scan the CIS for configuration table entries,
@@ -303,31 +283,36 @@ static int atmel_config(struct pcmcia_device *link)
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
- if (link->conf.Attributes & CONF_ENABLE_IRQ)
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ }
/*
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
if (link->irq.AssignedIRQ == 0) {
printk(KERN_ALERT
"atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
- goto cs_failed;
+ goto failed;
}
((local_info_t*)link->priv)->eth_dev =
init_atmel_card(link->irq.AssignedIRQ,
link->io.BasePort1,
did ? did->driver_info : ATMEL_FW_TYPE_NONE,
- &handle_to_dev(link),
+ &link->dev,
card_present,
link);
if (!((local_info_t*)link->priv)->eth_dev)
- goto cs_failed;
+ goto failed;
/*
@@ -340,8 +325,6 @@ static int atmel_config(struct pcmcia_device *link)
return 0;
- cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
atmel_release(link);
return -ENODEV;
@@ -359,7 +342,7 @@ static void atmel_release(struct pcmcia_device *link)
{
struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
- DEBUG(0, "atmel_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "atmel_release\n");
if (dev)
stop_atmel_card(dev);
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index fa1549a03c71..660716214d49 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -607,82 +607,7 @@ struct b43_qos_params {
struct ieee80211_tx_queue_params p;
};
-struct b43_wldev;
-
-/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
-struct b43_wl {
- /* Pointer to the active wireless device on this chip */
- struct b43_wldev *current_dev;
- /* Pointer to the ieee80211 hardware data structure */
- struct ieee80211_hw *hw;
-
- /* Global driver mutex. Every operation must run with this mutex locked. */
- struct mutex mutex;
- /* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
- * handler, only. This basically is just the IRQ mask register. */
- spinlock_t hardirq_lock;
-
- /* The number of queues that were registered with the mac80211 subsystem
- * initially. This is a backup copy of hw->queues in case hw->queues has
- * to be dynamically lowered at runtime (Firmware does not support QoS).
- * hw->queues has to be restored to the original value before unregistering
- * from the mac80211 subsystem. */
- u16 mac80211_initially_registered_queues;
-
- /* We can only have one operating interface (802.11 core)
- * at a time. General information about this interface follows.
- */
-
- struct ieee80211_vif *vif;
- /* The MAC address of the operating interface. */
- u8 mac_addr[ETH_ALEN];
- /* Current BSSID */
- u8 bssid[ETH_ALEN];
- /* Interface type. (NL80211_IFTYPE_XXX) */
- int if_type;
- /* Is the card operating in AP, STA or IBSS mode? */
- bool operating;
- /* filter flags */
- unsigned int filter_flags;
- /* Stats about the wireless interface */
- struct ieee80211_low_level_stats ieee_stats;
-
-#ifdef CONFIG_B43_HWRNG
- struct hwrng rng;
- bool rng_initialized;
- char rng_name[30 + 1];
-#endif /* CONFIG_B43_HWRNG */
-
- /* List of all wireless devices on this chip */
- struct list_head devlist;
- u8 nr_devs;
-
- bool radiotap_enabled;
- bool radio_enabled;
-
- /* The beacon we are currently using (AP or IBSS mode). */
- struct sk_buff *current_beacon;
- bool beacon0_uploaded;
- bool beacon1_uploaded;
- bool beacon_templates_virgin; /* Never wrote the templates? */
- struct work_struct beacon_update_trigger;
-
- /* The current QOS parameters for the 4 queues. */
- struct b43_qos_params qos_params[4];
-
- /* Work for adjustment of the transmission power.
- * This is scheduled when we determine that the actual TX output
- * power doesn't match what we want. */
- struct work_struct txpower_adjust_work;
-
- /* Packet transmit work */
- struct work_struct tx_work;
- /* Queue of packets to be transmitted. */
- struct sk_buff_head tx_queue;
-
- /* The device LEDs. */
- struct b43_leds leds;
-};
+struct b43_wl;
/* The type of the firmware file. */
enum b43_firmware_file_type {
@@ -824,6 +749,97 @@ struct b43_wldev {
#endif
};
+/*
+ * Include goes here to avoid a dependency problem.
+ * A better fix would be to integrate xmit.h into b43.h.
+ */
+#include "xmit.h"
+
+/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
+struct b43_wl {
+ /* Pointer to the active wireless device on this chip */
+ struct b43_wldev *current_dev;
+ /* Pointer to the ieee80211 hardware data structure */
+ struct ieee80211_hw *hw;
+
+ /* Global driver mutex. Every operation must run with this mutex locked. */
+ struct mutex mutex;
+ /* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
+ * handler, only. This basically is just the IRQ mask register. */
+ spinlock_t hardirq_lock;
+
+ /* The number of queues that were registered with the mac80211 subsystem
+ * initially. This is a backup copy of hw->queues in case hw->queues has
+ * to be dynamically lowered at runtime (Firmware does not support QoS).
+ * hw->queues has to be restored to the original value before unregistering
+ * from the mac80211 subsystem. */
+ u16 mac80211_initially_registered_queues;
+
+ /* We can only have one operating interface (802.11 core)
+ * at a time. General information about this interface follows.
+ */
+
+ struct ieee80211_vif *vif;
+ /* The MAC address of the operating interface. */
+ u8 mac_addr[ETH_ALEN];
+ /* Current BSSID */
+ u8 bssid[ETH_ALEN];
+ /* Interface type. (NL80211_IFTYPE_XXX) */
+ int if_type;
+ /* Is the card operating in AP, STA or IBSS mode? */
+ bool operating;
+ /* filter flags */
+ unsigned int filter_flags;
+ /* Stats about the wireless interface */
+ struct ieee80211_low_level_stats ieee_stats;
+
+#ifdef CONFIG_B43_HWRNG
+ struct hwrng rng;
+ bool rng_initialized;
+ char rng_name[30 + 1];
+#endif /* CONFIG_B43_HWRNG */
+
+ /* List of all wireless devices on this chip */
+ struct list_head devlist;
+ u8 nr_devs;
+
+ bool radiotap_enabled;
+ bool radio_enabled;
+
+ /* The beacon we are currently using (AP or IBSS mode). */
+ struct sk_buff *current_beacon;
+ bool beacon0_uploaded;
+ bool beacon1_uploaded;
+ bool beacon_templates_virgin; /* Never wrote the templates? */
+ struct work_struct beacon_update_trigger;
+
+ /* The current QOS parameters for the 4 queues. */
+ struct b43_qos_params qos_params[4];
+
+ /* Work for adjustment of the transmission power.
+ * This is scheduled when we determine that the actual TX output
+ * power doesn't match what we want. */
+ struct work_struct txpower_adjust_work;
+
+ /* Packet transmit work */
+ struct work_struct tx_work;
+ /* Queue of packets to be transmitted. */
+ struct sk_buff_head tx_queue;
+
+ /* The device LEDs. */
+ struct b43_leds leds;
+
+#ifdef CONFIG_B43_PIO
+ /*
+ * RX/TX header/tail buffers used by the frame transmit functions.
+ */
+ struct b43_rxhdr_fw4 rxhdr;
+ struct b43_txhdr txhdr;
+ u8 rx_tail[4];
+ u8 tx_tail[4];
+#endif /* CONFIG_B43_PIO */
+};
+
static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
{
return hw->priv;
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 8701034569fa..de4e804bedf0 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1157,8 +1157,9 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot)
}
static int dma_tx_fragment(struct b43_dmaring *ring,
- struct sk_buff *skb)
+ struct sk_buff **in_skb)
{
+ struct sk_buff *skb = *in_skb;
const struct b43_dma_ops *ops = ring->ops;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
u8 *header;
@@ -1224,8 +1225,14 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
}
memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
+ memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb));
+ bounce_skb->dev = skb->dev;
+ skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb));
+ info = IEEE80211_SKB_CB(bounce_skb);
+
dev_kfree_skb_any(skb);
skb = bounce_skb;
+ *in_skb = bounce_skb;
meta->skb = skb;
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
@@ -1355,7 +1362,11 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
* static, so we don't need to store it per frame. */
ring->queue_prio = skb_get_queue_mapping(skb);
- err = dma_tx_fragment(ring, skb);
+ /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing
+ * into the skb data or cb now. */
+ hdr = NULL;
+ info = NULL;
+ err = dma_tx_fragment(ring, &skb);
if (unlikely(err == -ENOKEY)) {
/* Drop this packet, as we don't have the encryption key
* anymore and must not transmit it unencrypted. */
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index fbe3d4f62ce2..1e8dba488004 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -348,9 +348,9 @@ void b43_leds_register(struct b43_wldev *dev)
}
}
-void b43_leds_unregister(struct b43_wldev *dev)
+void b43_leds_unregister(struct b43_wl *wl)
{
- struct b43_leds *leds = &dev->wl->leds;
+ struct b43_leds *leds = &wl->leds;
b43_unregister_led(&leds->led_tx);
b43_unregister_led(&leds->led_rx);
diff --git a/drivers/net/wireless/b43/leds.h b/drivers/net/wireless/b43/leds.h
index 9592e4c5a5f5..32b66d53cdac 100644
--- a/drivers/net/wireless/b43/leds.h
+++ b/drivers/net/wireless/b43/leds.h
@@ -1,6 +1,7 @@
#ifndef B43_LEDS_H_
#define B43_LEDS_H_
+struct b43_wl;
struct b43_wldev;
#ifdef CONFIG_B43_LEDS
@@ -60,7 +61,7 @@ enum b43_led_behaviour {
};
void b43_leds_register(struct b43_wldev *dev);
-void b43_leds_unregister(struct b43_wldev *dev);
+void b43_leds_unregister(struct b43_wl *wl);
void b43_leds_init(struct b43_wldev *dev);
void b43_leds_exit(struct b43_wldev *dev);
void b43_leds_stop(struct b43_wldev *dev);
@@ -76,7 +77,7 @@ struct b43_leds {
static inline void b43_leds_register(struct b43_wldev *dev)
{
}
-static inline void b43_leds_unregister(struct b43_wldev *dev)
+static inline void b43_leds_unregister(struct b43_wl *wl)
{
}
static inline void b43_leds_init(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9b907a36bb8c..098dda1a67c1 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3874,6 +3874,7 @@ static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
struct b43_wldev *orig_dev;
+ u32 mask;
redo:
if (!dev || b43_status(dev) < B43_STAT_STARTED)
@@ -3920,7 +3921,8 @@ redo:
goto redo;
return dev;
}
- B43_WARN_ON(b43_read32(dev, B43_MMIO_GEN_IRQ_MASK));
+ mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
+ B43_WARN_ON(mask != 0xFFFFFFFF && mask);
/* Drain the TX queue */
while (skb_queue_len(&wl->tx_queue))
@@ -4519,9 +4521,8 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
{
struct b43_wl *wl = hw_to_b43_wl(hw);
- mutex_lock(&wl->mutex);
+ /* FIXME: add locking */
b43_update_templates(wl);
- mutex_unlock(&wl->mutex);
return 0;
}
@@ -4997,7 +4998,7 @@ static void b43_remove(struct ssb_device *dev)
if (list_empty(&wl->devlist)) {
b43_rng_exit(wl);
- b43_leds_unregister(wldev);
+ b43_leds_unregister(wl);
/* Last core on the chip unregistered.
* We can destroy common struct b43_wl.
*/
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
index 6c3a74964ab8..984174bc7b0f 100644
--- a/drivers/net/wireless/b43/pcmcia.c
+++ b/drivers/net/wireless/b43/pcmcia.c
@@ -65,35 +65,15 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
struct ssb_bus *ssb;
win_req_t win;
memreq_t mem;
- tuple_t tuple;
- cisparse_t parse;
int err = -ENOMEM;
int res = 0;
- unsigned char buf[64];
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
if (!ssb)
goto out_error;
err = -ENODEV;
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- res = pcmcia_get_first_tuple(dev, &tuple);
- if (res != 0)
- goto err_kfree_ssb;
- res = pcmcia_get_tuple_data(dev, &tuple);
- if (res != 0)
- goto err_kfree_ssb;
- res = pcmcia_parse_tuple(&tuple, &parse);
- if (res != 0)
- goto err_kfree_ssb;
-
- dev->conf.ConfigBase = parse.config.base;
- dev->conf.Present = parse.config.rmask[0];
dev->conf.Attributes = CONF_ENABLE_IRQ;
dev->conf.IntType = INT_MEMORY_AND_IO;
@@ -107,20 +87,18 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
win.Base = 0;
win.Size = SSB_CORE_SIZE;
win.AccessSpeed = 250;
- res = pcmcia_request_window(&dev, &win, &dev->win);
+ res = pcmcia_request_window(dev, &win, &dev->win);
if (res != 0)
goto err_kfree_ssb;
mem.CardOffset = 0;
mem.Page = 0;
- res = pcmcia_map_mem_page(dev->win, &mem);
+ res = pcmcia_map_mem_page(dev, dev->win, &mem);
if (res != 0)
goto err_disable;
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
dev->irq.Handler = NULL; /* The handler is registered later. */
- dev->irq.Instance = NULL;
res = pcmcia_request_irq(dev, &dev->irq);
if (res != 0)
goto err_disable;
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 5e87650b07fb..9b9044400218 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -332,6 +332,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
unsigned int data_len)
{
struct b43_wldev *dev = q->dev;
+ struct b43_wl *wl = dev->wl;
const u8 *data = _data;
ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
@@ -341,13 +342,12 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
q->mmio_base + B43_PIO_TXDATA,
sizeof(u16));
if (data_len & 1) {
- u8 tail[2] = { 0, };
-
/* Write the last byte. */
ctl &= ~B43_PIO_TXCTL_WRITEHI;
b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
- tail[0] = data[data_len - 1];
- ssb_block_write(dev->dev, tail, 2,
+ wl->tx_tail[0] = data[data_len - 1];
+ wl->tx_tail[1] = 0;
+ ssb_block_write(dev->dev, wl->tx_tail, 2,
q->mmio_base + B43_PIO_TXDATA,
sizeof(u16));
}
@@ -382,6 +382,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
unsigned int data_len)
{
struct b43_wldev *dev = q->dev;
+ struct b43_wl *wl = dev->wl;
const u8 *data = _data;
ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 |
@@ -392,29 +393,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
q->mmio_base + B43_PIO8_TXDATA,
sizeof(u32));
if (data_len & 3) {
- u8 tail[4] = { 0, };
-
+ wl->tx_tail[3] = 0;
/* Write the last few bytes. */
ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
B43_PIO8_TXCTL_24_31);
switch (data_len & 3) {
case 3:
ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
- tail[0] = data[data_len - 3];
- tail[1] = data[data_len - 2];
- tail[2] = data[data_len - 1];
+ wl->tx_tail[0] = data[data_len - 3];
+ wl->tx_tail[1] = data[data_len - 2];
+ wl->tx_tail[2] = data[data_len - 1];
break;
case 2:
ctl |= B43_PIO8_TXCTL_8_15;
- tail[0] = data[data_len - 2];
- tail[1] = data[data_len - 1];
+ wl->tx_tail[0] = data[data_len - 2];
+ wl->tx_tail[1] = data[data_len - 1];
+ wl->tx_tail[2] = 0;
break;
case 1:
- tail[0] = data[data_len - 1];
+ wl->tx_tail[0] = data[data_len - 1];
+ wl->tx_tail[1] = 0;
+ wl->tx_tail[2] = 0;
break;
}
b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
- ssb_block_write(dev->dev, tail, 4,
+ ssb_block_write(dev->dev, wl->tx_tail, 4,
q->mmio_base + B43_PIO8_TXDATA,
sizeof(u32));
}
@@ -446,8 +449,9 @@ static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
static int pio_tx_frame(struct b43_pio_txqueue *q,
struct sk_buff *skb)
{
+ struct b43_wldev *dev = q->dev;
+ struct b43_wl *wl = dev->wl;
struct b43_pio_txpacket *pack;
- struct b43_txhdr txhdr;
u16 cookie;
int err;
unsigned int hdrlen;
@@ -458,8 +462,8 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
struct b43_pio_txpacket, list);
cookie = generate_cookie(q, pack);
- hdrlen = b43_txhdr_size(q->dev);
- err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb,
+ hdrlen = b43_txhdr_size(dev);
+ err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb,
info, cookie);
if (err)
return err;
@@ -467,15 +471,15 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
/* Tell the firmware about the cookie of the last
* mcast frame, so it can clear the more-data bit in it. */
- b43_shm_write16(q->dev, B43_SHM_SHARED,
+ b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_MCASTCOOKIE, cookie);
}
pack->skb = skb;
if (q->rev >= 8)
- pio_tx_frame_4byte_queue(pack, (const u8 *)&txhdr, hdrlen);
+ pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
else
- pio_tx_frame_2byte_queue(pack, (const u8 *)&txhdr, hdrlen);
+ pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
/* Remove it from the list of available packet slots.
* It will be put back when we receive the status report. */
@@ -615,14 +619,14 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
static bool pio_rx_frame(struct b43_pio_rxqueue *q)
{
struct b43_wldev *dev = q->dev;
- struct b43_rxhdr_fw4 rxhdr;
+ struct b43_wl *wl = dev->wl;
u16 len;
u32 macstat;
unsigned int i, padding;
struct sk_buff *skb;
const char *err_msg = NULL;
- memset(&rxhdr, 0, sizeof(rxhdr));
+ memset(&wl->rxhdr, 0, sizeof(wl->rxhdr));
/* Check if we have data and wait for it to get ready. */
if (q->rev >= 8) {
@@ -660,16 +664,16 @@ data_ready:
/* Get the preamble (RX header) */
if (q->rev >= 8) {
- ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr),
+ ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
q->mmio_base + B43_PIO8_RXDATA,
sizeof(u32));
} else {
- ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr),
+ ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
q->mmio_base + B43_PIO_RXDATA,
sizeof(u16));
}
/* Sanity checks. */
- len = le16_to_cpu(rxhdr.frame_len);
+ len = le16_to_cpu(wl->rxhdr.frame_len);
if (unlikely(len > 0x700)) {
err_msg = "len > 0x700";
goto rx_error;
@@ -679,7 +683,7 @@ data_ready:
goto rx_error;
}
- macstat = le32_to_cpu(rxhdr.mac_status);
+ macstat = le32_to_cpu(wl->rxhdr.mac_status);
if (macstat & B43_RX_MAC_FCSERR) {
if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
/* Drop frames with failed FCS. */
@@ -704,24 +708,22 @@ data_ready:
q->mmio_base + B43_PIO8_RXDATA,
sizeof(u32));
if (len & 3) {
- u8 tail[4] = { 0, };
-
/* Read the last few bytes. */
- ssb_block_read(dev->dev, tail, 4,
+ ssb_block_read(dev->dev, wl->rx_tail, 4,
q->mmio_base + B43_PIO8_RXDATA,
sizeof(u32));
switch (len & 3) {
case 3:
- skb->data[len + padding - 3] = tail[0];
- skb->data[len + padding - 2] = tail[1];
- skb->data[len + padding - 1] = tail[2];
+ skb->data[len + padding - 3] = wl->rx_tail[0];
+ skb->data[len + padding - 2] = wl->rx_tail[1];
+ skb->data[len + padding - 1] = wl->rx_tail[2];
break;
case 2:
- skb->data[len + padding - 2] = tail[0];
- skb->data[len + padding - 1] = tail[1];
+ skb->data[len + padding - 2] = wl->rx_tail[0];
+ skb->data[len + padding - 1] = wl->rx_tail[1];
break;
case 1:
- skb->data[len + padding - 1] = tail[0];
+ skb->data[len + padding - 1] = wl->rx_tail[0];
break;
}
}
@@ -730,17 +732,15 @@ data_ready:
q->mmio_base + B43_PIO_RXDATA,
sizeof(u16));
if (len & 1) {
- u8 tail[2] = { 0, };
-
/* Read the last byte. */
- ssb_block_read(dev->dev, tail, 2,
+ ssb_block_read(dev->dev, wl->rx_tail, 2,
q->mmio_base + B43_PIO_RXDATA,
sizeof(u16));
- skb->data[len + padding - 1] = tail[0];
+ skb->data[len + padding - 1] = wl->rx_tail[0];
}
}
- b43_rx(q->dev, skb, &rxhdr);
+ b43_rx(q->dev, skb, &wl->rxhdr);
return 1;
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 7a3218c5ba7d..ffdce6f3c909 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -33,7 +33,8 @@ bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
& B43_MMIO_RADIO_HWENABLED_HI_MASK))
return 1;
} else {
- if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
+ if (b43_status(dev) >= B43_STAT_STARTED &&
+ b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
& B43_MMIO_RADIO_HWENABLED_LO_MASK)
return 1;
}
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index ac9f600995e4..f4e9695ec186 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -27,7 +27,7 @@
*/
-#include "xmit.h"
+#include "b43.h"
#include "phy_common.h"
#include "dma.h"
#include "pio.h"
@@ -690,7 +690,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
}
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+
+ local_bh_disable();
ieee80211_rx(dev->wl->hw, skb);
+ local_bh_enable();
#if B43_DEBUG
dev->rx_count++;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index ad8eab4a639b..c9640a3e02c9 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -274,9 +274,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
conf_reg_t reg;
struct hostap_interface *iface = netdev_priv(dev);
local_info_t *local = iface->local;
- tuple_t tuple;
- cisparse_t *parse = NULL;
- u_char buf[64];
struct hostap_cs_priv *hw_priv = local->hw_priv;
if (hw_priv->link->io.NumPorts1 < 0x42) {
@@ -285,28 +282,13 @@ static int sandisk_enable_wireless(struct net_device *dev)
goto done;
}
- parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
- if (parse == NULL) {
- ret = -ENOMEM;
- goto done;
- }
-
- tuple.Attributes = TUPLE_RETURN_COMMON;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) {
/* No SanDisk manfid found */
ret = -ENODEV;
goto done;
}
- tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
- if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
- pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
- pcmcia_parse_tuple(&tuple, parse) ||
- parse->longlink_mfc.nfn < 2) {
+ if (hw_priv->link->socket->functions < 2) {
/* No multi-function links found */
ret = -ENODEV;
goto done;
@@ -354,7 +336,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
udelay(10);
done:
- kfree(parse);
return ret;
}
@@ -529,10 +510,6 @@ static void prism2_detach(struct pcmcia_device *link)
}
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
-
/* run after a CARD_INSERTION event is received to configure the PCMCIA
* socket and make the device available to the system */
@@ -624,7 +601,6 @@ static int prism2_config(struct pcmcia_device *link)
struct hostap_interface *iface;
local_info_t *local;
int ret = 1;
- int last_fn, last_ret;
struct hostap_cs_priv *hw_priv;
PDEBUG(DEBUG_FLOW, "prism2_config()\n");
@@ -636,19 +612,18 @@ static int prism2_config(struct pcmcia_device *link)
}
/* Look for an appropriate configuration table entry in the CIS */
- last_ret = pcmcia_loop_config(link, prism2_config_check, NULL);
- if (last_ret) {
+ ret = pcmcia_loop_config(link, prism2_config_check, NULL);
+ if (ret) {
if (!ignore_cis_vcc)
printk(KERN_ERR "GetNextTuple(): No matching "
"CIS configuration. Maybe you need the "
"ignore_cis_vcc=1 parameter.\n");
- cs_error(link, RequestIO, last_ret);
goto failed;
}
/* Need to allocate net_device before requesting IRQ handler */
dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
- &handle_to_dev(link));
+ &link->dev);
if (dev == NULL)
goto failed;
link->priv = dev;
@@ -666,13 +641,11 @@ static int prism2_config(struct pcmcia_device *link)
* irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING |
- IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = prism2_interrupt;
- link->irq.Instance = dev;
- CS_CHECK(RequestIRQ,
- pcmcia_request_irq(link, &link->irq));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
}
/*
@@ -680,8 +653,9 @@ static int prism2_config(struct pcmcia_device *link)
* the I/O windows and the interrupt mapping, and putting the
* card and host interface into "Memory and IO" mode.
*/
- CS_CHECK(RequestConfiguration,
- pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
@@ -714,9 +688,6 @@ static int prism2_config(struct pcmcia_device *link)
}
return ret;
- cs_failed:
- cs_error(link, last_fn, last_ret);
-
failed:
kfree(hw_priv);
prism2_release((u_long)link);
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 240cff1e6979..6e2fc0cb6f8a 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -6029,7 +6029,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
struct ipw2100_priv *priv;
struct net_device *dev;
- dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0);
+ dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
if (!dev)
return NULL;
priv = libipw_priv(dev);
@@ -6342,7 +6342,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
sysfs_remove_group(&pci_dev->dev.kobj,
&ipw2100_attribute_group);
- free_ieee80211(dev, 0);
+ free_ieee80211(dev);
pci_set_drvdata(pci_dev, NULL);
}
@@ -6400,7 +6400,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
if (dev->base_addr)
iounmap((void __iomem *)dev->base_addr);
- free_ieee80211(dev, 0);
+ free_ieee80211(dev);
}
pci_release_regions(pci_dev);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 827824d45de9..a6ca536e44f8 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -104,25 +104,6 @@ static int antenna = CFG_SYS_ANTENNA_BOTH;
static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */
#endif
-static struct ieee80211_rate ipw2200_rates[] = {
- { .bitrate = 10 },
- { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
- { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
- { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
- { .bitrate = 60 },
- { .bitrate = 90 },
- { .bitrate = 120 },
- { .bitrate = 180 },
- { .bitrate = 240 },
- { .bitrate = 360 },
- { .bitrate = 480 },
- { .bitrate = 540 }
-};
-
-#define ipw2200_a_rates (ipw2200_rates + 4)
-#define ipw2200_num_a_rates 8
-#define ipw2200_bg_rates (ipw2200_rates + 0)
-#define ipw2200_num_bg_rates 12
#ifdef CONFIG_IPW2200_QOS
static int qos_enable = 0;
@@ -8674,6 +8655,24 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
*
*/
+static int ipw_wx_get_name(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = libipw_priv(dev);
+ mutex_lock(&priv->mutex);
+ if (priv->status & STATUS_RF_KILL_MASK)
+ strcpy(wrqu->name, "radio off");
+ else if (!(priv->status & STATUS_ASSOCIATED))
+ strcpy(wrqu->name, "unassociated");
+ else
+ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
+ ipw_modes[priv->assoc_request.ieee_mode]);
+ IPW_DEBUG_WX("Name: %s\n", wrqu->name);
+ mutex_unlock(&priv->mutex);
+ return 0;
+}
+
static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
{
if (channel == 0) {
@@ -9973,7 +9972,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
/* Rebase the WE IOCTLs to zero for the handler array */
#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
static iw_handler ipw_wx_handlers[] = {
- IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
+ IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
@@ -11417,100 +11416,16 @@ static void ipw_bg_down(struct work_struct *work)
/* Called by register_netdev() */
static int ipw_net_init(struct net_device *dev)
{
- int i, rc = 0;
struct ipw_priv *priv = libipw_priv(dev);
- const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
- struct wireless_dev *wdev = &priv->ieee->wdev;
mutex_lock(&priv->mutex);
if (ipw_up(priv)) {
- rc = -EIO;
- goto out;
- }
-
- memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
-
- /* fill-out priv->ieee->bg_band */
- if (geo->bg_channels) {
- struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
-
- bg_band->band = IEEE80211_BAND_2GHZ;
- bg_band->n_channels = geo->bg_channels;
- bg_band->channels =
- kzalloc(geo->bg_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
- /* translate geo->bg to bg_band.channels */
- for (i = 0; i < geo->bg_channels; i++) {
- bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
- bg_band->channels[i].center_freq = geo->bg[i].freq;
- bg_band->channels[i].hw_value = geo->bg[i].channel;
- bg_band->channels[i].max_power = geo->bg[i].max_power;
- if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
- bg_band->channels[i].flags |=
- IEEE80211_CHAN_PASSIVE_SCAN;
- if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
- bg_band->channels[i].flags |=
- IEEE80211_CHAN_NO_IBSS;
- if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
- bg_band->channels[i].flags |=
- IEEE80211_CHAN_RADAR;
- /* No equivalent for LIBIPW_CH_80211H_RULES,
- LIBIPW_CH_UNIFORM_SPREADING, or
- LIBIPW_CH_B_ONLY... */
- }
- /* point at bitrate info */
- bg_band->bitrates = ipw2200_bg_rates;
- bg_band->n_bitrates = ipw2200_num_bg_rates;
-
- wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
- }
-
- /* fill-out priv->ieee->a_band */
- if (geo->a_channels) {
- struct ieee80211_supported_band *a_band = &priv->ieee->a_band;
-
- a_band->band = IEEE80211_BAND_5GHZ;
- a_band->n_channels = geo->a_channels;
- a_band->channels =
- kzalloc(geo->a_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
- /* translate geo->bg to a_band.channels */
- for (i = 0; i < geo->a_channels; i++) {
- a_band->channels[i].band = IEEE80211_BAND_2GHZ;
- a_band->channels[i].center_freq = geo->a[i].freq;
- a_band->channels[i].hw_value = geo->a[i].channel;
- a_band->channels[i].max_power = geo->a[i].max_power;
- if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
- a_band->channels[i].flags |=
- IEEE80211_CHAN_PASSIVE_SCAN;
- if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
- a_band->channels[i].flags |=
- IEEE80211_CHAN_NO_IBSS;
- if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
- a_band->channels[i].flags |=
- IEEE80211_CHAN_RADAR;
- /* No equivalent for LIBIPW_CH_80211H_RULES,
- LIBIPW_CH_UNIFORM_SPREADING, or
- LIBIPW_CH_B_ONLY... */
- }
- /* point at bitrate info */
- a_band->bitrates = ipw2200_a_rates;
- a_band->n_bitrates = ipw2200_num_a_rates;
-
- wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
- }
-
- set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
-
- /* With that information in place, we can now register the wiphy... */
- if (wiphy_register(wdev->wiphy)) {
- rc = -EIO;
- goto out;
+ mutex_unlock(&priv->mutex);
+ return -EIO;
}
-out:
mutex_unlock(&priv->mutex);
- return rc;
+ return 0;
}
/* PCI driver stuff */
@@ -11641,7 +11556,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
if (priv->prom_net_dev)
return -EPERM;
- priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1);
+ priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv));
if (priv->prom_net_dev == NULL)
return -ENOMEM;
@@ -11660,7 +11575,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
rc = register_netdev(priv->prom_net_dev);
if (rc) {
- free_ieee80211(priv->prom_net_dev, 1);
+ free_ieee80211(priv->prom_net_dev);
priv->prom_net_dev = NULL;
return rc;
}
@@ -11674,7 +11589,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
return;
unregister_netdev(priv->prom_net_dev);
- free_ieee80211(priv->prom_net_dev, 1);
+ free_ieee80211(priv->prom_net_dev);
priv->prom_net_dev = NULL;
}
@@ -11702,7 +11617,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
struct ipw_priv *priv;
int i;
- net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0);
+ net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
if (net_dev == NULL) {
err = -ENOMEM;
goto out;
@@ -11850,7 +11765,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
out_free_ieee80211:
- free_ieee80211(priv->net_dev, 0);
+ free_ieee80211(priv->net_dev);
out:
return err;
}
@@ -11917,7 +11832,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
- free_ieee80211(priv->net_dev, 0);
+ free_ieee80211(priv->net_dev);
free_firmware();
}
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index bf45391172f3..1e334ff6bd52 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -31,7 +31,6 @@
#include <linux/ieee80211.h>
#include <net/lib80211.h>
-#include <net/cfg80211.h>
#define LIBIPW_VERSION "git-1.1.13"
@@ -784,15 +783,12 @@ struct libipw_geo {
struct libipw_device {
struct net_device *dev;
- struct wireless_dev wdev;
struct libipw_security sec;
/* Bookkeeping structures */
struct libipw_stats ieee_stats;
struct libipw_geo geo;
- struct ieee80211_supported_band bg_band;
- struct ieee80211_supported_band a_band;
/* Probe / Beacon management */
struct list_head network_free_list;
@@ -1018,8 +1014,8 @@ static inline int libipw_is_cck_rate(u8 rate)
}
/* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev, int monitor);
-extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor);
+extern void free_ieee80211(struct net_device *dev);
+extern struct net_device *alloc_ieee80211(int sizeof_priv);
extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
extern void libipw_networks_age(struct libipw_device *ieee,
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index a0e9f6aed7da..eb2b60834c17 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -62,9 +62,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL");
-struct cfg80211_ops libipw_config_ops = { };
-void *libipw_wiphy_privid = &libipw_wiphy_privid;
-
static int libipw_networks_allocate(struct libipw_device *ieee)
{
if (ieee->networks)
@@ -143,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu)
}
EXPORT_SYMBOL(libipw_change_mtu);
-struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
+struct net_device *alloc_ieee80211(int sizeof_priv)
{
struct libipw_device *ieee;
struct net_device *dev;
@@ -160,31 +157,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
ieee->dev = dev;
- if (!monitor) {
- ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
- if (!ieee->wdev.wiphy) {
- LIBIPW_ERROR("Unable to allocate wiphy.\n");
- goto failed_free_netdev;
- }
-
- ieee->dev->ieee80211_ptr = &ieee->wdev;
- ieee->wdev.iftype = NL80211_IFTYPE_STATION;
-
- /* Fill-out wiphy structure bits we know... Not enough info
- here to call set_wiphy_dev or set MAC address or channel info
- -- have to do that in ->ndo_init... */
- ieee->wdev.wiphy->privid = libipw_wiphy_privid;
-
- ieee->wdev.wiphy->max_scan_ssids = 1;
- ieee->wdev.wiphy->max_scan_ie_len = 0;
- ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
- | BIT(NL80211_IFTYPE_ADHOC);
- }
-
err = libipw_networks_allocate(ieee);
if (err) {
LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
- goto failed_free_wiphy;
+ goto failed_free_netdev;
}
libipw_networks_initialize(ieee);
@@ -217,31 +193,19 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
return dev;
-failed_free_wiphy:
- if (!monitor)
- wiphy_free(ieee->wdev.wiphy);
failed_free_netdev:
free_netdev(dev);
failed:
return NULL;
}
-void free_ieee80211(struct net_device *dev, int monitor)
+void free_ieee80211(struct net_device *dev)
{
struct libipw_device *ieee = netdev_priv(dev);
lib80211_crypt_info_free(&ieee->crypt_info);
libipw_networks_free(ieee);
-
- /* free cfg80211 resources */
- if (!monitor) {
- wiphy_unregister(ieee->wdev.wiphy);
- kfree(ieee->a_band.channels);
- kfree(ieee->bg_band.channels);
- wiphy_free(ieee->wdev.wiphy);
- }
-
free_netdev(dev);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 2716b91ba9fa..950267ab556a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -161,5 +161,6 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
.shadow_ram_support = false,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index a16bd4147eac..cbb0585083a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -702,7 +702,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
u8 sta_id = iwl_find_station(priv, hdr->addr1);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
+ IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
hdr->addr1);
sta_id = iwl_add_station(priv, hdr->addr1, false,
CMD_ASYNC, NULL);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 68136172b823..f059b49dc691 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -611,7 +611,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
if (rx_status.band == IEEE80211_BAND_5GHZ)
rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
- rx_status.antenna = le16_to_cpu(rx_hdr->phy_flags &
+ rx_status.antenna = (le16_to_cpu(rx_hdr->phy_flags) &
RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
/* set the preamble flag if appropriate */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index d6bc0e051043..6e6f516ba404 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -318,7 +318,7 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
(s32)average_noise[i])) / 1500;
/* bound gain by 2 bits value max, 3rd bit is sign */
data->delta_gain_code[i] =
- min(abs(delta_g), CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
+ min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
if (delta_g < 0)
/* set negative sign */
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index c295b8ee9228..1473452ba22f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -175,6 +175,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
/*
@@ -198,6 +199,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
struct iwl_cfg iwl6050_2agn_cfg = {
@@ -218,6 +220,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
struct iwl_cfg iwl6000_3agn_cfg = {
@@ -238,6 +241,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
struct iwl_cfg iwl6050_3agn_cfg = {
@@ -258,6 +262,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 346dc06fa7b7..81726ee32858 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -418,6 +418,15 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
else if (tid == IWL_AGG_ALL_TID)
for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++)
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
+ if (priv->cfg->use_rts_for_ht) {
+ /*
+ * switch to RTS/CTS if it is the prefer protection method
+ * for HT traffic
+ */
+ IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
+ priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
+ iwlcore_commit_rxon(priv);
+ }
}
static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 313d3e5ee84b..921dc4a26fe2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -116,9 +116,6 @@ int iwl_commit_rxon(struct iwl_priv *priv)
/* always get timestamp with Rx frame */
priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
- /* allow CTS-to-self if possible. this is relevant only for
- * 5000, but will not damage 4965 */
- priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
ret = iwl_check_rxon_cmd(priv);
if (ret) {
@@ -218,6 +215,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
"Could not send WEP static key.\n");
}
+ /*
+ * allow CTS-to-self if possible for new association.
+ * this is relevant only for 5000 series and up,
+ * but will not damage 4965
+ */
+ priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
+
/* Apply the new configuration
* RXON assoc doesn't clear the station table in uCode,
*/
@@ -3106,8 +3110,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
out_pci_disable_device:
pci_disable_device(pdev);
out_ieee80211_free_hw:
- ieee80211_free_hw(priv->hw);
iwl_free_traffic_mem(priv);
+ ieee80211_free_hw(priv->hw);
out:
return err;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 2c5c88fc38f5..4afaf773aeac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1154,7 +1154,7 @@ struct iwl_wep_cmd {
#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
-#define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0)
+#define RX_RES_PHY_FLAGS_ANTENNA_MSK 0xf0
#define RX_RES_PHY_FLAGS_ANTENNA_POS 4
#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index e50103a956b1..7754538c2194 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -213,6 +213,7 @@ struct iwl_mod_params {
* @pa_type: used by 6000 series only to identify the type of Power Amplifier
* @max_ll_items: max number of OTP blocks
* @shadow_ram_support: shadow support for OTP memory
+ * @use_rts_for_ht: use rts/cts protection for HT traffic
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
@@ -255,6 +256,7 @@ struct iwl_cfg {
const bool shadow_ram_support;
const bool ht_greenfield_support;
const bool broken_powersave;
+ bool use_rts_for_ht;
};
/***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 3d2b93a61e62..e14c9952a935 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -410,7 +410,6 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
u16 *validblockaddr)
{
u16 next_link_addr = 0, link_value = 0, valid_addr;
- int ret = 0;
int usedblocks = 0;
/* set addressing mode to absolute to traverse the link list */
@@ -430,29 +429,29 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
* check for more block on the link list
*/
valid_addr = next_link_addr;
- next_link_addr = link_value;
+ next_link_addr = link_value * sizeof(u16);
IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
usedblocks, next_link_addr);
if (iwl_read_otp_word(priv, next_link_addr, &link_value))
return -EINVAL;
if (!link_value) {
/*
- * reach the end of link list,
+ * reach the end of link list, return success and
* set address point to the starting address
* of the image
*/
- goto done;
+ *validblockaddr = valid_addr;
+ /* skip first 2 bytes (link list pointer) */
+ *validblockaddr += 2;
+ return 0;
}
/* more in the link list, continue */
usedblocks++;
- } while (usedblocks < priv->cfg->max_ll_items);
- /* OTP full, use last block */
- IWL_DEBUG_INFO(priv, "OTP is full, use last block\n");
-done:
- *validblockaddr = valid_addr;
- /* skip first 2 bytes (link list pointer) */
- *validblockaddr += 2;
- return ret;
+ } while (usedblocks <= priv->cfg->max_ll_items);
+
+ /* OTP has no valid blocks */
+ IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
+ return -EINVAL;
}
/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 6b68db7b1b81..80b9e45d9b9c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -220,35 +220,35 @@ struct iwl_eeprom_enhanced_txpwr {
* Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_)
*/
/* 2.4 GHz band: CCK */
-#define EEPROM_LB_CCK_20_COMMON ((0xAA)\
+#define EEPROM_LB_CCK_20_COMMON ((0xA8)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 8 bytes */
/* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
-#define EEPROM_LB_OFDM_COMMON ((0xB2)\
+#define EEPROM_LB_OFDM_COMMON ((0xB0)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
/* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
-#define EEPROM_HB_OFDM_COMMON ((0xCA)\
+#define EEPROM_HB_OFDM_COMMON ((0xC8)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
/* 2.4GHz band channels:
* 1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */
-#define EEPROM_LB_OFDM_20_BAND ((0xE2)\
+#define EEPROM_LB_OFDM_20_BAND ((0xE0)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 64 bytes */
/* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */
-#define EEPROM_LB_OFDM_HT40_BAND ((0x122)\
+#define EEPROM_LB_OFDM_HT40_BAND ((0x120)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 40 bytes */
/* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */
-#define EEPROM_HB_OFDM_20_BAND ((0x14A)\
+#define EEPROM_HB_OFDM_20_BAND ((0x148)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 48 bytes */
/* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */
-#define EEPROM_HB_OFDM_HT40_BAND ((0x17A)\
+#define EEPROM_HB_OFDM_HT40_BAND ((0x178)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
/* 2.4 GHz band, channnel 13: Legacy, HT */
-#define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x192)\
+#define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x190)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
/* 5.2 GHz band, channnel 140: Legacy, HT */
-#define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A2)\
+#define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A0)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
/* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */
-#define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B2)\
+#define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B0)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 8e1bb53c0aa3..493626bcd3ec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1044,7 +1044,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
* as a bitmask.
*/
rx_status.antenna =
- le16_to_cpu(phy_res->phy_flags & RX_RES_PHY_FLAGS_ANTENNA_MSK)
+ (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
>> RX_RES_PHY_FLAGS_ANTENNA_POS;
/* set the preamble flag if appropriate */
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index fb9bcfa6d947..b7e196e3c8d3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1277,8 +1277,16 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
return -ENXIO;
}
+ if (priv->stations[sta_id].tid[tid].agg.state ==
+ IWL_EMPTYING_HW_QUEUE_ADDBA) {
+ IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
+ ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid);
+ priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
+ return 0;
+ }
+
if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
- IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n");
+ IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
tid_data = &priv->stations[sta_id].tid[tid];
ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index aa49230422f3..d00a80334095 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4097,8 +4097,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
out_ieee80211_free_hw:
- ieee80211_free_hw(priv->hw);
iwl_free_traffic_mem(priv);
+ ieee80211_free_hw(priv->hw);
out:
return err;
}
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index c42d3faa2660..23f684337fdd 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -3,6 +3,7 @@
* responses as well as events generated by firmware.
*/
#include <linux/delay.h>
+#include <linux/sched.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <asm/unaligned.h>
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 039b555e4d76..53d56ab83c03 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -169,16 +169,19 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
struct lbs_private *priv = dev->ml_priv;
uint32_t criteria = 0;
- if (priv->wol_criteria == 0xffffffff && wol->wolopts)
- return -EOPNOTSUPP;
-
if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
return -EOPNOTSUPP;
- if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA;
- if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA;
- if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
- if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT;
+ if (wol->wolopts & WAKE_UCAST)
+ criteria |= EHS_WAKE_ON_UNICAST_DATA;
+ if (wol->wolopts & WAKE_MCAST)
+ criteria |= EHS_WAKE_ON_MULTICAST_DATA;
+ if (wol->wolopts & WAKE_BCAST)
+ criteria |= EHS_WAKE_ON_BROADCAST_DATA;
+ if (wol->wolopts & WAKE_PHY)
+ criteria |= EHS_WAKE_ON_MAC_EVENT;
+ if (wol->wolopts == 0)
+ criteria |= EHS_REMOVE_WAKEUP;
return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
}
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 62381768f2d5..b1d84592b959 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -590,7 +590,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
/* TODO: make firmware file configurable */
ret = request_firmware(&fw, "libertas_cs_helper.fw",
- &handle_to_dev(card->p_dev));
+ &card->p_dev->dev);
if (ret) {
lbs_pr_err("can't load helper firmware\n");
ret = -ENODEV;
@@ -663,7 +663,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
/* TODO: make firmware file configurable */
ret = request_firmware(&fw, "libertas_cs.fw",
- &handle_to_dev(card->p_dev));
+ &card->p_dev->dev);
if (ret) {
lbs_pr_err("can't load firmware\n");
ret = -ENODEV;
@@ -793,18 +793,37 @@ static void if_cs_release(struct pcmcia_device *p_dev)
* configure the card at this point -- we wait until we receive a card
* insertion event.
*/
+
+static int if_cs_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ p_dev->io.BasePort1 = cfg->io.win[0].base;
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ if (cfg->io.nwin != 1) {
+ lbs_pr_err("wrong CIS (check number of IO windows)\n");
+ return -ENODEV;
+ }
+
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
static int if_cs_probe(struct pcmcia_device *p_dev)
{
int ret = -ENOMEM;
unsigned int prod_id;
struct lbs_private *priv;
struct if_cs_card *card;
- /* CIS parsing */
- tuple_t tuple;
- cisparse_t parse;
- cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
- cistpl_io_t *io = &cfg->io;
- u_char buf[64];
lbs_deb_enter(LBS_DEB_CS);
@@ -818,48 +837,15 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = NULL;
- p_dev->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
p_dev->conf.Attributes = 0;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
- (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
- (ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
- {
- lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
- goto out1;
- }
-
- p_dev->conf.ConfigIndex = cfg->index;
-
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1) {
- p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
- }
-
- /* IO window settings */
- if (cfg->io.nwin != 1) {
- lbs_pr_err("wrong CIS (check number of IO windows)\n");
- ret = -ENODEV;
+ if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
+ lbs_pr_err("error in pcmcia_loop_config\n");
goto out1;
}
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- p_dev->io.BasePort1 = io->win[0].base;
- p_dev->io.NumPorts1 = io->win[0].len;
- /* This reserves IO space but doesn't actually enable it */
- ret = pcmcia_request_io(p_dev, &p_dev->io);
- if (ret) {
- lbs_pr_err("error in pcmcia_request_io\n");
- goto out1;
- }
/*
* Allocate an interrupt line. Note that this does not assign
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index cb8be8d7abc1..5b3672c4d0cc 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -134,7 +134,7 @@ static void spu_transaction_finish(struct if_spi_card *card)
static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
{
int err = 0;
- u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
+ __le16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
struct spi_message m;
struct spi_transfer reg_trans;
struct spi_transfer data_trans;
@@ -166,7 +166,7 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
{
- u16 buff;
+ __le16 buff;
buff = cpu_to_le16(val);
return spu_write(card, reg, (u8 *)&buff, sizeof(u16));
@@ -188,7 +188,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
{
unsigned int delay;
int err = 0;
- u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
+ __le16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
struct spi_message m;
struct spi_transfer reg_trans;
struct spi_transfer dummy_trans;
@@ -235,7 +235,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
/* Read 16 bits from an SPI register */
static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
{
- u16 buf;
+ __le16 buf;
int ret;
ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
@@ -248,7 +248,7 @@ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
* The low 16 bits are read first. */
static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
{
- u32 buf;
+ __le32 buf;
int err;
err = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 92bc8c5f1ca2..3fac4efa5ac8 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -508,7 +508,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
/* Fill the receive configuration URB and initialise the Rx call back */
usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
- (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
+ skb->data + IPFIELD_ALIGN_OFFSET,
MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
cardp);
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 9498b46c99a4..e61e6b9440ab 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -145,23 +145,6 @@ static const unsigned int txConfEUD = 0x10; /* Enable Uni-Data packets */
static const unsigned int txConfKey = 0x02; /* Scramble data packets */
static const unsigned int txConfLoop = 0x01; /* Loopback mode */
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -383,7 +366,7 @@ static int netwave_probe(struct pcmcia_device *link)
struct net_device *dev;
netwave_private *priv;
- DEBUG(0, "netwave_attach()\n");
+ dev_dbg(&link->dev, "netwave_attach()\n");
/* Initialize the struct pcmcia_device structure */
dev = alloc_etherdev(sizeof(netwave_private));
@@ -401,8 +384,7 @@ static int netwave_probe(struct pcmcia_device *link)
link->io.IOAddrLines = 5;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = &netwave_interrupt;
/* General socket configuration */
@@ -421,8 +403,6 @@ static int netwave_probe(struct pcmcia_device *link)
dev->watchdog_timeo = TX_TIMEOUT;
- link->irq.Instance = dev;
-
return netwave_pcmcia_config( link);
} /* netwave_attach */
@@ -438,7 +418,7 @@ static void netwave_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "netwave_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "netwave_detach\n");
netwave_release(link);
@@ -725,18 +705,15 @@ static const struct iw_handler_def netwave_handler_def =
*
*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int netwave_pcmcia_config(struct pcmcia_device *link) {
struct net_device *dev = link->priv;
netwave_private *priv = netdev_priv(dev);
- int i, j, last_ret, last_fn;
+ int i, j, ret;
win_req_t req;
memreq_t mem;
u_char __iomem *ramBase = NULL;
- DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "netwave_pcmcia_config\n");
/*
* Try allocating IO ports. This tries a few fixed addresses.
@@ -749,22 +726,24 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
if (i == 0)
break;
}
- if (i != 0) {
- cs_error(link, RequestIO, i);
+ if (i != 0)
goto failed;
- }
/*
* Now allocate an interrupt line. Note that this does not
* actually assign a handler to the interrupt.
*/
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
/*
* This actually configures the PCMCIA socket -- setting up
* the I/O windows and the interrupt mapping.
*/
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*
* Allocate a 32K memory window. Note that the struct pcmcia_device
@@ -772,14 +751,18 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
* device needs several windows, you'll need to keep track of
* the handles in your private data structure, dev->priv.
*/
- DEBUG(1, "Setting mem speed of %d\n", mem_speed);
+ dev_dbg(&link->dev, "Setting mem speed of %d\n", mem_speed);
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
req.Base = 0; req.Size = 0x8000;
req.AccessSpeed = mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+ ret = pcmcia_request_window(link, &req, &link->win);
+ if (ret)
+ goto failed;
mem.CardOffset = 0x20000; mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+ ret = pcmcia_map_mem_page(link, link->win, &mem);
+ if (ret)
+ goto failed;
/* Store base address of the common window frame */
ramBase = ioremap(req.Base, 0x8000);
@@ -787,7 +770,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
@@ -818,8 +801,6 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
get_uint16(ramBase + NETWAVE_EREG_ARW+2));
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
netwave_release(link);
return -ENODEV;
@@ -837,7 +818,7 @@ static void netwave_release(struct pcmcia_device *link)
struct net_device *dev = link->priv;
netwave_private *priv = netdev_priv(dev);
- DEBUG(0, "netwave_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "netwave_release\n");
pcmcia_disable_device(link);
if (link->win)
@@ -892,7 +873,7 @@ static void netwave_reset(struct net_device *dev) {
u_char __iomem *ramBase = priv->ramBase;
unsigned int iobase = dev->base_addr;
- DEBUG(0, "netwave_reset: Done with hardware reset\n");
+ pr_debug("netwave_reset: Done with hardware reset\n");
priv->timeoutCounter = 0;
@@ -988,7 +969,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
dev->stats.tx_bytes += len;
- DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
+ pr_debug("Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
readb(ramBase + NETWAVE_EREG_SPCQ),
readb(ramBase + NETWAVE_EREG_SPU),
readb(ramBase + NETWAVE_EREG_LIF),
@@ -1000,7 +981,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
- DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n",
+ pr_debug("TxFreeList %x, MaxData %x, DataOffset %x\n",
TxFreeList, MaxData, DataOffset);
/* Copy packet to the adapter fragment buffers */
@@ -1088,7 +1069,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
status = inb(iobase + NETWAVE_REG_ASR);
if (!pcmcia_dev_present(link)) {
- DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
+ pr_debug("netwave_interrupt: Interrupt with status 0x%x "
"from removed or suspended card!\n", status);
break;
}
@@ -1132,7 +1113,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
int txStatus;
txStatus = readb(ramBase + NETWAVE_EREG_TSER);
- DEBUG(3, "Transmit done. TSER = %x id %x\n",
+ pr_debug("Transmit done. TSER = %x id %x\n",
txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
if (txStatus & 0x20) {
@@ -1156,7 +1137,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
* TxGU and TxNOAP is set. (Those are the only ones
* to set TxErr).
*/
- DEBUG(3, "netwave_interrupt: TxDN with error status %x\n",
+ pr_debug("netwave_interrupt: TxDN with error status %x\n",
txStatus);
/* Clear out TxGU, TxNOAP, TxErr and TxTrys */
@@ -1164,7 +1145,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
++dev->stats.tx_errors;
}
- DEBUG(3, "New status is TSER %x ASR %x\n",
+ pr_debug("New status is TSER %x ASR %x\n",
readb(ramBase + NETWAVE_EREG_TSER),
inb(iobase + NETWAVE_REG_ASR));
@@ -1172,7 +1153,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
}
/* TxBA, this would trigger on all error packets received */
/* if (status & 0x01) {
- DEBUG(4, "Transmit buffers available, %x\n", status);
+ pr_debug("Transmit buffers available, %x\n", status);
}
*/
}
@@ -1190,7 +1171,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
*/
static void netwave_watchdog(struct net_device *dev) {
- DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
+ pr_debug("%s: netwave_watchdog: watchdog timer expired\n", dev->name);
netwave_reset(dev);
dev->trans_start = jiffies;
netif_wake_queue(dev);
@@ -1211,7 +1192,7 @@ static int netwave_rx(struct net_device *dev)
int i;
u_char *ptr;
- DEBUG(3, "xinw_rx: Receiving ... \n");
+ pr_debug("xinw_rx: Receiving ... \n");
/* Receive max 10 packets for now. */
for (i = 0; i < 10; i++) {
@@ -1237,7 +1218,7 @@ static int netwave_rx(struct net_device *dev)
skb = dev_alloc_skb(rcvLen+5);
if (skb == NULL) {
- DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
+ pr_debug("netwave_rx: Could not allocate an sk_buff of "
"length %d\n", rcvLen);
++dev->stats.rx_dropped;
/* Tell the adapter to skip the packet */
@@ -1279,7 +1260,7 @@ static int netwave_rx(struct net_device *dev)
wait_WOC(iobase);
writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
- DEBUG(3, "Packet reception ok\n");
+ pr_debug("Packet reception ok\n");
}
return 0;
}
@@ -1288,7 +1269,7 @@ static int netwave_open(struct net_device *dev) {
netwave_private *priv = netdev_priv(dev);
struct pcmcia_device *link = priv->p_dev;
- DEBUG(1, "netwave_open: starting.\n");
+ dev_dbg(&link->dev, "netwave_open: starting.\n");
if (!pcmcia_dev_present(link))
return -ENODEV;
@@ -1305,7 +1286,7 @@ static int netwave_close(struct net_device *dev) {
netwave_private *priv = netdev_priv(dev);
struct pcmcia_device *link = priv->p_dev;
- DEBUG(1, "netwave_close: finishing.\n");
+ dev_dbg(&link->dev, "netwave_close: finishing.\n");
link->open--;
netif_stop_queue(dev);
@@ -1358,11 +1339,11 @@ static void set_multicast_list(struct net_device *dev)
u_char rcvMode = 0;
#ifdef PCMCIA_DEBUG
- if (pc_debug > 2) {
- static int old;
+ {
+ xstatic int old;
if (old != dev->mc_count) {
old = dev->mc_count;
- DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+ pr_debug("%s: setting Rx mode to %d addresses.\n",
dev->name, dev->mc_count);
}
}
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 38c1c9d2abb8..f27bb8367c98 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -109,7 +109,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
struct orinoco_private *priv;
struct orinoco_pccard *card;
- priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+ priv = alloc_orinocodev(sizeof(*card), &link->dev,
orinoco_cs_hard_reset, NULL);
if (!priv)
return -ENOMEM;
@@ -120,10 +120,8 @@ orinoco_cs_probe(struct pcmcia_device *link)
link->priv = priv;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = orinoco_interrupt;
- link->irq.Instance = priv;
/* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for
@@ -160,12 +158,6 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
* device available to the system.
*/
-#define CS_CHECK(fn, ret) do { \
- last_fn = (fn); \
- if ((last_ret = (ret)) != 0) \
- goto cs_failed; \
-} while (0)
-
static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
@@ -240,7 +232,7 @@ orinoco_cs_config(struct pcmcia_device *link)
struct orinoco_private *priv = link->priv;
struct orinoco_pccard *card = priv->card;
hermes_t *hw = &priv->hw;
- int last_fn, last_ret;
+ int ret;
void __iomem *mem;
/*
@@ -257,13 +249,12 @@ orinoco_cs_config(struct pcmcia_device *link)
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
- last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
- if (last_ret) {
+ ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
+ if (ret) {
if (!ignore_cis_vcc)
printk(KERN_ERR PFX "GetNextTuple(): No matching "
"CIS configuration. Maybe you need the "
"ignore_cis_vcc=1 parameter.\n");
- cs_error(link, RequestIO, last_ret);
goto failed;
}
@@ -272,14 +263,16 @@ orinoco_cs_config(struct pcmcia_device *link)
* a handler to the interrupt, unless the 'Handler' member of
* the irq structure is initialized.
*/
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
/* We initialize the hermes structure before completing PCMCIA
* configuration just in case the interrupt handler gets
* called. */
mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
if (!mem)
- goto cs_failed;
+ goto failed;
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
@@ -288,8 +281,9 @@ orinoco_cs_config(struct pcmcia_device *link)
* the I/O windows and the interrupt mapping, and putting the
* card and host interface into "Memory and IO" mode.
*/
- CS_CHECK(RequestConfiguration,
- pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/* Ok, we have the configuration, prepare to register the netdev */
card->node.major = card->node.minor = 0;
@@ -315,9 +309,6 @@ orinoco_cs_config(struct pcmcia_device *link)
* net_device has been registered */
return 0;
- cs_failed:
- cs_error(link, last_fn, last_ret);
-
failed:
orinoco_cs_release(link);
return -ENODEV;
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index c361310b885d..59bda240fdc2 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -73,9 +73,6 @@ static void spectrum_cs_release(struct pcmcia_device *link);
#define HCR_MEM16 0x10 /* memory width bit, should be preserved */
-#define CS_CHECK(fn, ret) \
- do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
/*
* Reset the card using configuration registers COR and CCSR.
* If IDLE is 1, stop the firmware, so that it can be safely rewritten.
@@ -83,7 +80,7 @@ static void spectrum_cs_release(struct pcmcia_device *link);
static int
spectrum_reset(struct pcmcia_device *link, int idle)
{
- int last_ret, last_fn;
+ int ret;
conf_reg_t reg;
u_int save_cor;
@@ -95,23 +92,26 @@ spectrum_reset(struct pcmcia_device *link, int idle)
reg.Function = 0;
reg.Action = CS_READ;
reg.Offset = CISREG_COR;
- CS_CHECK(AccessConfigurationRegister,
- pcmcia_access_configuration_register(link, &reg));
+ ret = pcmcia_access_configuration_register(link, &reg);
+ if (ret)
+ goto failed;
save_cor = reg.Value;
/* Soft-Reset card */
reg.Action = CS_WRITE;
reg.Offset = CISREG_COR;
reg.Value = (save_cor | COR_SOFT_RESET);
- CS_CHECK(AccessConfigurationRegister,
- pcmcia_access_configuration_register(link, &reg));
+ ret = pcmcia_access_configuration_register(link, &reg);
+ if (ret)
+ goto failed;
udelay(1000);
/* Read CCSR */
reg.Action = CS_READ;
reg.Offset = CISREG_CCSR;
- CS_CHECK(AccessConfigurationRegister,
- pcmcia_access_configuration_register(link, &reg));
+ ret = pcmcia_access_configuration_register(link, &reg);
+ if (ret)
+ goto failed;
/*
* Start or stop the firmware. Memory width bit should be
@@ -120,21 +120,22 @@ spectrum_reset(struct pcmcia_device *link, int idle)
reg.Action = CS_WRITE;
reg.Offset = CISREG_CCSR;
reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
- CS_CHECK(AccessConfigurationRegister,
- pcmcia_access_configuration_register(link, &reg));
+ ret = pcmcia_access_configuration_register(link, &reg);
+ if (ret)
+ goto failed;
udelay(1000);
/* Restore original COR configuration index */
reg.Action = CS_WRITE;
reg.Offset = CISREG_COR;
reg.Value = (save_cor & ~COR_SOFT_RESET);
- CS_CHECK(AccessConfigurationRegister,
- pcmcia_access_configuration_register(link, &reg));
+ ret = pcmcia_access_configuration_register(link, &reg);
+ if (ret)
+ goto failed;
udelay(1000);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
+failed:
return -ENODEV;
}
@@ -181,7 +182,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
struct orinoco_private *priv;
struct orinoco_pccard *card;
- priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+ priv = alloc_orinocodev(sizeof(*card), &link->dev,
spectrum_cs_hard_reset,
spectrum_cs_stop_firmware);
if (!priv)
@@ -193,10 +194,8 @@ spectrum_cs_probe(struct pcmcia_device *link)
link->priv = priv;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = orinoco_interrupt;
- link->irq.Instance = priv;
/* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for
@@ -307,7 +306,7 @@ spectrum_cs_config(struct pcmcia_device *link)
struct orinoco_private *priv = link->priv;
struct orinoco_pccard *card = priv->card;
hermes_t *hw = &priv->hw;
- int last_fn, last_ret;
+ int ret;
void __iomem *mem;
/*
@@ -324,13 +323,12 @@ spectrum_cs_config(struct pcmcia_device *link)
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
- last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
- if (last_ret) {
+ ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
+ if (ret) {
if (!ignore_cis_vcc)
printk(KERN_ERR PFX "GetNextTuple(): No matching "
"CIS configuration. Maybe you need the "
"ignore_cis_vcc=1 parameter.\n");
- cs_error(link, RequestIO, last_ret);
goto failed;
}
@@ -339,14 +337,16 @@ spectrum_cs_config(struct pcmcia_device *link)
* a handler to the interrupt, unless the 'Handler' member of
* the irq structure is initialized.
*/
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
/* We initialize the hermes structure before completing PCMCIA
* configuration just in case the interrupt handler gets
* called. */
mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
if (!mem)
- goto cs_failed;
+ goto failed;
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
@@ -355,8 +355,9 @@ spectrum_cs_config(struct pcmcia_device *link)
* the I/O windows and the interrupt mapping, and putting the
* card and host interface into "Memory and IO" mode.
*/
- CS_CHECK(RequestConfiguration,
- pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/* Ok, we have the configuration, prepare to register the netdev */
card->node.major = card->node.minor = 0;
@@ -386,9 +387,6 @@ spectrum_cs_config(struct pcmcia_device *link)
* net_device has been registered */
return 0;
- cs_failed:
- cs_error(link, last_fn, last_ret);
-
failed:
spectrum_cs_release(link);
return -ENODEV;
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 17e199546eeb..92af9b96bb7a 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -426,12 +426,16 @@ static const char p54u_romboot_3887[] = "~~~~";
static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
- u8 buf[4];
+ u8 *buf;
int ret;
- memcpy(&buf, p54u_romboot_3887, sizeof(buf));
+ buf = kmalloc(4, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ memcpy(buf, p54u_romboot_3887, 4);
ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
- buf, sizeof(buf));
+ buf, 4);
+ kfree(buf);
if (ret)
dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
"boot ROM (%d)!\n", ret);
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 88cd58eb3b9f..5b8e3e4cdd9f 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -71,25 +71,7 @@ typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */
#include "rayctl.h"
#include "ray_cs.h"
-/* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef RAYLINK_DEBUG
-#define PCMCIA_DEBUG RAYLINK_DEBUG
-#endif
-#ifdef PCMCIA_DEBUG
-static int ray_debug;
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */
-#define DEBUG(n, args...) if (pc_debug > (n)) printk(args);
-#else
-#define DEBUG(n, args...)
-#endif
/** Prototypes based on PCMCIA skeleton driver *******************************/
static int ray_config(struct pcmcia_device *link);
static void ray_release(struct pcmcia_device *link);
@@ -325,7 +307,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
ray_dev_t *local;
struct net_device *dev;
- DEBUG(1, "ray_attach()\n");
+ dev_dbg(&p_dev->dev, "ray_attach()\n");
/* Allocate space for private device-specific data */
dev = alloc_etherdev(sizeof(ray_dev_t));
@@ -341,8 +323,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
p_dev->io.IOAddrLines = 5;
/* Interrupt setup. For PCMCIA, driver takes what's given */
- p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = &ray_interrupt;
/* General socket configuration */
@@ -351,13 +332,12 @@ static int ray_probe(struct pcmcia_device *p_dev)
p_dev->conf.ConfigIndex = 1;
p_dev->priv = dev;
- p_dev->irq.Instance = dev;
local->finder = p_dev;
local->card_status = CARD_INSERTED;
local->authentication_state = UNAUTHENTICATED;
local->num_multi = 0;
- DEBUG(2, "ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n",
+ dev_dbg(&p_dev->dev, "ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n",
p_dev, dev, local, &ray_interrupt);
/* Raylink entries in the device structure */
@@ -370,7 +350,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
#endif /* WIRELESS_SPY */
- DEBUG(2, "ray_cs ray_attach calling ether_setup.)\n");
+ dev_dbg(&p_dev->dev, "ray_cs ray_attach calling ether_setup.)\n");
netif_stop_queue(dev);
init_timer(&local->timer);
@@ -393,7 +373,7 @@ static void ray_detach(struct pcmcia_device *link)
struct net_device *dev;
ray_dev_t *local;
- DEBUG(1, "ray_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "ray_detach\n");
this_device = NULL;
dev = link->priv;
@@ -408,7 +388,7 @@ static void ray_detach(struct pcmcia_device *link)
unregister_netdev(dev);
free_netdev(dev);
}
- DEBUG(2, "ray_cs ray_detach ending\n");
+ dev_dbg(&link->dev, "ray_cs ray_detach ending\n");
} /* ray_detach */
/*=============================================================================
@@ -416,19 +396,17 @@ static void ray_detach(struct pcmcia_device *link)
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
=============================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define MAX_TUPLE_SIZE 128
static int ray_config(struct pcmcia_device *link)
{
- int last_fn = 0, last_ret = 0;
+ int ret = 0;
int i;
win_req_t req;
memreq_t mem;
struct net_device *dev = (struct net_device *)link->priv;
ray_dev_t *local = netdev_priv(dev);
- DEBUG(1, "ray_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "ray_config\n");
/* Determine card type and firmware version */
printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
@@ -440,14 +418,17 @@ static int ray_config(struct pcmcia_device *link)
/* Now allocate an interrupt line. Note that this does not
actually assign a handler to the interrupt.
*/
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
dev->irq = link->irq.AssignedIRQ;
/* This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping.
*/
- CS_CHECK(RequestConfiguration,
- pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*** Set up 32k window for shared memory (transmit and control) ************/
req.Attributes =
@@ -455,10 +436,14 @@ static int ray_config(struct pcmcia_device *link)
req.Base = 0;
req.Size = 0x8000;
req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+ ret = pcmcia_request_window(link, &req, &link->win);
+ if (ret)
+ goto failed;
mem.CardOffset = 0x0000;
mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+ ret = pcmcia_map_mem_page(link, link->win, &mem);
+ if (ret)
+ goto failed;
local->sram = ioremap(req.Base, req.Size);
/*** Set up 16k window for shared memory (receive buffer) ***************/
@@ -467,11 +452,14 @@ static int ray_config(struct pcmcia_device *link)
req.Base = 0;
req.Size = 0x4000;
req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow,
- pcmcia_request_window(&link, &req, &local->rmem_handle));
+ ret = pcmcia_request_window(link, &req, &local->rmem_handle);
+ if (ret)
+ goto failed;
mem.CardOffset = 0x8000;
mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
+ ret = pcmcia_map_mem_page(link, local->rmem_handle, &mem);
+ if (ret)
+ goto failed;
local->rmem = ioremap(req.Base, req.Size);
/*** Set up window for attribute memory ***********************************/
@@ -480,22 +468,25 @@ static int ray_config(struct pcmcia_device *link)
req.Base = 0;
req.Size = 0x1000;
req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow,
- pcmcia_request_window(&link, &req, &local->amem_handle));
+ ret = pcmcia_request_window(link, &req, &local->amem_handle);
+ if (ret)
+ goto failed;
mem.CardOffset = 0x0000;
mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
+ ret = pcmcia_map_mem_page(link, local->amem_handle, &mem);
+ if (ret)
+ goto failed;
local->amem = ioremap(req.Base, req.Size);
- DEBUG(3, "ray_config sram=%p\n", local->sram);
- DEBUG(3, "ray_config rmem=%p\n", local->rmem);
- DEBUG(3, "ray_config amem=%p\n", local->amem);
+ dev_dbg(&link->dev, "ray_config sram=%p\n", local->sram);
+ dev_dbg(&link->dev, "ray_config rmem=%p\n", local->rmem);
+ dev_dbg(&link->dev, "ray_config amem=%p\n", local->amem);
if (ray_init(dev) < 0) {
ray_release(link);
return -ENODEV;
}
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
i = register_netdev(dev);
if (i != 0) {
printk("ray_config register_netdev() failed\n");
@@ -511,9 +502,7 @@ static int ray_config(struct pcmcia_device *link)
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
-
+failed:
ray_release(link);
return -ENODEV;
} /* ray_config */
@@ -543,9 +532,9 @@ static int ray_init(struct net_device *dev)
struct ccs __iomem *pccs;
ray_dev_t *local = netdev_priv(dev);
struct pcmcia_device *link = local->finder;
- DEBUG(1, "ray_init(0x%p)\n", dev);
+ dev_dbg(&link->dev, "ray_init(0x%p)\n", dev);
if (!(pcmcia_dev_present(link))) {
- DEBUG(0, "ray_init - device not present\n");
+ dev_dbg(&link->dev, "ray_init - device not present\n");
return -1;
}
@@ -567,13 +556,13 @@ static int ray_init(struct net_device *dev)
local->fw_ver = local->startup_res.firmware_version[0];
local->fw_bld = local->startup_res.firmware_version[1];
local->fw_var = local->startup_res.firmware_version[2];
- DEBUG(1, "ray_init firmware version %d.%d \n", local->fw_ver,
+ dev_dbg(&link->dev, "ray_init firmware version %d.%d \n", local->fw_ver,
local->fw_bld);
local->tib_length = 0x20;
if ((local->fw_ver == 5) && (local->fw_bld >= 30))
local->tib_length = local->startup_res.tib_length;
- DEBUG(2, "ray_init tib_length = 0x%02x\n", local->tib_length);
+ dev_dbg(&link->dev, "ray_init tib_length = 0x%02x\n", local->tib_length);
/* Initialize CCS's to buffer free state */
pccs = ccs_base(local);
for (i = 0; i < NUMBER_OF_CCS; i++) {
@@ -592,7 +581,7 @@ static int ray_init(struct net_device *dev)
clear_interrupt(local); /* Clear any interrupt from the card */
local->card_status = CARD_AWAITING_PARAM;
- DEBUG(2, "ray_init ending\n");
+ dev_dbg(&link->dev, "ray_init ending\n");
return 0;
} /* ray_init */
@@ -605,9 +594,9 @@ static int dl_startup_params(struct net_device *dev)
struct ccs __iomem *pccs;
struct pcmcia_device *link = local->finder;
- DEBUG(1, "dl_startup_params entered\n");
+ dev_dbg(&link->dev, "dl_startup_params entered\n");
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs dl_startup_params - device not present\n");
+ dev_dbg(&link->dev, "ray_cs dl_startup_params - device not present\n");
return -1;
}
@@ -625,7 +614,7 @@ static int dl_startup_params(struct net_device *dev)
local->dl_param_ccs = ccsindex;
pccs = ccs_base(local) + ccsindex;
writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
- DEBUG(2, "dl_startup_params start ccsindex = %d\n",
+ dev_dbg(&link->dev, "dl_startup_params start ccsindex = %d\n",
local->dl_param_ccs);
/* Interrupt the firmware to process the command */
if (interrupt_ecf(local, ccsindex)) {
@@ -641,7 +630,7 @@ static int dl_startup_params(struct net_device *dev)
local->timer.data = (long)local;
local->timer.function = &verify_dl_startup;
add_timer(&local->timer);
- DEBUG(2,
+ dev_dbg(&link->dev,
"ray_cs dl_startup_params started timer for verify_dl_startup\n");
return 0;
} /* dl_startup_params */
@@ -717,11 +706,11 @@ static void verify_dl_startup(u_long data)
struct pcmcia_device *link = local->finder;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs verify_dl_startup - device not present\n");
+ dev_dbg(&link->dev, "ray_cs verify_dl_startup - device not present\n");
return;
}
-#ifdef PCMCIA_DEBUG
- if (pc_debug > 2) {
+#if 0
+ {
int i;
printk(KERN_DEBUG
"verify_dl_startup parameters sent via ccs %d:\n",
@@ -760,7 +749,7 @@ static void start_net(u_long data)
int ccsindex;
struct pcmcia_device *link = local->finder;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs start_net - device not present\n");
+ dev_dbg(&link->dev, "ray_cs start_net - device not present\n");
return;
}
/* Fill in the CCS fields for the ECF */
@@ -771,7 +760,7 @@ static void start_net(u_long data)
writeb(0, &pccs->var.start_network.update_param);
/* Interrupt the firmware to process the command */
if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1, "ray start net failed - card not ready for intr\n");
+ dev_dbg(&link->dev, "ray start net failed - card not ready for intr\n");
writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
return;
}
@@ -790,7 +779,7 @@ static void join_net(u_long data)
struct pcmcia_device *link = local->finder;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs join_net - device not present\n");
+ dev_dbg(&link->dev, "ray_cs join_net - device not present\n");
return;
}
/* Fill in the CCS fields for the ECF */
@@ -802,7 +791,7 @@ static void join_net(u_long data)
writeb(0, &pccs->var.join_network.net_initiated);
/* Interrupt the firmware to process the command */
if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1, "ray join net failed - card not ready for intr\n");
+ dev_dbg(&link->dev, "ray join net failed - card not ready for intr\n");
writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
return;
}
@@ -821,7 +810,7 @@ static void ray_release(struct pcmcia_device *link)
ray_dev_t *local = netdev_priv(dev);
int i;
- DEBUG(1, "ray_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "ray_release\n");
del_timer(&local->timer);
@@ -829,15 +818,15 @@ static void ray_release(struct pcmcia_device *link)
iounmap(local->rmem);
iounmap(local->amem);
/* Do bother checking to see if these succeed or not */
- i = pcmcia_release_window(local->amem_handle);
+ i = pcmcia_release_window(link, local->amem_handle);
if (i != 0)
- DEBUG(0, "ReleaseWindow(local->amem) ret = %x\n", i);
- i = pcmcia_release_window(local->rmem_handle);
+ dev_dbg(&link->dev, "ReleaseWindow(local->amem) ret = %x\n", i);
+ i = pcmcia_release_window(link, local->rmem_handle);
if (i != 0)
- DEBUG(0, "ReleaseWindow(local->rmem) ret = %x\n", i);
+ dev_dbg(&link->dev, "ReleaseWindow(local->rmem) ret = %x\n", i);
pcmcia_disable_device(link);
- DEBUG(2, "ray_release ending\n");
+ dev_dbg(&link->dev, "ray_release ending\n");
}
static int ray_suspend(struct pcmcia_device *link)
@@ -871,9 +860,9 @@ static int ray_dev_init(struct net_device *dev)
ray_dev_t *local = netdev_priv(dev);
struct pcmcia_device *link = local->finder;
- DEBUG(1, "ray_dev_init(dev=%p)\n", dev);
+ dev_dbg(&link->dev, "ray_dev_init(dev=%p)\n", dev);
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_dev_init - device not present\n");
+ dev_dbg(&link->dev, "ray_dev_init - device not present\n");
return -1;
}
#ifdef RAY_IMMEDIATE_INIT
@@ -887,7 +876,7 @@ static int ray_dev_init(struct net_device *dev)
/* Postpone the card init so that we can still configure the card,
* for example using the Wireless Extensions. The init will happen
* in ray_open() - Jean II */
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
local->card_status);
#endif /* RAY_IMMEDIATE_INIT */
@@ -896,7 +885,7 @@ static int ray_dev_init(struct net_device *dev)
memcpy(dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
memset(dev->broadcast, 0xff, ETH_ALEN);
- DEBUG(2, "ray_dev_init ending\n");
+ dev_dbg(&link->dev, "ray_dev_init ending\n");
return 0;
}
@@ -906,9 +895,9 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map)
ray_dev_t *local = netdev_priv(dev);
struct pcmcia_device *link = local->finder;
/* Dummy routine to satisfy device structure */
- DEBUG(1, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
+ dev_dbg(&link->dev, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_dev_config - device not present\n");
+ dev_dbg(&link->dev, "ray_dev_config - device not present\n");
return -1;
}
@@ -924,14 +913,14 @@ static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
short length = skb->len;
if (!pcmcia_dev_present(link)) {
- DEBUG(2, "ray_dev_start_xmit - device not present\n");
+ dev_dbg(&link->dev, "ray_dev_start_xmit - device not present\n");
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
- DEBUG(3, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
+ dev_dbg(&link->dev, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
if (local->authentication_state == NEED_TO_AUTH) {
- DEBUG(0, "ray_cs Sending authentication request.\n");
+ dev_dbg(&link->dev, "ray_cs Sending authentication request.\n");
if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
local->authentication_state = AUTHENTICATED;
netif_stop_queue(dev);
@@ -971,7 +960,7 @@ static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
struct tx_msg __iomem *ptx; /* Address of xmit buffer in PC space */
short int addr; /* Address of xmit buffer in card space */
- DEBUG(3, "ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
+ pr_debug("ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) {
printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",
len);
@@ -979,9 +968,9 @@ static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
}
switch (ccsindex = get_free_tx_ccs(local)) {
case ECCSBUSY:
- DEBUG(2, "ray_hw_xmit tx_ccs table busy\n");
+ pr_debug("ray_hw_xmit tx_ccs table busy\n");
case ECCSFULL:
- DEBUG(2, "ray_hw_xmit No free tx ccs\n");
+ pr_debug("ray_hw_xmit No free tx ccs\n");
case ECARDGONE:
netif_stop_queue(dev);
return XMIT_NO_CCS;
@@ -1018,12 +1007,12 @@ static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
writeb(0, &pccs->var.tx_request.antenna);
- DEBUG(3, "ray_hw_xmit default_tx_rate = 0x%x\n",
+ pr_debug("ray_hw_xmit default_tx_rate = 0x%x\n",
local->net_default_tx_rate);
/* Interrupt the firmware to process the command */
if (interrupt_ecf(local, ccsindex)) {
- DEBUG(2, "ray_hw_xmit failed - ECF not ready for intr\n");
+ pr_debug("ray_hw_xmit failed - ECF not ready for intr\n");
/* TBD very inefficient to copy packet to buffer, and then not
send it, but the alternative is to queue the messages and that
won't be done for a while. Maybe set tbusy until a CCS is free?
@@ -1040,7 +1029,7 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
{
__be16 proto = ((struct ethhdr *)data)->h_proto;
if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
- DEBUG(3, "ray_cs translate_frame DIX II\n");
+ pr_debug("ray_cs translate_frame DIX II\n");
/* Copy LLC header to card buffer */
memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
memcpy_toio(((void __iomem *)&ptx->var) + sizeof(eth2_llc),
@@ -1056,9 +1045,9 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
len - ETH_HLEN);
return (int)sizeof(struct snaphdr_t) - ETH_HLEN;
} else { /* already 802 type, and proto is length */
- DEBUG(3, "ray_cs translate_frame 802\n");
+ pr_debug("ray_cs translate_frame 802\n");
if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
- DEBUG(3, "ray_cs translate_frame evil IPX\n");
+ pr_debug("ray_cs translate_frame evil IPX\n");
memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
return 0 - ETH_HLEN;
}
@@ -1603,7 +1592,7 @@ static int ray_open(struct net_device *dev)
struct pcmcia_device *link;
link = local->finder;
- DEBUG(1, "ray_open('%s')\n", dev->name);
+ dev_dbg(&link->dev, "ray_open('%s')\n", dev->name);
if (link->open == 0)
local->num_multi = 0;
@@ -1613,7 +1602,7 @@ static int ray_open(struct net_device *dev)
if (local->card_status == CARD_AWAITING_PARAM) {
int i;
- DEBUG(1, "ray_open: doing init now !\n");
+ dev_dbg(&link->dev, "ray_open: doing init now !\n");
/* Download startup parameters */
if ((i = dl_startup_params(dev)) < 0) {
@@ -1629,7 +1618,7 @@ static int ray_open(struct net_device *dev)
else
netif_start_queue(dev);
- DEBUG(2, "ray_open ending\n");
+ dev_dbg(&link->dev, "ray_open ending\n");
return 0;
} /* end ray_open */
@@ -1640,7 +1629,7 @@ static int ray_dev_close(struct net_device *dev)
struct pcmcia_device *link;
link = local->finder;
- DEBUG(1, "ray_dev_close('%s')\n", dev->name);
+ dev_dbg(&link->dev, "ray_dev_close('%s')\n", dev->name);
link->open--;
netif_stop_queue(dev);
@@ -1656,7 +1645,7 @@ static int ray_dev_close(struct net_device *dev)
/*===========================================================================*/
static void ray_reset(struct net_device *dev)
{
- DEBUG(1, "ray_reset entered\n");
+ pr_debug("ray_reset entered\n");
return;
}
@@ -1669,17 +1658,17 @@ static int interrupt_ecf(ray_dev_t *local, int ccs)
struct pcmcia_device *link = local->finder;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs interrupt_ecf - device not present\n");
+ dev_dbg(&link->dev, "ray_cs interrupt_ecf - device not present\n");
return -1;
}
- DEBUG(2, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
+ dev_dbg(&link->dev, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
while (i &&
(readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) &
ECF_INTR_SET))
i--;
if (i == 0) {
- DEBUG(2, "ray_cs interrupt_ecf card not ready for interrupt\n");
+ dev_dbg(&link->dev, "ray_cs interrupt_ecf card not ready for interrupt\n");
return -1;
}
/* Fill the mailbox, then kick the card */
@@ -1698,12 +1687,12 @@ static int get_free_tx_ccs(ray_dev_t *local)
struct pcmcia_device *link = local->finder;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs get_free_tx_ccs - device not present\n");
+ dev_dbg(&link->dev, "ray_cs get_free_tx_ccs - device not present\n");
return ECARDGONE;
}
if (test_and_set_bit(0, &local->tx_ccs_lock)) {
- DEBUG(1, "ray_cs tx_ccs_lock busy\n");
+ dev_dbg(&link->dev, "ray_cs tx_ccs_lock busy\n");
return ECCSBUSY;
}
@@ -1716,7 +1705,7 @@ static int get_free_tx_ccs(ray_dev_t *local)
}
}
local->tx_ccs_lock = 0;
- DEBUG(2, "ray_cs ERROR no free tx CCS for raylink card\n");
+ dev_dbg(&link->dev, "ray_cs ERROR no free tx CCS for raylink card\n");
return ECCSFULL;
} /* get_free_tx_ccs */
@@ -1730,11 +1719,11 @@ static int get_free_ccs(ray_dev_t *local)
struct pcmcia_device *link = local->finder;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs get_free_ccs - device not present\n");
+ dev_dbg(&link->dev, "ray_cs get_free_ccs - device not present\n");
return ECARDGONE;
}
if (test_and_set_bit(0, &local->ccs_lock)) {
- DEBUG(1, "ray_cs ccs_lock busy\n");
+ dev_dbg(&link->dev, "ray_cs ccs_lock busy\n");
return ECCSBUSY;
}
@@ -1747,7 +1736,7 @@ static int get_free_ccs(ray_dev_t *local)
}
}
local->ccs_lock = 0;
- DEBUG(1, "ray_cs ERROR no free CCS for raylink card\n");
+ dev_dbg(&link->dev, "ray_cs ERROR no free CCS for raylink card\n");
return ECCSFULL;
} /* get_free_ccs */
@@ -1823,7 +1812,7 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev)
struct pcmcia_device *link = local->finder;
struct status __iomem *p = local->sram + STATUS_BASE;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs net_device_stats - device not present\n");
+ dev_dbg(&link->dev, "ray_cs net_device_stats - device not present\n");
return &local->stats;
}
if (readb(&p->mrx_overflow_for_host)) {
@@ -1856,12 +1845,12 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
struct ccs __iomem *pccs;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_update_parm - device not present\n");
+ dev_dbg(&link->dev, "ray_update_parm - device not present\n");
return;
}
if ((ccsindex = get_free_ccs(local)) < 0) {
- DEBUG(0, "ray_update_parm - No free ccs\n");
+ dev_dbg(&link->dev, "ray_update_parm - No free ccs\n");
return;
}
pccs = ccs_base(local) + ccsindex;
@@ -1874,7 +1863,7 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
}
/* Interrupt the firmware to process the command */
if (interrupt_ecf(local, ccsindex)) {
- DEBUG(0, "ray_cs associate failed - ECF not ready for intr\n");
+ dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
}
}
@@ -1891,12 +1880,12 @@ static void ray_update_multi_list(struct net_device *dev, int all)
void __iomem *p = local->sram + HOST_TO_ECF_BASE;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_update_multi_list - device not present\n");
+ dev_dbg(&link->dev, "ray_update_multi_list - device not present\n");
return;
} else
- DEBUG(2, "ray_update_multi_list(%p)\n", dev);
+ dev_dbg(&link->dev, "ray_update_multi_list(%p)\n", dev);
if ((ccsindex = get_free_ccs(local)) < 0) {
- DEBUG(1, "ray_update_multi - No free ccs\n");
+ dev_dbg(&link->dev, "ray_update_multi - No free ccs\n");
return;
}
pccs = ccs_base(local) + ccsindex;
@@ -1910,7 +1899,7 @@ static void ray_update_multi_list(struct net_device *dev, int all)
for (dmip = &dev->mc_list; (dmi = *dmip) != NULL;
dmip = &dmi->next) {
memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
dmi->dmi_addr[0], dmi->dmi_addr[1],
dmi->dmi_addr[2], dmi->dmi_addr[3],
@@ -1921,12 +1910,12 @@ static void ray_update_multi_list(struct net_device *dev, int all)
if (i > 256 / ADDRLEN)
i = 256 / ADDRLEN;
writeb((UCHAR) i, &pccs->var);
- DEBUG(1, "ray_cs update_multi %d addresses in list\n", i);
+ dev_dbg(&link->dev, "ray_cs update_multi %d addresses in list\n", i);
/* Interrupt the firmware to process the command */
local->num_multi = i;
}
if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs update_multi failed - ECF not ready for intr\n");
writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
}
@@ -1938,11 +1927,11 @@ static void set_multicast_list(struct net_device *dev)
ray_dev_t *local = netdev_priv(dev);
UCHAR promisc;
- DEBUG(2, "ray_cs set_multicast_list(%p)\n", dev);
+ pr_debug("ray_cs set_multicast_list(%p)\n", dev);
if (dev->flags & IFF_PROMISC) {
if (local->sparm.b5.a_promiscuous_mode == 0) {
- DEBUG(1, "ray_cs set_multicast_list promisc on\n");
+ pr_debug("ray_cs set_multicast_list promisc on\n");
local->sparm.b5.a_promiscuous_mode = 1;
promisc = 1;
ray_update_parm(dev, OBJID_promiscuous_mode,
@@ -1950,7 +1939,7 @@ static void set_multicast_list(struct net_device *dev)
}
} else {
if (local->sparm.b5.a_promiscuous_mode == 1) {
- DEBUG(1, "ray_cs set_multicast_list promisc off\n");
+ pr_debug("ray_cs set_multicast_list promisc off\n");
local->sparm.b5.a_promiscuous_mode = 0;
promisc = 0;
ray_update_parm(dev, OBJID_promiscuous_mode,
@@ -1984,19 +1973,19 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
return IRQ_NONE;
- DEBUG(4, "ray_cs: interrupt for *dev=%p\n", dev);
+ pr_debug("ray_cs: interrupt for *dev=%p\n", dev);
local = netdev_priv(dev);
link = (struct pcmcia_device *)local->finder;
if (!pcmcia_dev_present(link)) {
- DEBUG(2,
- "ray_cs interrupt from device not present or suspended.\n");
+ pr_debug(
+ "ray_cs interrupt from device not present or suspended.\n");
return IRQ_NONE;
}
rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
- DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
+ dev_dbg(&link->dev, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
clear_interrupt(local);
return IRQ_HANDLED;
}
@@ -2008,33 +1997,33 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */
del_timer(&local->timer);
if (status == CCS_COMMAND_COMPLETE) {
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs interrupt download_startup_parameters OK\n");
} else {
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs interrupt download_startup_parameters fail\n");
}
break;
case CCS_UPDATE_PARAMS:
- DEBUG(1, "ray_cs interrupt update params done\n");
+ dev_dbg(&link->dev, "ray_cs interrupt update params done\n");
if (status != CCS_COMMAND_COMPLETE) {
tmp =
readb(&pccs->var.update_param.
failure_cause);
- DEBUG(0,
+ dev_dbg(&link->dev,
"ray_cs interrupt update params failed - reason %d\n",
tmp);
}
break;
case CCS_REPORT_PARAMS:
- DEBUG(1, "ray_cs interrupt report params done\n");
+ dev_dbg(&link->dev, "ray_cs interrupt report params done\n");
break;
case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs interrupt CCS Update Multicast List done\n");
break;
case CCS_UPDATE_POWER_SAVINGS_MODE:
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs interrupt update power save mode done\n");
break;
case CCS_START_NETWORK:
@@ -2043,11 +2032,11 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
if (readb
(&pccs->var.start_network.net_initiated) ==
1) {
- DEBUG(0,
+ dev_dbg(&link->dev,
"ray_cs interrupt network \"%s\" started\n",
local->sparm.b4.a_current_ess_id);
} else {
- DEBUG(0,
+ dev_dbg(&link->dev,
"ray_cs interrupt network \"%s\" joined\n",
local->sparm.b4.a_current_ess_id);
}
@@ -2075,12 +2064,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
local->timer.expires = jiffies + HZ * 5;
local->timer.data = (long)local;
if (status == CCS_START_NETWORK) {
- DEBUG(0,
+ dev_dbg(&link->dev,
"ray_cs interrupt network \"%s\" start failed\n",
local->sparm.b4.a_current_ess_id);
local->timer.function = &start_net;
} else {
- DEBUG(0,
+ dev_dbg(&link->dev,
"ray_cs interrupt network \"%s\" join failed\n",
local->sparm.b4.a_current_ess_id);
local->timer.function = &join_net;
@@ -2091,19 +2080,19 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
case CCS_START_ASSOCIATION:
if (status == CCS_COMMAND_COMPLETE) {
local->card_status = CARD_ASSOC_COMPLETE;
- DEBUG(0, "ray_cs association successful\n");
+ dev_dbg(&link->dev, "ray_cs association successful\n");
} else {
- DEBUG(0, "ray_cs association failed,\n");
+ dev_dbg(&link->dev, "ray_cs association failed,\n");
local->card_status = CARD_ASSOC_FAILED;
join_net((u_long) local);
}
break;
case CCS_TX_REQUEST:
if (status == CCS_COMMAND_COMPLETE) {
- DEBUG(3,
+ dev_dbg(&link->dev,
"ray_cs interrupt tx request complete\n");
} else {
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs interrupt tx request failed\n");
}
if (!sniffer)
@@ -2111,21 +2100,21 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
netif_wake_queue(dev);
break;
case CCS_TEST_MEMORY:
- DEBUG(1, "ray_cs interrupt mem test done\n");
+ dev_dbg(&link->dev, "ray_cs interrupt mem test done\n");
break;
case CCS_SHUTDOWN:
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs interrupt Unexpected CCS returned - Shutdown\n");
break;
case CCS_DUMP_MEMORY:
- DEBUG(1, "ray_cs interrupt dump memory done\n");
+ dev_dbg(&link->dev, "ray_cs interrupt dump memory done\n");
break;
case CCS_START_TIMER:
- DEBUG(2,
+ dev_dbg(&link->dev,
"ray_cs interrupt DING - raylink timer expired\n");
break;
default:
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
rcsindex, cmd);
}
@@ -2139,7 +2128,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
ray_rx(dev, local, prcs);
break;
case REJOIN_NET_COMPLETE:
- DEBUG(1, "ray_cs interrupt rejoin net complete\n");
+ dev_dbg(&link->dev, "ray_cs interrupt rejoin net complete\n");
local->card_status = CARD_ACQ_COMPLETE;
/* do we need to clear tx buffers CCS's? */
if (local->sparm.b4.a_network_type == ADHOC) {
@@ -2149,7 +2138,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
memcpy_fromio(&local->bss_id,
prcs->var.rejoin_net_complete.
bssid, ADDRLEN);
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",
local->bss_id[0], local->bss_id[1],
local->bss_id[2], local->bss_id[3],
@@ -2159,15 +2148,15 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
}
break;
case ROAMING_INITIATED:
- DEBUG(1, "ray_cs interrupt roaming initiated\n");
+ dev_dbg(&link->dev, "ray_cs interrupt roaming initiated\n");
netif_stop_queue(dev);
local->card_status = CARD_DOING_ACQ;
break;
case JAPAN_CALL_SIGN_RXD:
- DEBUG(1, "ray_cs interrupt japan call sign rx\n");
+ dev_dbg(&link->dev, "ray_cs interrupt japan call sign rx\n");
break;
default:
- DEBUG(1,
+ dev_dbg(&link->dev,
"ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
rcsindex,
(unsigned int)readb(&prcs->interrupt_id));
@@ -2186,7 +2175,7 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local,
int rx_len;
unsigned int pkt_addr;
void __iomem *pmsg;
- DEBUG(4, "ray_rx process rx packet\n");
+ pr_debug("ray_rx process rx packet\n");
/* Calculate address of packet within Rx buffer */
pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
@@ -2199,28 +2188,28 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local,
pmsg = local->rmem + pkt_addr;
switch (readb(pmsg)) {
case DATA_TYPE:
- DEBUG(4, "ray_rx data type\n");
+ pr_debug("ray_rx data type\n");
rx_data(dev, prcs, pkt_addr, rx_len);
break;
case AUTHENTIC_TYPE:
- DEBUG(4, "ray_rx authentic type\n");
+ pr_debug("ray_rx authentic type\n");
if (sniffer)
rx_data(dev, prcs, pkt_addr, rx_len);
else
rx_authenticate(local, prcs, pkt_addr, rx_len);
break;
case DEAUTHENTIC_TYPE:
- DEBUG(4, "ray_rx deauth type\n");
+ pr_debug("ray_rx deauth type\n");
if (sniffer)
rx_data(dev, prcs, pkt_addr, rx_len);
else
rx_deauthenticate(local, prcs, pkt_addr, rx_len);
break;
case NULL_MSG_TYPE:
- DEBUG(3, "ray_cs rx NULL msg\n");
+ pr_debug("ray_cs rx NULL msg\n");
break;
case BEACON_TYPE:
- DEBUG(4, "ray_rx beacon type\n");
+ pr_debug("ray_rx beacon type\n");
if (sniffer)
rx_data(dev, prcs, pkt_addr, rx_len);
@@ -2233,7 +2222,7 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local,
ray_get_stats(dev);
break;
default:
- DEBUG(0, "ray_cs unknown pkt type %2x\n",
+ pr_debug("ray_cs unknown pkt type %2x\n",
(unsigned int)readb(pmsg));
break;
}
@@ -2262,7 +2251,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
rx_len >
(dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
FCS_LEN)) {
- DEBUG(0,
+ pr_debug(
"ray_cs invalid packet length %d received \n",
rx_len);
return;
@@ -2273,17 +2262,17 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
rx_len >
(dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
FCS_LEN)) {
- DEBUG(0,
+ pr_debug(
"ray_cs invalid packet length %d received \n",
rx_len);
return;
}
}
}
- DEBUG(4, "ray_cs rx_data packet\n");
+ pr_debug("ray_cs rx_data packet\n");
/* If fragmented packet, verify sizes of fragments add up */
if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
- DEBUG(1, "ray_cs rx'ed fragment\n");
+ pr_debug("ray_cs rx'ed fragment\n");
tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
+ readb(&prcs->var.rx_packet.totalpacketlength[1]);
total_len = tmp;
@@ -2301,7 +2290,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
} while (1);
if (tmp < 0) {
- DEBUG(0,
+ pr_debug(
"ray_cs rx_data fragment lengths don't add up\n");
local->stats.rx_dropped++;
release_frag_chain(local, prcs);
@@ -2313,7 +2302,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
skb = dev_alloc_skb(total_len + 5);
if (skb == NULL) {
- DEBUG(0, "ray_cs rx_data could not allocate skb\n");
+ pr_debug("ray_cs rx_data could not allocate skb\n");
local->stats.rx_dropped++;
if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
release_frag_chain(local, prcs);
@@ -2321,7 +2310,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
}
skb_reserve(skb, 2); /* Align IP on 16 byte (TBD check this) */
- DEBUG(4, "ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
+ pr_debug("ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
rx_len);
/************************/
@@ -2354,7 +2343,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
tmp = 17;
if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
prcslink = prcs;
- DEBUG(1, "ray_cs rx_data in fragment loop\n");
+ pr_debug("ray_cs rx_data in fragment loop\n");
do {
prcslink = rcs_base(local)
+
@@ -2426,8 +2415,8 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
-#ifdef PCMCIA_DEBUG
- if (pc_debug > 3) {
+#if 0
+ if {
print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ",
DUMP_PREFIX_NONE, 16, 1,
skb->data, 64, true);
@@ -2441,7 +2430,7 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
/* not a snap type so leave it alone */
- DEBUG(3, "ray_cs untranslate NOT SNAP %02x %02x %02x\n",
+ pr_debug("ray_cs untranslate NOT SNAP %02x %02x %02x\n",
psnap->dsap, psnap->ssap, psnap->ctrl);
delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
@@ -2450,7 +2439,7 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
} else { /* Its a SNAP */
if (memcmp(psnap->org, org_bridge, 3) == 0) {
/* EtherII and nuke the LLC */
- DEBUG(3, "ray_cs untranslate Bridge encap\n");
+ pr_debug("ray_cs untranslate Bridge encap\n");
delta = RX_MAC_HEADER_LENGTH
+ sizeof(struct snaphdr_t) - ETH_HLEN;
peth = (struct ethhdr *)(skb->data + delta);
@@ -2459,14 +2448,14 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
switch (ntohs(type)) {
case ETH_P_IPX:
case ETH_P_AARP:
- DEBUG(3, "ray_cs untranslate RFC IPX/AARP\n");
+ pr_debug("ray_cs untranslate RFC IPX/AARP\n");
delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
peth = (struct ethhdr *)(skb->data + delta);
peth->h_proto =
htons(len - RX_MAC_HEADER_LENGTH);
break;
default:
- DEBUG(3, "ray_cs untranslate RFC default\n");
+ pr_debug("ray_cs untranslate RFC default\n");
delta = RX_MAC_HEADER_LENGTH +
sizeof(struct snaphdr_t) - ETH_HLEN;
peth = (struct ethhdr *)(skb->data + delta);
@@ -2482,12 +2471,12 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
}
/* TBD reserve skb_reserve(skb, delta); */
skb_pull(skb, delta);
- DEBUG(3, "untranslate after skb_pull(%d), skb->data = %p\n", delta,
+ pr_debug("untranslate after skb_pull(%d), skb->data = %p\n", delta,
skb->data);
memcpy(peth->h_dest, destaddr, ADDRLEN);
memcpy(peth->h_source, srcaddr, ADDRLEN);
-#ifdef PCMCIA_DEBUG
- if (pc_debug > 3) {
+#if 0
+ {
int i;
printk(KERN_DEBUG "skb->data after untranslate:");
for (i = 0; i < 64; i++)
@@ -2529,7 +2518,7 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
while (tmp--) {
writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
- DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n",
+ pr_debug("ray_cs interrupt bad rcsindex = 0x%x\n",
rcsindex);
break;
}
@@ -2543,9 +2532,9 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
static void authenticate(ray_dev_t *local)
{
struct pcmcia_device *link = local->finder;
- DEBUG(0, "ray_cs Starting authentication.\n");
+ dev_dbg(&link->dev, "ray_cs Starting authentication.\n");
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs authenticate - device not present\n");
+ dev_dbg(&link->dev, "ray_cs authenticate - device not present\n");
return;
}
@@ -2573,11 +2562,11 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
/* if we are trying to get authenticated */
if (local->sparm.b4.a_network_type == ADHOC) {
- DEBUG(1, "ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
+ pr_debug("ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
msg->var[0], msg->var[1], msg->var[2], msg->var[3],
msg->var[4], msg->var[5]);
if (msg->var[2] == 1) {
- DEBUG(0, "ray_cs Sending authentication response.\n");
+ pr_debug("ray_cs Sending authentication response.\n");
if (!build_auth_frame
(local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
local->authentication_state = NEED_TO_AUTH;
@@ -2591,13 +2580,13 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
/* Verify authentication sequence #2 and success */
if (msg->var[2] == 2) {
if ((msg->var[3] | msg->var[4]) == 0) {
- DEBUG(1, "Authentication successful\n");
+ pr_debug("Authentication successful\n");
local->card_status = CARD_AUTH_COMPLETE;
associate(local);
local->authentication_state =
AUTHENTICATED;
} else {
- DEBUG(0, "Authentication refused\n");
+ pr_debug("Authentication refused\n");
local->card_status = CARD_AUTH_REFUSED;
join_net((u_long) local);
local->authentication_state =
@@ -2617,22 +2606,22 @@ static void associate(ray_dev_t *local)
struct net_device *dev = link->priv;
int ccsindex;
if (!(pcmcia_dev_present(link))) {
- DEBUG(2, "ray_cs associate - device not present\n");
+ dev_dbg(&link->dev, "ray_cs associate - device not present\n");
return;
}
/* If no tx buffers available, return */
if ((ccsindex = get_free_ccs(local)) < 0) {
/* TBD should never be here but... what if we are? */
- DEBUG(1, "ray_cs associate - No free ccs\n");
+ dev_dbg(&link->dev, "ray_cs associate - No free ccs\n");
return;
}
- DEBUG(1, "ray_cs Starting association with access point\n");
+ dev_dbg(&link->dev, "ray_cs Starting association with access point\n");
pccs = ccs_base(local) + ccsindex;
/* fill in the CCS */
writeb(CCS_START_ASSOCIATION, &pccs->cmd);
/* Interrupt the firmware to process the command */
if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1, "ray_cs associate failed - ECF not ready for intr\n");
+ dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
del_timer(&local->timer);
@@ -2655,7 +2644,7 @@ static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
/* UCHAR buff[256];
struct rx_msg *msg = (struct rx_msg *)buff;
*/
- DEBUG(0, "Deauthentication frame received\n");
+ pr_debug("Deauthentication frame received\n");
local->authentication_state = UNAUTHENTICATED;
/* Need to reauthenticate or rejoin depending on reason code */
/* copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
@@ -2823,7 +2812,7 @@ static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
/* If no tx buffers available, return */
if ((ccsindex = get_free_tx_ccs(local)) < 0) {
- DEBUG(1, "ray_cs send authenticate - No free tx ccs\n");
+ pr_debug("ray_cs send authenticate - No free tx ccs\n");
return -1;
}
@@ -2855,7 +2844,7 @@ static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
/* Interrupt the firmware to process the command */
if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,
+ pr_debug(
"ray_cs send authentication request failed - ECF not ready for intr\n");
writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
return -1;
@@ -2879,7 +2868,7 @@ static int write_essid(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
static char proc_essid[33];
- int len = count;
+ unsigned int len = count;
if (len > 32)
len = 32;
@@ -2942,9 +2931,9 @@ static int __init init_ray_cs(void)
{
int rc;
- DEBUG(1, "%s\n", rcsid);
+ pr_debug("%s\n", rcsid);
rc = pcmcia_register_driver(&ray_driver);
- DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",
+ pr_debug("raylink init_module register_pcmcia_driver returns 0x%x\n",
rc);
#ifdef CONFIG_PROC_FS
@@ -2964,7 +2953,7 @@ static int __init init_ray_cs(void)
static void __exit exit_ray_cs(void)
{
- DEBUG(0, "ray_cs: cleanup_module\n");
+ pr_debug("ray_cs: cleanup_module\n");
#ifdef CONFIG_PROC_FS
remove_proc_entry("driver/ray_cs/ray_cs", NULL);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index a084077a1c61..9fe770f7d7bb 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1994,7 +1994,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
- (skbdesc->entry->entry_idx + 1) : 0xff);
+ txdesc->key_idx : 0xff);
rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
skb->len - txdesc->l2pad);
rt2x00_set_field32(&word, TXWI_W1_PACKETID,
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 71761b343839..73bbec58341e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -815,6 +815,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
mutex_init(&rt2x00dev->csr_mutex);
+ set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+
/*
* Make room for rt2x00_intf inside the per-interface
* structure ieee80211_vif.
@@ -871,8 +873,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
rt2x00leds_register(rt2x00dev);
rt2x00debug_register(rt2x00dev);
- set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
-
return 0;
exit:
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index c64db0ba7f40..c708d0be9155 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -362,8 +362,9 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
rt2x00link_reset_tuner(rt2x00dev, false);
- ieee80211_queue_delayed_work(rt2x00dev->hw,
- &link->work, LINK_TUNE_INTERVAL);
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ ieee80211_queue_delayed_work(rt2x00dev->hw,
+ &link->work, LINK_TUNE_INTERVAL);
}
void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
@@ -469,8 +470,10 @@ static void rt2x00link_tuner(struct work_struct *work)
* Increase tuner counter, and reschedule the next link tuner run.
*/
link->count++;
- ieee80211_queue_delayed_work(rt2x00dev->hw,
- &link->work, LINK_TUNE_INTERVAL);
+
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ ieee80211_queue_delayed_work(rt2x00dev->hw,
+ &link->work, LINK_TUNE_INTERVAL);
}
void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 501544882c2c..f02b48a90593 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -47,6 +47,8 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
(requesttype == USB_VENDOR_REQUEST_IN) ?
usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);
+ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ return -ENODEV;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
status = usb_control_msg(usb_dev, pipe, request, requesttype,
@@ -60,8 +62,10 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
* -ENODEV: Device has disappeared, no point continuing.
* All other errors: Try again.
*/
- else if (status == -ENODEV)
+ else if (status == -ENODEV) {
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
break;
+ }
}
ERROR(rt2x00dev,
@@ -161,6 +165,9 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
{
unsigned int i;
+ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ return -ENODEV;
+
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2x00usb_register_read_lock(rt2x00dev, offset, reg);
if (!rt2x00_get_field32(*reg, field))
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index b8f5ee33445e..14e7bb210075 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2389,10 +2389,13 @@ static struct usb_device_id rt73usb_device_table[] = {
{ USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) },
/* MSI */
+ { USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* Ovislink */
+ { USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) },
/* Ralink */
{ USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
@@ -2420,6 +2423,8 @@ static struct usb_device_id rt73usb_device_table[] = {
/* Planex */
{ USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* WideTell */
+ { USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) },
/* Zcom */
{ USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) },
/* ZyXEL */
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
index a1c670fc1552..cf8a4a40fdf6 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c
@@ -210,10 +210,10 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev)
/* turn the LED off before exiting */
ieee80211_queue_delayed_work(dev, &priv->led_off, 0);
- cancel_delayed_work_sync(&priv->led_off);
- cancel_delayed_work_sync(&priv->led_on);
rtl8187_unregister_led(&priv->led_rx);
rtl8187_unregister_led(&priv->led_tx);
+ cancel_delayed_work_sync(&priv->led_off);
+ cancel_delayed_work_sync(&priv->led_on);
}
#endif /* def CONFIG_RTL8187_LED */
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
index 9fab13e4004e..cad8037ab2af 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
@@ -18,6 +18,7 @@
#include <net/mac80211.h>
#include "rtl8187.h"
+#include "rtl8187_rfkill.h"
static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
{
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 431a20ec6db6..33918fd5b231 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -3656,10 +3656,7 @@ wv_pcmcia_reset(struct net_device * dev)
i = pcmcia_access_configuration_register(link, &reg);
if (i != 0)
- {
- cs_error(link, AccessConfigurationRegister, i);
return FALSE;
- }
#ifdef DEBUG_CONFIG_INFO
printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n",
@@ -3670,19 +3667,13 @@ wv_pcmcia_reset(struct net_device * dev)
reg.Value = reg.Value | COR_SW_RESET;
i = pcmcia_access_configuration_register(link, &reg);
if (i != 0)
- {
- cs_error(link, AccessConfigurationRegister, i);
return FALSE;
- }
reg.Action = CS_WRITE;
reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
i = pcmcia_access_configuration_register(link, &reg);
if (i != 0)
- {
- cs_error(link, AccessConfigurationRegister, i);
return FALSE;
- }
#ifdef DEBUG_CONFIG_TRACE
printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name);
@@ -3857,10 +3848,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
{
i = pcmcia_request_io(link, &link->io);
if (i != 0)
- {
- cs_error(link, RequestIO, i);
break;
- }
/*
* Now allocate an interrupt line. Note that this does not
@@ -3868,10 +3856,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
*/
i = pcmcia_request_irq(link, &link->irq);
if (i != 0)
- {
- cs_error(link, RequestIRQ, i);
break;
- }
/*
* This actually configures the PCMCIA socket -- setting up
@@ -3880,10 +3865,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
link->conf.ConfigIndex = 1;
i = pcmcia_request_configuration(link, &link->conf);
if (i != 0)
- {
- cs_error(link, RequestConfiguration, i);
break;
- }
/*
* Allocate a small memory window. Note that the struct pcmcia_device
@@ -3894,24 +3876,18 @@ wv_pcmcia_config(struct pcmcia_device * link)
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = req.Size = 0;
req.AccessSpeed = mem_speed;
- i = pcmcia_request_window(&link, &req, &link->win);
+ i = pcmcia_request_window(link, &req, &link->win);
if (i != 0)
- {
- cs_error(link, RequestWindow, i);
break;
- }
lp->mem = ioremap(req.Base, req.Size);
dev->mem_start = (u_long)lp->mem;
dev->mem_end = dev->mem_start + req.Size;
mem.CardOffset = 0; mem.Page = 0;
- i = pcmcia_map_mem_page(link->win, &mem);
+ i = pcmcia_map_mem_page(link, link->win, &mem);
if (i != 0)
- {
- cs_error(link, MapMemPage, i);
break;
- }
/* Feed device with this info... */
dev->irq = link->irq.AssignedIRQ;
@@ -3923,7 +3899,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
lp->mem, dev->irq, (u_int) dev->base_addr);
#endif
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
i = register_netdev(dev);
if(i != 0)
{
@@ -4462,8 +4438,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
p_dev->io.IOAddrLines = 3;
/* Interrupt setup */
- p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = wavelan_interrupt;
/* General socket configuration */
@@ -4475,7 +4450,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
if (!dev)
return -ENOMEM;
- p_dev->priv = p_dev->irq.Instance = dev;
+ p_dev->priv = dev;
lp = netdev_priv(dev);
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 4f1e0cfe609b..5f0401a52cff 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -67,23 +67,7 @@
/* For rough constant delay */
#define WL3501_NOPLOOP(n) { int x = 0; while (x++ < n) slow_down_io(); }
-/*
- * All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If you do not
- * define PCMCIA_DEBUG at all, all the debug code will be left out. If you
- * compile with PCMCIA_DEBUG=0, the debug code will be present but disabled --
- * but it can then be enabled for specific modules at load time with a
- * 'pc_debug=#' option to insmod.
- */
-#define PCMCIA_DEBUG 0
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define dprintk(n, format, args...) \
- { if (pc_debug > (n)) \
- printk(KERN_INFO "%s: " format "\n", __func__ , ##args); }
-#else
-#define dprintk(n, format, args...)
-#endif
+
#define wl3501_outb(a, b) { outb(a, b); slow_down_io(); }
#define wl3501_outb_p(a, b) { outb_p(a, b); slow_down_io(); }
@@ -684,10 +668,10 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
int matchflag = 0;
struct wl3501_scan_confirm sig;
- dprintk(3, "entry");
+ pr_debug("entry");
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
if (sig.status == WL3501_STATUS_SUCCESS) {
- dprintk(3, "success");
+ pr_debug("success");
if ((this->net_type == IW_MODE_INFRA &&
(sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
(this->net_type == IW_MODE_ADHOC &&
@@ -722,7 +706,7 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
}
}
} else if (sig.status == WL3501_STATUS_TIMEOUT) {
- dprintk(3, "timeout");
+ pr_debug("timeout");
this->join_sta_bss = 0;
for (i = this->join_sta_bss; i < this->bss_cnt; i++)
if (!wl3501_mgmt_join(this, i))
@@ -879,7 +863,7 @@ static int wl3501_mgmt_auth(struct wl3501_card *this)
.timeout = 1000,
};
- dprintk(3, "entry");
+ pr_debug("entry");
memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
return wl3501_esbq_exec(this, &sig, sizeof(sig));
}
@@ -893,7 +877,7 @@ static int wl3501_mgmt_association(struct wl3501_card *this)
.cap_info = this->cap_info,
};
- dprintk(3, "entry");
+ pr_debug("entry");
memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
return wl3501_esbq_exec(this, &sig, sizeof(sig));
}
@@ -903,7 +887,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
struct wl3501_card *this = netdev_priv(dev);
struct wl3501_join_confirm sig;
- dprintk(3, "entry");
+ pr_debug("entry");
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
if (sig.status == WL3501_STATUS_SUCCESS) {
if (this->net_type == IW_MODE_INFRA) {
@@ -962,7 +946,7 @@ static inline void wl3501_md_confirm_interrupt(struct net_device *dev,
{
struct wl3501_md_confirm sig;
- dprintk(3, "entry");
+ pr_debug("entry");
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
wl3501_free_tx_buffer(this, sig.data);
if (netif_queue_stopped(dev))
@@ -1017,7 +1001,7 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this,
u16 addr, void *sig, int size)
{
- dprintk(3, "entry");
+ pr_debug("entry");
wl3501_get_from_wla(this, addr, &this->sig_get_confirm,
sizeof(this->sig_get_confirm));
wake_up(&this->wait);
@@ -1029,7 +1013,7 @@ static inline void wl3501_start_confirm_interrupt(struct net_device *dev,
{
struct wl3501_start_confirm sig;
- dprintk(3, "entry");
+ pr_debug("entry");
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
if (sig.status == WL3501_STATUS_SUCCESS)
netif_wake_queue(dev);
@@ -1041,7 +1025,7 @@ static inline void wl3501_assoc_confirm_interrupt(struct net_device *dev,
struct wl3501_card *this = netdev_priv(dev);
struct wl3501_assoc_confirm sig;
- dprintk(3, "entry");
+ pr_debug("entry");
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
if (sig.status == WL3501_STATUS_SUCCESS)
@@ -1053,7 +1037,7 @@ static inline void wl3501_auth_confirm_interrupt(struct wl3501_card *this,
{
struct wl3501_auth_confirm sig;
- dprintk(3, "entry");
+ pr_debug("entry");
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
if (sig.status == WL3501_STATUS_SUCCESS)
@@ -1069,7 +1053,7 @@ static inline void wl3501_rx_interrupt(struct net_device *dev)
u8 sig_id;
struct wl3501_card *this = netdev_priv(dev);
- dprintk(3, "entry");
+ pr_debug("entry");
loop:
morepkts = 0;
if (!wl3501_esbq_confirm(this))
@@ -1302,7 +1286,7 @@ static int wl3501_reset(struct net_device *dev)
wl3501_ack_interrupt(this);
wl3501_unblock_interrupt(this);
wl3501_mgmt_scan(this, 100);
- dprintk(1, "%s: device reset", dev->name);
+ pr_debug("%s: device reset", dev->name);
rc = 0;
out:
return rc;
@@ -1376,7 +1360,7 @@ static int wl3501_open(struct net_device *dev)
link->open++;
/* Initial WL3501 firmware */
- dprintk(1, "%s: Initialize WL3501 firmware...", dev->name);
+ pr_debug("%s: Initialize WL3501 firmware...", dev->name);
if (wl3501_init_firmware(this))
goto fail;
/* Initial device variables */
@@ -1388,7 +1372,7 @@ static int wl3501_open(struct net_device *dev)
wl3501_unblock_interrupt(this);
wl3501_mgmt_scan(this, 100);
rc = 0;
- dprintk(1, "%s: WL3501 opened", dev->name);
+ pr_debug("%s: WL3501 opened", dev->name);
printk(KERN_INFO "%s: Card Name: %s\n"
"%s: Firmware Date: %s\n",
dev->name, this->card_name,
@@ -1914,8 +1898,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
p_dev->io.IOAddrLines = 5;
/* Interrupt setup */
- p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = wl3501_interrupt;
/* General socket configuration */
@@ -1938,16 +1921,13 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
dev->wireless_handlers = &wl3501_handler_def;
SET_ETHTOOL_OPS(dev, &ops);
netif_stop_queue(dev);
- p_dev->priv = p_dev->irq.Instance = dev;
+ p_dev->priv = dev;
return wl3501_config(p_dev);
out_link:
return -ENOMEM;
}
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
/**
* wl3501_config - configure the PCMCIA socket and make eth device available
* @link - FILL_IN
@@ -1959,7 +1939,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int wl3501_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- int i = 0, j, last_fn, last_ret;
+ int i = 0, j, ret;
struct wl3501_card *this;
/* Try allocating IO ports. This tries a few fixed addresses. If you
@@ -1975,24 +1955,26 @@ static int wl3501_config(struct pcmcia_device *link)
if (i == 0)
break;
}
- if (i != 0) {
- cs_error(link, RequestIO, i);
+ if (i != 0)
goto failed;
- }
/* Now allocate an interrupt line. Note that this does not actually
* assign a handler to the interrupt. */
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
/* This actually configures the PCMCIA socket -- setting up the I/O
* windows and the interrupt mapping. */
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev)) {
printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
goto failed;
@@ -2041,8 +2023,6 @@ static int wl3501_config(struct pcmcia_device *link)
netif_start_queue(dev);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
wl3501_release(link);
return -ENODEV;
diff --git a/drivers/net/znet.c b/drivers/net/znet.c
index a0384b6f09b6..b42347333750 100644
--- a/drivers/net/znet.c
+++ b/drivers/net/znet.c
@@ -169,7 +169,6 @@ static void znet_tx_timeout (struct net_device *dev);
static int znet_request_resources (struct net_device *dev)
{
struct znet_private *znet = netdev_priv(dev);
- unsigned long flags;
if (request_irq (dev->irq, &znet_interrupt, 0, "ZNet", dev))
goto failed;
@@ -187,13 +186,9 @@ static int znet_request_resources (struct net_device *dev)
free_sia:
release_region (znet->sia_base, znet->sia_size);
free_tx_dma:
- flags = claim_dma_lock();
free_dma (znet->tx_dma);
- release_dma_lock (flags);
free_rx_dma:
- flags = claim_dma_lock();
free_dma (znet->rx_dma);
- release_dma_lock (flags);
free_irq:
free_irq (dev->irq, dev);
failed:
@@ -203,14 +198,11 @@ static int znet_request_resources (struct net_device *dev)
static void znet_release_resources (struct net_device *dev)
{
struct znet_private *znet = netdev_priv(dev);
- unsigned long flags;
release_region (znet->sia_base, znet->sia_size);
release_region (dev->base_addr, znet->io_size);
- flags = claim_dma_lock();
free_dma (znet->tx_dma);
free_dma (znet->rx_dma);
- release_dma_lock (flags);
free_irq (dev->irq, dev);
}
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index bacaa536fd51..4b22ba568b19 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -97,6 +97,12 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
}
EXPORT_SYMBOL(of_mdiobus_register);
+/* Helper function for of_phy_find_device */
+static int of_phy_match(struct device *dev, void *phy_np)
+{
+ return dev_archdata_get_node(&dev->archdata) == phy_np;
+}
+
/**
* of_phy_find_device - Give a PHY node, find the phy_device
* @phy_np: Pointer to the phy's device tree node
@@ -106,15 +112,10 @@ EXPORT_SYMBOL(of_mdiobus_register);
struct phy_device *of_phy_find_device(struct device_node *phy_np)
{
struct device *d;
- int match(struct device *dev, void *phy_np)
- {
- return dev_archdata_get_node(&dev->archdata) == phy_np;
- }
-
if (!phy_np)
return NULL;
- d = bus_find_device(&mdio_bus_type, NULL, phy_np, match);
+ d = bus_find_device(&mdio_bus_type, NULL, phy_np, of_phy_match);
return d ? to_phy_device(d) : NULL;
}
EXPORT_SYMBOL(of_phy_find_device);
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
index 2b7ae366ceb1..5df60a6b6776 100644
--- a/drivers/oprofile/event_buffer.c
+++ b/drivers/oprofile/event_buffer.c
@@ -35,12 +35,23 @@ static size_t buffer_pos;
/* atomic_t because wait_event checks it outside of buffer_mutex */
static atomic_t buffer_ready = ATOMIC_INIT(0);
-/* Add an entry to the event buffer. When we
- * get near to the end we wake up the process
- * sleeping on the read() of the file.
+/*
+ * Add an entry to the event buffer. When we get near to the end we
+ * wake up the process sleeping on the read() of the file. To protect
+ * the event_buffer this function may only be called when buffer_mutex
+ * is set.
*/
void add_event_entry(unsigned long value)
{
+ /*
+ * This shouldn't happen since all workqueues or handlers are
+ * canceled or flushed before the event buffer is freed.
+ */
+ if (!event_buffer) {
+ WARN_ON_ONCE(1);
+ return;
+ }
+
if (buffer_pos == buffer_size) {
atomic_inc(&oprofile_stats.event_lost_overflow);
return;
@@ -69,7 +80,6 @@ void wake_up_buffer_waiter(void)
int alloc_event_buffer(void)
{
- int err = -ENOMEM;
unsigned long flags;
spin_lock_irqsave(&oprofilefs_lock, flags);
@@ -80,21 +90,22 @@ int alloc_event_buffer(void)
if (buffer_watershed >= buffer_size)
return -EINVAL;
+ buffer_pos = 0;
event_buffer = vmalloc(sizeof(unsigned long) * buffer_size);
if (!event_buffer)
- goto out;
+ return -ENOMEM;
- err = 0;
-out:
- return err;
+ return 0;
}
void free_event_buffer(void)
{
+ mutex_lock(&buffer_mutex);
vfree(event_buffer);
-
+ buffer_pos = 0;
event_buffer = NULL;
+ mutex_unlock(&buffer_mutex);
}
@@ -167,6 +178,12 @@ static ssize_t event_buffer_read(struct file *file, char __user *buf,
mutex_lock(&buffer_mutex);
+ /* May happen if the buffer is freed during pending reads. */
+ if (!event_buffer) {
+ retval = -EINTR;
+ goto out;
+ }
+
atomic_set(&buffer_ready, 0);
retval = -EFAULT;
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 8fdfa4f537a6..7dd370fa3439 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -67,14 +67,6 @@ MODULE_LICENSE("Dual MPL/GPL");
INT_MODULE_PARM(epp_mode, 1);
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"parport_cs.c 1.29 2002/10/11 06:57:41 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -103,7 +95,7 @@ static int parport_probe(struct pcmcia_device *link)
{
parport_info_t *info;
- DEBUG(0, "parport_attach()\n");
+ dev_dbg(&link->dev, "parport_attach()\n");
/* Create new parport device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -114,7 +106,6 @@ static int parport_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -132,7 +123,7 @@ static int parport_probe(struct pcmcia_device *link)
static void parport_detach(struct pcmcia_device *link)
{
- DEBUG(0, "parport_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "parport_detach\n");
parport_cs_release(link);
@@ -147,9 +138,6 @@ static void parport_detach(struct pcmcia_device *link)
======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int parport_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
@@ -178,18 +166,20 @@ static int parport_config(struct pcmcia_device *link)
{
parport_info_t *info = link->priv;
struct parport *p;
- int last_ret, last_fn;
+ int ret;
- DEBUG(0, "parport_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "parport_config\n");
- last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
- if (last_ret) {
- cs_error(link, RequestIO, last_ret);
+ ret = pcmcia_loop_config(link, parport_config_check, NULL);
+ if (ret)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
link->irq.AssignedIRQ, PARPORT_DMA_NONE,
@@ -213,8 +203,6 @@ static int parport_config(struct pcmcia_device *link)
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
parport_cs_release(link);
return -ENODEV;
@@ -232,7 +220,7 @@ static void parport_cs_release(struct pcmcia_device *link)
{
parport_info_t *info = link->priv;
- DEBUG(0, "parport_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "parport_release\n");
if (info->ndev) {
struct parport *p = info->port;
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 22b02c6df854..416f6ac65b76 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -175,15 +175,6 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
int ret = 0;
drhd = (struct acpi_dmar_hardware_unit *)header;
- if (!drhd->address) {
- /* Promote an attitude of violence to a BIOS engineer today */
- WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
- dmi_get_system_info(DMI_BIOS_VENDOR),
- dmi_get_system_info(DMI_BIOS_VERSION),
- dmi_get_system_info(DMI_PRODUCT_VERSION));
- return -ENODEV;
- }
dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
if (!dmaru)
return -ENOMEM;
@@ -591,12 +582,53 @@ int __init dmar_table_init(void)
return 0;
}
+int __init check_zero_address(void)
+{
+ struct acpi_table_dmar *dmar;
+ struct acpi_dmar_header *entry_header;
+ struct acpi_dmar_hardware_unit *drhd;
+
+ dmar = (struct acpi_table_dmar *)dmar_tbl;
+ entry_header = (struct acpi_dmar_header *)(dmar + 1);
+
+ while (((unsigned long)entry_header) <
+ (((unsigned long)dmar) + dmar_tbl->length)) {
+ /* Avoid looping forever on bad ACPI tables */
+ if (entry_header->length == 0) {
+ printk(KERN_WARNING PREFIX
+ "Invalid 0-length structure\n");
+ return 0;
+ }
+
+ if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
+ drhd = (void *)entry_header;
+ if (!drhd->address) {
+ /* Promote an attitude of violence to a BIOS engineer today */
+ WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
+ "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+ dmi_get_system_info(DMI_BIOS_VENDOR),
+ dmi_get_system_info(DMI_BIOS_VERSION),
+ dmi_get_system_info(DMI_PRODUCT_VERSION));
+#ifdef CONFIG_DMAR
+ dmar_disabled = 1;
+#endif
+ return 0;
+ }
+ break;
+ }
+
+ entry_header = ((void *)entry_header + entry_header->length);
+ }
+ return 1;
+}
+
void __init detect_intel_iommu(void)
{
int ret;
ret = dmar_table_detect();
-
+ if (ret)
+ ret = check_zero_address();
{
#ifdef CONFIG_INTR_REMAP
struct acpi_table_dmar *dmar;
@@ -613,10 +645,13 @@ void __init detect_intel_iommu(void)
"x2apic and Intr-remapping.\n");
#endif
#ifdef CONFIG_DMAR
- if (ret && !no_iommu && !iommu_detected && !swiotlb &&
- !dmar_disabled)
+ if (ret && !no_iommu && !iommu_detected && !dmar_disabled)
iommu_detected = 1;
#endif
+#ifdef CONFIG_X86
+ if (ret)
+ x86_init.iommu.iommu_init = intel_iommu_init;
+#endif
}
early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
dmar_tbl = NULL;
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index b1e97e682500..9261327b49f3 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -2767,7 +2767,15 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
size = PAGE_ALIGN(size);
order = get_order(size);
- flags &= ~(GFP_DMA | GFP_DMA32);
+
+ if (!iommu_no_mapping(hwdev))
+ flags &= ~(GFP_DMA | GFP_DMA32);
+ else if (hwdev->coherent_dma_mask < dma_get_required_mask(hwdev)) {
+ if (hwdev->coherent_dma_mask < DMA_BIT_MASK(32))
+ flags |= GFP_DMA;
+ else
+ flags |= GFP_DMA32;
+ }
vaddr = (void *)__get_free_pages(flags, order);
if (!vaddr)
@@ -3207,6 +3215,33 @@ static int __init init_iommu_sysfs(void)
}
#endif /* CONFIG_PM */
+/*
+ * Here we only respond to action of unbound device from driver.
+ *
+ * Added device is not attached to its DMAR domain here yet. That will happen
+ * when mapping the device to iova.
+ */
+static int device_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct dmar_domain *domain;
+
+ domain = find_domain(pdev);
+ if (!domain)
+ return 0;
+
+ if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through)
+ domain_remove_one_dev_info(domain, pdev);
+
+ return 0;
+}
+
+static struct notifier_block device_nb = {
+ .notifier_call = device_notifier,
+};
+
int __init intel_iommu_init(void)
{
int ret = 0;
@@ -3231,7 +3266,7 @@ int __init intel_iommu_init(void)
* Check the need for DMA-remapping initialization now.
* Above initialization will also be used by Interrupt-remapping.
*/
- if (no_iommu || swiotlb || dmar_disabled)
+ if (no_iommu || dmar_disabled)
return -ENODEV;
iommu_init_mempool();
@@ -3252,13 +3287,17 @@ int __init intel_iommu_init(void)
"PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
init_timer(&unmap_timer);
- force_iommu = 1;
+#ifdef CONFIG_SWIOTLB
+ swiotlb = 0;
+#endif
dma_ops = &intel_dma_ops;
init_iommu_sysfs();
register_iommu(&intel_iommu_ops);
+ bus_register_notifier(&pci_bus_type, &device_nb);
+
return 0;
}
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 745402e8e498..5b7056cec00c 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -656,8 +656,10 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
free_link_state(link);
/* Recheck latencies and configure upstream links */
- pcie_update_aspm_capable(root);
- pcie_config_aspm_path(parent_link);
+ if (parent_link) {
+ pcie_update_aspm_capable(root);
+ pcie_config_aspm_path(parent_link);
+ }
out:
mutex_unlock(&aspm_lock);
up_read(&pci_bus_sem);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index a790b1771f9f..245d2cdb4765 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1009,7 +1009,7 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX,
static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
{
- /* set SBX00 SATA in IDE mode to AHCI mode */
+ /* set SBX00/Hudson-2 SATA in IDE mode to AHCI mode */
u8 tmp;
pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &tmp);
@@ -1028,8 +1028,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk
DECLARE_PCI_FIXUP_RESUME_EARLY(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_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB900_SATA_IDE, quirk_amd_ide_mode);
-DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB900_SATA_IDE, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode);
/*
* Serverworks CSB5 IDE does not fully support native mode
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 0959430534b2..cb1a027eb552 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -299,17 +299,8 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon
r = bus->resource[i];
if (r == &ioport_resource || r == &iomem_resource)
continue;
- if (r && (r->flags & type_mask) == type) {
- if (!r->parent)
- return r;
- /*
- * if there is no child under that, we should release
- * and use it. don't need to reset it, pbus_size_* will
- * set it again
- */
- if (!r->child && !release_resource(r))
- return r;
- }
+ if (r && (r->flags & type_mask) == type && !r->parent)
+ return r;
}
return NULL;
}
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 17f38a781d47..f3ccbccf5f21 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -17,24 +17,6 @@ menuconfig PCCARD
if PCCARD
-config PCMCIA_DEBUG
- bool "Enable PCCARD debugging"
- help
- Say Y here to enable PCMCIA subsystem debugging. You
- will need to choose the debugging level either via the
- kernel command line, or module options depending whether
- you build the PCMCIA as modules.
-
- The kernel command line options are:
- pcmcia_core.pc_debug=N
- pcmcia.pc_debug=N
- sa11xx_core.pc_debug=N
-
- The module option is called pc_debug=N
-
- In all the above examples, N is the debugging verbosity
- level.
-
config PCMCIA
tristate "16-bit PCMCIA support"
select CRC32
@@ -196,9 +178,13 @@ config PCMCIA_BCM63XX
tristate "bcm63xx pcmcia support"
depends on BCM63XX && PCMCIA
+config PCMCIA_SOC_COMMON
+ bool
+
config PCMCIA_SA1100
tristate "SA1100 support"
depends on ARM && ARCH_SA1100 && PCMCIA
+ select PCMCIA_SOC_COMMON
help
Say Y here to include support for SA11x0-based PCMCIA or CF
sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
@@ -209,6 +195,7 @@ config PCMCIA_SA1100
config PCMCIA_SA1111
tristate "SA1111 support"
depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA
+ select PCMCIA_SOC_COMMON
help
Say Y here to include support for SA1111-based PCMCIA or CF
sockets, found on the Jornada 720, Graphicsmaster and other
@@ -222,9 +209,28 @@ config PCMCIA_PXA2XX
depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
|| MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
|| ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2)
+ select PCMCIA_SOC_COMMON
help
Say Y here to include support for the PXA2xx PCMCIA controller
+config PCMCIA_DEBUG
+ bool "Enable debugging"
+ depends on (PCMCIA_SA1111 || PCMCIA_SA1100 || PCMCIA_PXA2XX)
+ help
+ Say Y here to enable debugging for the SoC PCMCIA layer.
+ You will need to choose the debugging level either via the
+ kernel command line, or module options depending whether
+ you build the drivers as modules.
+
+ The kernel command line options are:
+ sa11xx_core.pc_debug=N
+ pxa2xx_core.pc_debug=N
+
+ The module option is called pc_debug=N
+
+ In all the above examples, N is the debugging verbosity
+ level.
+
config PCMCIA_PROBE
bool
default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index a03a38acd77d..382938313991 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -22,8 +22,9 @@ obj-$(CONFIG_I82365) += i82365.o
obj-$(CONFIG_I82092) += i82092.o
obj-$(CONFIG_TCIC) += tcic.o
obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
-obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
-obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
+obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o
+obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o
+obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o
obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
@@ -35,9 +36,6 @@ obj-$(CONFIG_BFIN_CFPCMCIA) += bfin_cf_pcmcia.o
obj-$(CONFIG_AT91_CF) += at91_cf.o
obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
-sa11xx_core-y += soc_common.o sa11xx_base.o
-pxa2xx_core-y += soc_common.o pxa2xx_base.o
-
au1x00_ss-y += au1000_generic.o
au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o
au1x00_ss-$(CONFIG_MIPS_PB1100) += au1000_pb1x00.o
@@ -77,4 +75,4 @@ pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
-obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y)
+obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y)
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index db77e1f3309a..4cd70d056810 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -91,7 +91,7 @@ static u_int xlate_rom_addr(void __iomem *b, u_int addr)
static void cb_release_cis_mem(struct pcmcia_socket * s)
{
if (s->cb_cis_virt) {
- cs_dbg(s, 1, "cb_release_cis_mem()\n");
+ dev_dbg(&s->dev, "cb_release_cis_mem()\n");
iounmap(s->cb_cis_virt);
s->cb_cis_virt = NULL;
s->cb_cis_res = NULL;
@@ -132,7 +132,7 @@ int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void
struct pci_dev *dev;
struct resource *res;
- cs_dbg(s, 3, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
+ dev_dbg(&s->dev, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
dev = pci_get_slot(s->cb_dev->subordinate, 0);
if (!dev)
diff --git a/drivers/pcmcia/cirrus.h b/drivers/pcmcia/cirrus.h
index ecd4fc7f666f..446a4576e73e 100644
--- a/drivers/pcmcia/cirrus.h
+++ b/drivers/pcmcia/cirrus.h
@@ -30,16 +30,6 @@
#ifndef _LINUX_CIRRUS_H
#define _LINUX_CIRRUS_H
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS 0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_6729
-#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_6832
-#define PCI_DEVICE_ID_CIRRUS_6832 0x1110
-#endif
-
#define PD67_MISC_CTL_1 0x16 /* Misc control 1 */
#define PD67_FIFO_CTL 0x17 /* FIFO control */
#define PD67_MISC_CTL_2 0x1E /* Misc control 2 */
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 4a110b7b2673..8c1b73cf021b 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -138,7 +138,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
void __iomem *sys, *end;
unsigned char *buf = ptr;
- cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+ dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed
@@ -190,7 +190,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
addr = 0;
}
}
- cs_dbg(s, 3, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
+ dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
*(u_char *)(ptr+0), *(u_char *)(ptr+1),
*(u_char *)(ptr+2), *(u_char *)(ptr+3));
return 0;
@@ -204,7 +204,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
void __iomem *sys, *end;
unsigned char *buf = ptr;
- cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+ dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed
@@ -584,7 +584,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
ofs += link[1] + 2;
}
if (i == MAX_TUPLES) {
- cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
+ dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
return -ENOSPC;
}
@@ -1440,7 +1440,7 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
break;
}
if (ret)
- __cs_dbg(0, "parse_tuple failed %d\n", ret);
+ pr_debug("parse_tuple failed %d\n", ret);
return ret;
}
EXPORT_SYMBOL(pcmcia_parse_tuple);
@@ -1463,7 +1463,9 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
return -ENOMEM;
}
tuple.DesiredTuple = code;
- tuple.Attributes = TUPLE_RETURN_COMMON;
+ tuple.Attributes = 0;
+ if (function == BIND_FN_ALL)
+ tuple.Attributes = TUPLE_RETURN_COMMON;
ret = pccard_get_first_tuple(s, function, &tuple);
if (ret != 0)
goto done;
@@ -1480,6 +1482,67 @@ done:
}
EXPORT_SYMBOL(pccard_read_tuple);
+
+/**
+ * pccard_loop_tuple() - loop over tuples in the CIS
+ * @s: the struct pcmcia_socket where the card is inserted
+ * @function: the device function we loop for
+ * @code: which CIS code shall we look for?
+ * @parse: buffer where the tuple shall be parsed (or NULL, if no parse)
+ * @priv_data: private data to be passed to the loop_tuple function.
+ * @loop_tuple: function to call for each CIS entry of type @function. IT
+ * gets passed the raw tuple, the paresed tuple (if @parse is
+ * set) and @priv_data.
+ *
+ * pccard_loop_tuple() loops over all CIS entries of type @function, and
+ * calls the @loop_tuple function for each entry. If the call to @loop_tuple
+ * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
+ */
+int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
+ cisdata_t code, cisparse_t *parse, void *priv_data,
+ int (*loop_tuple) (tuple_t *tuple,
+ cisparse_t *parse,
+ void *priv_data))
+{
+ tuple_t tuple;
+ cisdata_t *buf;
+ int ret;
+
+ buf = kzalloc(256, GFP_KERNEL);
+ if (buf == NULL) {
+ dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
+ return -ENOMEM;
+ }
+
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = 255;
+ tuple.TupleOffset = 0;
+ tuple.DesiredTuple = code;
+ tuple.Attributes = 0;
+
+ ret = pccard_get_first_tuple(s, function, &tuple);
+ while (!ret) {
+ if (pccard_get_tuple_data(s, &tuple))
+ goto next_entry;
+
+ if (parse)
+ if (pcmcia_parse_tuple(&tuple, parse))
+ goto next_entry;
+
+ ret = loop_tuple(&tuple, parse, priv_data);
+ if (!ret)
+ break;
+
+next_entry:
+ ret = pccard_get_next_tuple(s, function, &tuple);
+ }
+
+ kfree(buf);
+ return ret;
+}
+EXPORT_SYMBOL(pccard_loop_tuple);
+
+
/*======================================================================
This tries to determine if a card has a sensible CIS. It returns
@@ -1490,7 +1553,7 @@ EXPORT_SYMBOL(pccard_read_tuple);
======================================================================*/
-int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *info)
+int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
{
tuple_t *tuple;
cisparse_t *p;
@@ -1515,30 +1578,30 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
count = reserved = 0;
tuple->DesiredTuple = RETURN_FIRST_TUPLE;
tuple->Attributes = TUPLE_RETURN_COMMON;
- ret = pccard_get_first_tuple(s, function, tuple);
+ ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
if (ret != 0)
goto done;
/* First tuple should be DEVICE; we should really have either that
or a CFTABLE_ENTRY of some sort */
if ((tuple->TupleCode == CISTPL_DEVICE) ||
- (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == 0) ||
- (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
+ (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p) == 0) ||
+ (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
dev_ok++;
/* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
tuple, for card identification. Certain old D-Link and Linksys
cards have only a broken VERS_2 tuple; hence the bogus test. */
- if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) ||
- (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) ||
- (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC))
+ if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
+ (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
+ (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
ident_ok++;
if (!dev_ok && !ident_ok)
goto done;
for (count = 1; count < MAX_TUPLES; count++) {
- ret = pccard_get_next_tuple(s, function, tuple);
+ ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
if (ret != 0)
break;
if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 934d4bee39a0..790af87a922f 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -61,17 +61,6 @@ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
/* Access speed for attribute memory windows */
INT_MODULE_PARM(cis_speed, 300); /* ns */
-#ifdef CONFIG_PCMCIA_DEBUG
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-
-int cs_debug_level(int level)
-{
- return pc_debug > level;
-}
-#endif
-
socket_state_t dead_socket = {
.csc_mask = SS_DETECT,
@@ -98,10 +87,13 @@ EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
* These functions check for the appropriate struct pcmcia_soket arrays,
* and pass them to the low-level functions pcmcia_{suspend,resume}_socket
*/
+static int socket_early_resume(struct pcmcia_socket *skt);
+static int socket_late_resume(struct pcmcia_socket *skt);
static int socket_resume(struct pcmcia_socket *skt);
static int socket_suspend(struct pcmcia_socket *skt);
-int pcmcia_socket_dev_suspend(struct device *dev)
+static void pcmcia_socket_dev_run(struct device *dev,
+ int (*cb)(struct pcmcia_socket *))
{
struct pcmcia_socket *socket;
@@ -110,29 +102,34 @@ int pcmcia_socket_dev_suspend(struct device *dev)
if (socket->dev.parent != dev)
continue;
mutex_lock(&socket->skt_mutex);
- socket_suspend(socket);
+ cb(socket);
mutex_unlock(&socket->skt_mutex);
}
up_read(&pcmcia_socket_list_rwsem);
+}
+int pcmcia_socket_dev_suspend(struct device *dev)
+{
+ pcmcia_socket_dev_run(dev, socket_suspend);
return 0;
}
EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
-int pcmcia_socket_dev_resume(struct device *dev)
+void pcmcia_socket_dev_early_resume(struct device *dev)
{
- struct pcmcia_socket *socket;
+ pcmcia_socket_dev_run(dev, socket_early_resume);
+}
+EXPORT_SYMBOL(pcmcia_socket_dev_early_resume);
- down_read(&pcmcia_socket_list_rwsem);
- list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
- if (socket->dev.parent != dev)
- continue;
- mutex_lock(&socket->skt_mutex);
- socket_resume(socket);
- mutex_unlock(&socket->skt_mutex);
- }
- up_read(&pcmcia_socket_list_rwsem);
+void pcmcia_socket_dev_late_resume(struct device *dev)
+{
+ pcmcia_socket_dev_run(dev, socket_late_resume);
+}
+EXPORT_SYMBOL(pcmcia_socket_dev_late_resume);
+int pcmcia_socket_dev_resume(struct device *dev)
+{
+ pcmcia_socket_dev_run(dev, socket_resume);
return 0;
}
EXPORT_SYMBOL(pcmcia_socket_dev_resume);
@@ -182,7 +179,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
return -EINVAL;
- cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops);
+ dev_dbg(&socket->dev, "pcmcia_register_socket(0x%p)\n", socket->ops);
spin_lock_init(&socket->lock);
@@ -254,6 +251,13 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
pcmcia_parse_events(socket, SS_DETECT);
+ /*
+ * Let's try to get the PCMCIA module for 16-bit PCMCIA support.
+ * If it fails, it doesn't matter -- we still have 32-bit CardBus
+ * support to offer, so this is not a failure mode.
+ */
+ request_module_nowait("pcmcia");
+
return 0;
err:
@@ -274,7 +278,7 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket)
if (!socket)
return;
- cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
+ dev_dbg(&socket->dev, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
if (socket->thread)
kthread_stop(socket->thread);
@@ -327,7 +331,7 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
if (s->state & SOCKET_CARDBUS)
return 0;
- cs_dbg(s, 1, "send_event(event %d, pri %d, callback 0x%p)\n",
+ dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n",
event, priority, s->callback);
if (!s->callback)
@@ -344,7 +348,7 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
static void socket_remove_drivers(struct pcmcia_socket *skt)
{
- cs_dbg(skt, 4, "remove_drivers\n");
+ dev_dbg(&skt->dev, "remove_drivers\n");
send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
}
@@ -353,7 +357,7 @@ static int socket_reset(struct pcmcia_socket *skt)
{
int status, i;
- cs_dbg(skt, 4, "reset\n");
+ dev_dbg(&skt->dev, "reset\n");
skt->socket.flags |= SS_OUTPUT_ENA | SS_RESET;
skt->ops->set_socket(skt, &skt->socket);
@@ -375,7 +379,7 @@ static int socket_reset(struct pcmcia_socket *skt)
msleep(unreset_check * 10);
}
- cs_err(skt, "time out after reset.\n");
+ dev_printk(KERN_ERR, &skt->dev, "time out after reset.\n");
return -ETIMEDOUT;
}
@@ -389,7 +393,7 @@ static void socket_shutdown(struct pcmcia_socket *s)
{
int status;
- cs_dbg(s, 4, "shutdown\n");
+ dev_dbg(&s->dev, "shutdown\n");
socket_remove_drivers(s);
s->state &= SOCKET_INUSE | SOCKET_PRESENT;
@@ -424,7 +428,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
{
int status, i;
- cs_dbg(skt, 4, "setup\n");
+ dev_dbg(&skt->dev, "setup\n");
skt->ops->get_status(skt, &status);
if (!(status & SS_DETECT))
@@ -444,13 +448,15 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
}
if (status & SS_PENDING) {
- cs_err(skt, "voltage interrogation timed out.\n");
+ dev_printk(KERN_ERR, &skt->dev,
+ "voltage interrogation timed out.\n");
return -ETIMEDOUT;
}
if (status & SS_CARDBUS) {
if (!(skt->features & SS_CAP_CARDBUS)) {
- cs_err(skt, "cardbus cards are not supported.\n");
+ dev_printk(KERN_ERR, &skt->dev,
+ "cardbus cards are not supported.\n");
return -EINVAL;
}
skt->state |= SOCKET_CARDBUS;
@@ -464,7 +470,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
else if (!(status & SS_XVCARD))
skt->socket.Vcc = skt->socket.Vpp = 50;
else {
- cs_err(skt, "unsupported voltage key.\n");
+ dev_printk(KERN_ERR, &skt->dev, "unsupported voltage key.\n");
return -EIO;
}
@@ -481,7 +487,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
skt->ops->get_status(skt, &status);
if (!(status & SS_POWERON)) {
- cs_err(skt, "unable to apply power.\n");
+ dev_printk(KERN_ERR, &skt->dev, "unable to apply power.\n");
return -EIO;
}
@@ -501,7 +507,7 @@ static int socket_insert(struct pcmcia_socket *skt)
{
int ret;
- cs_dbg(skt, 4, "insert\n");
+ dev_dbg(&skt->dev, "insert\n");
if (!cs_socket_get(skt))
return -ENODEV;
@@ -521,7 +527,7 @@ static int socket_insert(struct pcmcia_socket *skt)
skt->state |= SOCKET_CARDBUS_CONFIG;
}
#endif
- cs_dbg(skt, 4, "insert done\n");
+ dev_dbg(&skt->dev, "insert done\n");
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
} else {
@@ -546,34 +552,29 @@ static int socket_suspend(struct pcmcia_socket *skt)
return 0;
}
-/*
- * Resume a socket. If a card is present, verify its CIS against
- * our cached copy. If they are different, the card has been
- * replaced, and we need to tell the drivers.
- */
-static int socket_resume(struct pcmcia_socket *skt)
+static int socket_early_resume(struct pcmcia_socket *skt)
{
- int ret;
-
- if (!(skt->state & SOCKET_SUSPEND))
- return -EBUSY;
-
skt->socket = dead_socket;
skt->ops->init(skt);
skt->ops->set_socket(skt, &skt->socket);
+ if (skt->state & SOCKET_PRESENT)
+ skt->resume_status = socket_setup(skt, resume_delay);
+ return 0;
+}
+static int socket_late_resume(struct pcmcia_socket *skt)
+{
if (!(skt->state & SOCKET_PRESENT)) {
skt->state &= ~SOCKET_SUSPEND;
return socket_insert(skt);
}
- ret = socket_setup(skt, resume_delay);
- if (ret == 0) {
+ if (skt->resume_status == 0) {
/*
* FIXME: need a better check here for cardbus cards.
*/
if (verify_cis_cache(skt) != 0) {
- cs_dbg(skt, 4, "cis mismatch - different card\n");
+ dev_dbg(&skt->dev, "cis mismatch - different card\n");
socket_remove_drivers(skt);
destroy_cis_cache(skt);
/*
@@ -584,7 +585,7 @@ static int socket_resume(struct pcmcia_socket *skt)
msleep(200);
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
} else {
- cs_dbg(skt, 4, "cis matches cache\n");
+ dev_dbg(&skt->dev, "cis matches cache\n");
send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
}
} else {
@@ -596,6 +597,20 @@ static int socket_resume(struct pcmcia_socket *skt)
return 0;
}
+/*
+ * Resume a socket. If a card is present, verify its CIS against
+ * our cached copy. If they are different, the card has been
+ * replaced, and we need to tell the drivers.
+ */
+static int socket_resume(struct pcmcia_socket *skt)
+{
+ if (!(skt->state & SOCKET_SUSPEND))
+ return -EBUSY;
+
+ socket_early_resume(skt);
+ return socket_late_resume(skt);
+}
+
static void socket_remove(struct pcmcia_socket *skt)
{
dev_printk(KERN_NOTICE, &skt->dev,
@@ -706,7 +721,7 @@ static int pccardd(void *__skt)
void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
{
unsigned long flags;
- cs_dbg(s, 4, "parse_events: events %08x\n", events);
+ dev_dbg(&s->dev, "parse_events: events %08x\n", events);
if (s->thread) {
spin_lock_irqsave(&s->thread_lock, flags);
s->thread_events |= events;
@@ -756,19 +771,22 @@ int pcmcia_reset_card(struct pcmcia_socket *skt)
{
int ret;
- cs_dbg(skt, 1, "resetting socket\n");
+ dev_dbg(&skt->dev, "resetting socket\n");
mutex_lock(&skt->skt_mutex);
do {
if (!(skt->state & SOCKET_PRESENT)) {
+ dev_dbg(&skt->dev, "can't reset, not present\n");
ret = -ENODEV;
break;
}
if (skt->state & SOCKET_SUSPEND) {
+ dev_dbg(&skt->dev, "can't reset, suspended\n");
ret = -EBUSY;
break;
}
if (skt->state & SOCKET_CARDBUS) {
+ dev_dbg(&skt->dev, "can't reset, is cardbus\n");
ret = -EPERM;
break;
}
@@ -801,7 +819,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
{
int ret;
- cs_dbg(skt, 1, "suspending socket\n");
+ dev_dbg(&skt->dev, "suspending socket\n");
mutex_lock(&skt->skt_mutex);
do {
@@ -831,7 +849,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
{
int ret;
- cs_dbg(skt, 1, "waking up socket\n");
+ dev_dbg(&skt->dev, "waking up socket\n");
mutex_lock(&skt->skt_mutex);
do {
@@ -859,7 +877,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
{
int ret;
- cs_dbg(skt, 1, "user eject request\n");
+ dev_dbg(&skt->dev, "user eject request\n");
mutex_lock(&skt->skt_mutex);
do {
@@ -888,7 +906,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
{
int ret;
- cs_dbg(skt, 1, "user insert request\n");
+ dev_dbg(&skt->dev, "user insert request\n");
mutex_lock(&skt->skt_mutex);
do {
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 79615e6d540b..3bc02d53a3a3 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -107,28 +107,6 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
}
}
-#ifdef CONFIG_PCMCIA_DEBUG
-extern int cs_debug_level(int);
-
-#define cs_dbg(skt, lvl, fmt, arg...) do { \
- if (cs_debug_level(lvl)) \
- dev_printk(KERN_DEBUG, &skt->dev, \
- "cs: " fmt, ## arg); \
-} while (0)
-#define __cs_dbg(lvl, fmt, arg...) do { \
- if (cs_debug_level(lvl)) \
- printk(KERN_DEBUG \
- "cs: " fmt, ## arg); \
-} while (0)
-
-#else
-#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
-#define __cs_dbg(lvl, fmt, arg...) do { } while (0)
-#endif
-
-#define cs_err(skt, fmt, arg...) \
- dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg)
-
/*
* Stuff internal to module "pcmcia_core":
@@ -170,10 +148,6 @@ extern struct rw_semaphore pcmcia_socket_list_rwsem;
extern struct list_head pcmcia_socket_list;
extern struct class pcmcia_socket_class;
-int pcmcia_get_window(struct pcmcia_socket *s,
- window_handle_t *handle,
- int idx,
- win_req_t *req);
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
@@ -197,8 +171,23 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
cisdata_t code, void *parse);
int pcmcia_replace_cis(struct pcmcia_socket *s,
const u8 *data, const size_t len);
-int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function,
- unsigned int *count);
+int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
+
+/* loop over CIS entries */
+int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
+ cisdata_t code, cisparse_t *parse, void *priv_data,
+ int (*loop_tuple) (tuple_t *tuple,
+ cisparse_t *parse,
+ void *priv_data));
+
+int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
+ tuple_t *tuple);
+
+int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
+ tuple_t *tuple);
+
+int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
+
/* rsrc_mgr.c */
int pcmcia_validate_mem(struct pcmcia_socket *s);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 9f300d3cb125..05893d41dd41 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -41,129 +41,11 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("PCMCIA Driver Services");
MODULE_LICENSE("GPL");
-#ifdef CONFIG_PCMCIA_DEBUG
-int ds_pc_debug;
-
-module_param_named(pc_debug, ds_pc_debug, int, 0644);
-
-#define ds_dbg(lvl, fmt, arg...) do { \
- if (ds_pc_debug > (lvl)) \
- printk(KERN_DEBUG "ds: " fmt , ## arg); \
-} while (0)
-#define ds_dev_dbg(lvl, dev, fmt, arg...) do { \
- if (ds_pc_debug > (lvl)) \
- dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg); \
-} while (0)
-#else
-#define ds_dbg(lvl, fmt, arg...) do { } while (0)
-#define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0)
-#endif
spinlock_t pcmcia_dev_list_lock;
/*====================================================================*/
-/* code which was in cs.c before */
-
-/* String tables for error messages */
-
-typedef struct lookup_t {
- const int key;
- const char *msg;
-} lookup_t;
-
-static const lookup_t error_table[] = {
- { 0, "Operation succeeded" },
- { -EIO, "Input/Output error" },
- { -ENODEV, "No card present" },
- { -EINVAL, "Bad parameter" },
- { -EACCES, "Configuration locked" },
- { -EBUSY, "Resource in use" },
- { -ENOSPC, "No more items" },
- { -ENOMEM, "Out of resource" },
-};
-
-
-static const lookup_t service_table[] = {
- { AccessConfigurationRegister, "AccessConfigurationRegister" },
- { AddSocketServices, "AddSocketServices" },
- { AdjustResourceInfo, "AdjustResourceInfo" },
- { CheckEraseQueue, "CheckEraseQueue" },
- { CloseMemory, "CloseMemory" },
- { DeregisterClient, "DeregisterClient" },
- { DeregisterEraseQueue, "DeregisterEraseQueue" },
- { GetCardServicesInfo, "GetCardServicesInfo" },
- { GetClientInfo, "GetClientInfo" },
- { GetConfigurationInfo, "GetConfigurationInfo" },
- { GetEventMask, "GetEventMask" },
- { GetFirstClient, "GetFirstClient" },
- { GetFirstRegion, "GetFirstRegion" },
- { GetFirstTuple, "GetFirstTuple" },
- { GetNextClient, "GetNextClient" },
- { GetNextRegion, "GetNextRegion" },
- { GetNextTuple, "GetNextTuple" },
- { GetStatus, "GetStatus" },
- { GetTupleData, "GetTupleData" },
- { MapMemPage, "MapMemPage" },
- { ModifyConfiguration, "ModifyConfiguration" },
- { ModifyWindow, "ModifyWindow" },
- { OpenMemory, "OpenMemory" },
- { ParseTuple, "ParseTuple" },
- { ReadMemory, "ReadMemory" },
- { RegisterClient, "RegisterClient" },
- { RegisterEraseQueue, "RegisterEraseQueue" },
- { RegisterMTD, "RegisterMTD" },
- { ReleaseConfiguration, "ReleaseConfiguration" },
- { ReleaseIO, "ReleaseIO" },
- { ReleaseIRQ, "ReleaseIRQ" },
- { ReleaseWindow, "ReleaseWindow" },
- { RequestConfiguration, "RequestConfiguration" },
- { RequestIO, "RequestIO" },
- { RequestIRQ, "RequestIRQ" },
- { RequestSocketMask, "RequestSocketMask" },
- { RequestWindow, "RequestWindow" },
- { ResetCard, "ResetCard" },
- { SetEventMask, "SetEventMask" },
- { ValidateCIS, "ValidateCIS" },
- { WriteMemory, "WriteMemory" },
- { BindDevice, "BindDevice" },
- { BindMTD, "BindMTD" },
- { ReportError, "ReportError" },
- { SuspendCard, "SuspendCard" },
- { ResumeCard, "ResumeCard" },
- { EjectCard, "EjectCard" },
- { InsertCard, "InsertCard" },
- { ReplaceCIS, "ReplaceCIS" }
-};
-
-const char *pcmcia_error_func(int func)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(service_table); i++)
- if (service_table[i].key == func)
- return service_table[i].msg;
-
- return "Unknown service number";
-}
-EXPORT_SYMBOL(pcmcia_error_func);
-
-const char *pcmcia_error_ret(int ret)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(error_table); i++)
- if (error_table[i].key == ret)
- return error_table[i].msg;
-
- return "unknown";
-}
-EXPORT_SYMBOL(pcmcia_error_ret);
-
-/*======================================================================*/
-
-
-
static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
{
struct pcmcia_device_id *did = p_drv->id_table;
@@ -303,7 +185,7 @@ int pcmcia_register_driver(struct pcmcia_driver *driver)
spin_lock_init(&driver->dynids.lock);
INIT_LIST_HEAD(&driver->dynids.list);
- ds_dbg(3, "registering driver %s\n", driver->drv.name);
+ pr_debug("registering driver %s\n", driver->drv.name);
error = driver_register(&driver->drv);
if (error < 0)
@@ -323,7 +205,7 @@ EXPORT_SYMBOL(pcmcia_register_driver);
*/
void pcmcia_unregister_driver(struct pcmcia_driver *driver)
{
- ds_dbg(3, "unregistering driver %s\n", driver->drv.name);
+ pr_debug("unregistering driver %s\n", driver->drv.name);
driver_unregister(&driver->drv);
pcmcia_free_dynids(driver);
}
@@ -350,14 +232,14 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev)
static void pcmcia_release_function(struct kref *ref)
{
struct config_t *c = container_of(ref, struct config_t, ref);
- ds_dbg(1, "releasing config_t\n");
+ pr_debug("releasing config_t\n");
kfree(c);
}
static void pcmcia_release_dev(struct device *dev)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
- ds_dev_dbg(1, dev, "releasing device\n");
+ dev_dbg(dev, "releasing device\n");
pcmcia_put_socket(p_dev->socket);
kfree(p_dev->devname);
kref_put(&p_dev->function_config->ref, pcmcia_release_function);
@@ -367,7 +249,7 @@ static void pcmcia_release_dev(struct device *dev)
static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
{
if (!s->pcmcia_state.device_add_pending) {
- ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary"
+ dev_dbg(&s->dev, "scheduling to add %s secondary"
" device to %d\n", mfc ? "mfc" : "pfc", s->sock);
s->pcmcia_state.device_add_pending = 1;
s->pcmcia_state.mfc_pfc = mfc;
@@ -405,7 +287,7 @@ static int pcmcia_device_probe(struct device * dev)
*/
did = dev_get_drvdata(&p_dev->dev);
- ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name);
+ dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name);
if ((!p_drv->probe) || (!p_dev->function_config) ||
(!try_module_get(p_drv->owner))) {
@@ -428,7 +310,7 @@ static int pcmcia_device_probe(struct device * dev)
ret = p_drv->probe(p_dev);
if (ret) {
- ds_dev_dbg(1, dev, "binding to %s failed with %d\n",
+ dev_dbg(dev, "binding to %s failed with %d\n",
p_drv->drv.name, ret);
goto put_module;
}
@@ -456,7 +338,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
struct pcmcia_device *tmp;
unsigned long flags;
- ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev,
+ dev_dbg(leftover ? &leftover->dev : &s->dev,
"pcmcia_card_remove(%d) %s\n", s->sock,
leftover ? leftover->devname : "");
@@ -475,7 +357,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
p_dev->_removed=1;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
- ds_dev_dbg(2, &p_dev->dev, "unregistering device\n");
+ dev_dbg(&p_dev->dev, "unregistering device\n");
device_unregister(&p_dev->dev);
}
@@ -492,7 +374,7 @@ static int pcmcia_device_remove(struct device * dev)
p_dev = to_pcmcia_dev(dev);
p_drv = to_pcmcia_drv(dev->driver);
- ds_dev_dbg(1, dev, "removing device\n");
+ dev_dbg(dev, "removing device\n");
/* If we're removing the primary module driving a
* pseudo multi-function card, we need to unbind
@@ -547,7 +429,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
if (!vers1)
return -ENOMEM;
- if (!pccard_read_tuple(p_dev->socket, p_dev->func,
+ if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL,
CISTPL_MANFID, &manf_id)) {
p_dev->manf_id = manf_id.manf;
p_dev->card_id = manf_id.card;
@@ -572,7 +454,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
}
if (!pccard_read_tuple(p_dev->socket, p_dev->func,
CISTPL_DEVICE_GEO, devgeo)) {
- ds_dev_dbg(0, &p_dev->dev,
+ dev_dbg(&p_dev->dev,
"mem device geometry probably means "
"FUNCID_MEMORY\n");
p_dev->func_id = CISTPL_FUNCID_MEMORY;
@@ -581,9 +463,9 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
kfree(devgeo);
}
- if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_VERS_1,
+ if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, CISTPL_VERS_1,
vers1)) {
- for (i=0; i < vers1->ns; i++) {
+ for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) {
char *tmp;
unsigned int length;
@@ -628,7 +510,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
mutex_lock(&device_add_lock);
- ds_dbg(3, "adding device to %d, function %d\n", s->sock, function);
+ pr_debug("adding device to %d, function %d\n", s->sock, function);
/* max of 4 devices per card */
if (s->device_count == 4)
@@ -654,7 +536,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev));
if (!p_dev->devname)
goto err_free;
- ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname);
+ dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname);
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
@@ -677,7 +559,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
if (!p_dev->function_config) {
- ds_dev_dbg(3, &p_dev->dev, "creating config_t\n");
+ dev_dbg(&p_dev->dev, "creating config_t\n");
p_dev->function_config = kzalloc(sizeof(struct config_t),
GFP_KERNEL);
if (!p_dev->function_config)
@@ -722,20 +604,20 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
int ret = 0;
if (!(s->resource_setup_done)) {
- ds_dev_dbg(3, &s->dev,
+ dev_dbg(&s->dev,
"no resources available, delaying card_add\n");
return -EAGAIN; /* try again, but later... */
}
if (pcmcia_validate_mem(s)) {
- ds_dev_dbg(3, &s->dev, "validating mem resources failed, "
+ dev_dbg(&s->dev, "validating mem resources failed, "
"delaying card_add\n");
return -EAGAIN; /* try again, but later... */
}
- ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains);
+ ret = pccard_validate_cis(s, &no_chains);
if (ret || !no_chains) {
- ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n");
+ dev_dbg(&s->dev, "invalid CIS or invalid resources\n");
return -ENODEV;
}
@@ -756,7 +638,7 @@ static void pcmcia_delayed_add_device(struct work_struct *work)
{
struct pcmcia_socket *s =
container_of(work, struct pcmcia_socket, device_add);
- ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock);
+ dev_dbg(&s->dev, "adding additional device to %d\n", s->sock);
pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
s->pcmcia_state.device_add_pending = 0;
s->pcmcia_state.mfc_pfc = 0;
@@ -766,7 +648,7 @@ static int pcmcia_requery(struct device *dev, void * _data)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
if (!p_dev->dev.driver) {
- ds_dev_dbg(1, dev, "update device information\n");
+ dev_dbg(dev, "update device information\n");
pcmcia_device_query(p_dev);
}
@@ -780,7 +662,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis)
unsigned long flags;
/* must be called with skt_mutex held */
- ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock);
+ dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock);
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
if (list_empty(&skt->devices_list))
@@ -835,7 +717,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
if (!filename)
return -EINVAL;
- ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename);
+ dev_dbg(&dev->dev, "trying to load CIS file %s\n", filename);
if (request_firmware(&fw, filename, &dev->dev) == 0) {
if (fw->size >= CISTPL_MAX_CIS_SIZE) {
@@ -953,14 +835,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
* after it has re-checked that there is no possible module
* with a prod_id/manf_id/card_id match.
*/
- ds_dev_dbg(0, &dev->dev,
+ dev_dbg(&dev->dev,
"skipping FUNC_ID match until userspace interaction\n");
if (!dev->allow_func_id_match)
return 0;
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
- ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n");
+ dev_dbg(&dev->dev, "device needs a fake CIS\n");
if (!dev->socket->fake_cis)
pcmcia_load_firmware(dev, did->cisfile);
@@ -992,9 +874,9 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
/* match dynamic devices first */
spin_lock(&p_drv->dynids.lock);
list_for_each_entry(dynid, &p_drv->dynids.list, node) {
- ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
+ dev_dbg(dev, "trying to match to %s\n", drv->name);
if (pcmcia_devmatch(p_dev, &dynid->id)) {
- ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
+ dev_dbg(dev, "matched to %s\n", drv->name);
spin_unlock(&p_drv->dynids.lock);
return 1;
}
@@ -1004,15 +886,15 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
#ifdef CONFIG_PCMCIA_IOCTL
/* matching by cardmgr */
if (p_dev->cardmgr == p_drv) {
- ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name);
+ dev_dbg(dev, "cardmgr matched to %s\n", drv->name);
return 1;
}
#endif
while (did && did->match_flags) {
- ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
+ dev_dbg(dev, "trying to match to %s\n", drv->name);
if (pcmcia_devmatch(p_dev, did)) {
- ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
+ dev_dbg(dev, "matched to %s\n", drv->name);
return 1;
}
did++;
@@ -1218,7 +1100,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
if (p_dev->suspended)
return 0;
- ds_dev_dbg(2, dev, "suspending\n");
+ dev_dbg(dev, "suspending\n");
if (dev->driver)
p_drv = to_pcmcia_drv(dev->driver);
@@ -1238,7 +1120,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
}
if (p_dev->device_no == p_dev->func) {
- ds_dev_dbg(2, dev, "releasing configuration\n");
+ dev_dbg(dev, "releasing configuration\n");
pcmcia_release_configuration(p_dev);
}
@@ -1258,7 +1140,7 @@ static int pcmcia_dev_resume(struct device * dev)
if (!p_dev->suspended)
return 0;
- ds_dev_dbg(2, dev, "resuming\n");
+ dev_dbg(dev, "resuming\n");
if (dev->driver)
p_drv = to_pcmcia_drv(dev->driver);
@@ -1267,7 +1149,7 @@ static int pcmcia_dev_resume(struct device * dev)
goto out;
if (p_dev->device_no == p_dev->func) {
- ds_dev_dbg(2, dev, "requesting configuration\n");
+ dev_dbg(dev, "requesting configuration\n");
ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
if (ret)
goto out;
@@ -1309,14 +1191,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
static int pcmcia_bus_resume(struct pcmcia_socket *skt)
{
- ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock);
+ dev_dbg(&skt->dev, "resuming socket %d\n", skt->sock);
bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
return 0;
}
static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
{
- ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock);
+ dev_dbg(&skt->dev, "suspending socket %d\n", skt->sock);
if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
pcmcia_bus_suspend_callback)) {
pcmcia_bus_resume(skt);
@@ -1348,7 +1230,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
return -ENODEV;
}
- ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
+ dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
event, priority, skt);
switch (event) {
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index b906abe26ad0..c13fd9360511 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -63,21 +63,6 @@
#include "vg468.h"
#include "ricoh.h"
-#ifdef CONFIG_PCMCIA_DEBUG
-static const char version[] =
-"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
-
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-
-#define debug(lvl, fmt, arg...) do { \
- if (pc_debug > (lvl)) \
- printk(KERN_DEBUG "i82365: " fmt , ## arg); \
-} while (0)
-#else
-#define debug(lvl, fmt, arg...) do { } while (0)
-#endif
static irqreturn_t i365_count_irq(int, void *);
static inline int _check_irq(int irq, int flags)
@@ -501,13 +486,13 @@ static irqreturn_t i365_count_irq(int irq, void *dev)
{
i365_get(irq_sock, I365_CSC);
irq_hits++;
- debug(2, "-> hit on irq %d\n", irq);
+ pr_debug("i82365: -> hit on irq %d\n", irq);
return IRQ_HANDLED;
}
static u_int __init test_irq(u_short sock, int irq)
{
- debug(2, " testing ISA irq %d\n", irq);
+ pr_debug("i82365: testing ISA irq %d\n", irq);
if (request_irq(irq, i365_count_irq, IRQF_PROBE_SHARED, "scan",
i365_count_irq) != 0)
return 1;
@@ -515,7 +500,7 @@ static u_int __init test_irq(u_short sock, int irq)
msleep(10);
if (irq_hits) {
free_irq(irq, i365_count_irq);
- debug(2, " spurious hit!\n");
+ pr_debug("i82365: spurious hit!\n");
return 1;
}
@@ -528,7 +513,7 @@ static u_int __init test_irq(u_short sock, int irq)
/* mask all interrupts */
i365_set(sock, I365_CSCINT, 0);
- debug(2, " hits = %d\n", irq_hits);
+ pr_debug("i82365: hits = %d\n", irq_hits);
return (irq_hits != 1);
}
@@ -854,7 +839,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev)
u_long flags = 0;
int handled = 0;
- debug(4, "pcic_interrupt(%d)\n", irq);
+ pr_debug("pcic_interrupt(%d)\n", irq);
for (j = 0; j < 20; j++) {
active = 0;
@@ -878,7 +863,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev)
events |= (csc & I365_CSC_READY) ? SS_READY : 0;
}
ISA_UNLOCK(i, flags);
- debug(2, "socket %d event 0x%02x\n", i, events);
+ pr_debug("socket %d event 0x%02x\n", i, events);
if (events)
pcmcia_parse_events(&socket[i].socket, events);
@@ -890,7 +875,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev)
if (j == 20)
printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
- debug(4, "interrupt done\n");
+ pr_debug("pcic_interrupt done\n");
return IRQ_RETVAL(handled);
} /* pcic_interrupt */
@@ -932,7 +917,7 @@ static int i365_get_status(u_short sock, u_int *value)
}
}
- debug(1, "GetStatus(%d) = %#4.4x\n", sock, *value);
+ pr_debug("GetStatus(%d) = %#4.4x\n", sock, *value);
return 0;
} /* i365_get_status */
@@ -943,7 +928,7 @@ static int i365_set_socket(u_short sock, socket_state_t *state)
struct i82365_socket *t = &socket[sock];
u_char reg;
- debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+ pr_debug("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
"io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
@@ -1052,9 +1037,9 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
{
u_char map, ioctl;
- debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
- "%#x-%#x)\n", sock, io->map, io->flags,
- io->speed, io->start, io->stop);
+ pr_debug("SetIOMap(%d, %d, %#2.2x, %d ns, "
+ "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed,
+ (unsigned long long)io->start, (unsigned long long)io->stop);
map = io->map;
if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
(io->stop < io->start)) return -EINVAL;
@@ -1082,7 +1067,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
u_short base, i;
u_char map;
- debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
+ pr_debug("SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
"%#x)\n", sock, mem->map, mem->flags, mem->speed,
(unsigned long long)mem->res->start,
(unsigned long long)mem->res->end, mem->card_start);
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index d1d89c4491ad..26a621c9e2fc 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -38,17 +38,6 @@
#include "m32r_cfc.h"
-#ifdef CONFIG_PCMCIA_DEBUG
-static int m32r_cfc_debug;
-module_param(m32r_cfc_debug, int, 0644);
-#define debug(lvl, fmt, arg...) do { \
- if (m32r_cfc_debug > (lvl)) \
- printk(KERN_DEBUG "m32r_cfc: " fmt , ## arg); \
-} while (0)
-#else
-#define debug(n, args...) do { } while (0)
-#endif
-
/* Poll status interval -- 0 means default to interrupt */
static int poll_interval = 0;
@@ -123,7 +112,7 @@ void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size,
unsigned char *bp = (unsigned char *)buf;
unsigned long flags;
- debug(3, "m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
+ pr_debug("m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
"size=%u, nmemb=%d, flag=%d\n",
sock, port, buf, size, nmemb, flag);
@@ -132,7 +121,7 @@ void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size,
printk("m32r_cfc:ioread_byte null port :%#lx\n",port);
return;
}
- debug(3, "m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
+ pr_debug("m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
spin_lock_irqsave(&pcc_lock, flags);
/* read Byte */
@@ -148,7 +137,7 @@ void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size,
unsigned short *bp = (unsigned short *)buf;
unsigned long flags;
- debug(3, "m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
+ pr_debug("m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
"buf=%p, size=%u, nmemb=%d, flag=%d\n",
sock, port, buf, size, nmemb, flag);
@@ -163,7 +152,7 @@ void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size,
printk("m32r_cfc:ioread_word null port :%#lx\n",port);
return;
}
- debug(3, "m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
+ pr_debug("m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
spin_lock_irqsave(&pcc_lock, flags);
/* read Word */
@@ -179,7 +168,7 @@ void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size,
unsigned char *bp = (unsigned char *)buf;
unsigned long flags;
- debug(3, "m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
+ pr_debug("m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
"buf=%p, size=%u, nmemb=%d, flag=%d\n",
sock, port, buf, size, nmemb, flag);
@@ -189,7 +178,7 @@ void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size,
printk("m32r_cfc:iowrite_byte null port:%#lx\n",port);
return;
}
- debug(3, "m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
+ pr_debug("m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
spin_lock_irqsave(&pcc_lock, flags);
while (nmemb--)
@@ -204,7 +193,7 @@ void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size,
unsigned short *bp = (unsigned short *)buf;
unsigned long flags;
- debug(3, "m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
+ pr_debug("m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
"buf=%p, size=%u, nmemb=%d, flag=%d\n",
sock, port, buf, size, nmemb, flag);
@@ -226,7 +215,7 @@ void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size,
return;
}
#endif
- debug(3, "m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
+ pr_debug("m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
spin_lock_irqsave(&pcc_lock, flags);
while (nmemb--)
@@ -262,7 +251,7 @@ static struct timer_list poll_timer;
static unsigned int pcc_get(u_short sock, unsigned int reg)
{
unsigned int val = inw(reg);
- debug(3, "m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
+ pr_debug("m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
return val;
}
@@ -270,7 +259,7 @@ static unsigned int pcc_get(u_short sock, unsigned int reg)
static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
{
outw(data, reg);
- debug(3, "m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
+ pr_debug("m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
}
/*======================================================================
@@ -286,14 +275,14 @@ static int __init is_alive(u_short sock)
{
unsigned int stat;
- debug(3, "m32r_cfc: is_alive:\n");
+ pr_debug("m32r_cfc: is_alive:\n");
printk("CF: ");
stat = pcc_get(sock, (unsigned int)PLD_CFSTS);
if (!stat)
printk("No ");
printk("Card is detected at socket %d : stat = 0x%08x\n", sock, stat);
- debug(3, "m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
+ pr_debug("m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
return 0;
}
@@ -303,7 +292,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
{
pcc_socket_t *t = &socket[pcc_sockets];
- debug(3, "m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
+ pr_debug("m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
"mapaddr=%#lx, ioaddr=%08x\n",
base, irq, mapaddr, ioaddr);
@@ -358,7 +347,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
/* eject interrupt */
request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
#endif
- debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
+ pr_debug("m32r_cfc: enable CFMSK, RDYSEL\n");
pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
#endif /* CONFIG_PLAT_USRV */
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
@@ -378,26 +367,26 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
u_int events = 0;
int handled = 0;
- debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
+ pr_debug("m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
for (i = 0; i < pcc_sockets; i++) {
if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
continue;
handled = 1;
- debug(3, "m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
+ pr_debug("m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
i, irq);
events |= SS_DETECT; /* insert or eject */
if (events)
pcmcia_parse_events(&socket[i].socket, events);
}
- debug(3, "m32r_cfc: pcc_interrupt: done\n");
+ pr_debug("m32r_cfc: pcc_interrupt: done\n");
return IRQ_RETVAL(handled);
} /* pcc_interrupt */
static void pcc_interrupt_wrapper(u_long data)
{
- debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n");
+ pr_debug("m32r_cfc: pcc_interrupt_wrapper:\n");
pcc_interrupt(0, NULL);
init_timer(&poll_timer);
poll_timer.expires = jiffies + poll_interval;
@@ -410,17 +399,17 @@ static int _pcc_get_status(u_short sock, u_int *value)
{
u_int status;
- debug(3, "m32r_cfc: _pcc_get_status:\n");
+ pr_debug("m32r_cfc: _pcc_get_status:\n");
status = pcc_get(sock, (unsigned int)PLD_CFSTS);
*value = (status) ? SS_DETECT : 0;
- debug(3, "m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
+ pr_debug("m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
if ( status ) {
/* enable CF power */
status = inw((unsigned int)PLD_CPCR);
if (!(status & PLD_CPCR_CF)) {
- debug(3, "m32r_cfc: _pcc_get_status: "
+ pr_debug("m32r_cfc: _pcc_get_status: "
"power on (CPCR=0x%08x)\n", status);
status |= PLD_CPCR_CF;
outw(status, (unsigned int)PLD_CPCR);
@@ -439,7 +428,7 @@ static int _pcc_get_status(u_short sock, u_int *value)
status &= ~PLD_CPCR_CF;
outw(status, (unsigned int)PLD_CPCR);
udelay(100);
- debug(3, "m32r_cfc: _pcc_get_status: "
+ pr_debug("m32r_cfc: _pcc_get_status: "
"power off (CPCR=0x%08x)\n", status);
}
#elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
@@ -465,13 +454,13 @@ static int _pcc_get_status(u_short sock, u_int *value)
/* disable CF power */
pcc_set(sock, (unsigned int)PLD_CPCR, 0);
udelay(100);
- debug(3, "m32r_cfc: _pcc_get_status: "
+ pr_debug("m32r_cfc: _pcc_get_status: "
"power off (CPCR=0x%08x)\n", status);
}
#else
#error no platform configuration
#endif
- debug(3, "m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
+ pr_debug("m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
sock, *value);
return 0;
} /* _get_status */
@@ -480,7 +469,7 @@ static int _pcc_get_status(u_short sock, u_int *value)
static int _pcc_set_socket(u_short sock, socket_state_t *state)
{
- debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+ pr_debug("m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
"io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
@@ -492,41 +481,39 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
}
#endif
if (state->flags & SS_RESET) {
- debug(3, ":RESET\n");
+ pr_debug(":RESET\n");
pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
}else{
pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
}
if (state->flags & SS_OUTPUT_ENA){
- debug(3, ":OUTPUT_ENA\n");
+ pr_debug(":OUTPUT_ENA\n");
/* bit clear */
pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
} else {
pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
}
-#ifdef CONFIG_PCMCIA_DEBUG
if(state->flags & SS_IOCARD){
- debug(3, ":IOCARD");
+ pr_debug(":IOCARD");
}
if (state->flags & SS_PWR_AUTO) {
- debug(3, ":PWR_AUTO");
+ pr_debug(":PWR_AUTO");
}
if (state->csc_mask & SS_DETECT)
- debug(3, ":csc-SS_DETECT");
+ pr_debug(":csc-SS_DETECT");
if (state->flags & SS_IOCARD) {
if (state->csc_mask & SS_STSCHG)
- debug(3, ":STSCHG");
+ pr_debug(":STSCHG");
} else {
if (state->csc_mask & SS_BATDEAD)
- debug(3, ":BATDEAD");
+ pr_debug(":BATDEAD");
if (state->csc_mask & SS_BATWARN)
- debug(3, ":BATWARN");
+ pr_debug(":BATWARN");
if (state->csc_mask & SS_READY)
- debug(3, ":READY");
+ pr_debug(":READY");
}
- debug(3, "\n");
-#endif
+ pr_debug("\n");
return 0;
} /* _set_socket */
@@ -536,9 +523,10 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
{
u_char map;
- debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
- "%#lx-%#lx)\n", sock, io->map, io->flags,
- io->speed, io->start, io->stop);
+ pr_debug("m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
+ "%#llx-%#llx)\n", sock, io->map, io->flags,
+ io->speed, (unsigned long long)io->start,
+ (unsigned long long)io->stop);
map = io->map;
return 0;
@@ -553,9 +541,10 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
u_long addr;
pcc_socket_t *t = &socket[sock];
- debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
- "%#lx, %#x)\n", sock, map, mem->flags,
- mem->speed, mem->static_start, mem->card_start);
+ pr_debug("m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
+ "%#llx, %#x)\n", sock, map, mem->flags,
+ mem->speed, (unsigned long long)mem->static_start,
+ mem->card_start);
/*
* sanity check
@@ -638,11 +627,11 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
if (socket[sock].flags & IS_ALIVE) {
- debug(3, "m32r_cfc: pcc_get_status: sock(%d) -EINVAL\n", sock);
+ dev_dbg(&s->dev, "pcc_get_status: sock(%d) -EINVAL\n", sock);
*value = 0;
return -EINVAL;
}
- debug(3, "m32r_cfc: pcc_get_status: sock(%d)\n", sock);
+ dev_dbg(&s->dev, "pcc_get_status: sock(%d)\n", sock);
LOCKED(_pcc_get_status(sock, value));
}
@@ -651,10 +640,10 @@ static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
if (socket[sock].flags & IS_ALIVE) {
- debug(3, "m32r_cfc: pcc_set_socket: sock(%d) -EINVAL\n", sock);
+ dev_dbg(&s->dev, "pcc_set_socket: sock(%d) -EINVAL\n", sock);
return -EINVAL;
}
- debug(3, "m32r_cfc: pcc_set_socket: sock(%d)\n", sock);
+ dev_dbg(&s->dev, "pcc_set_socket: sock(%d)\n", sock);
LOCKED(_pcc_set_socket(sock, state));
}
@@ -663,10 +652,10 @@ static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
if (socket[sock].flags & IS_ALIVE) {
- debug(3, "m32r_cfc: pcc_set_io_map: sock(%d) -EINVAL\n", sock);
+ dev_dbg(&s->dev, "pcc_set_io_map: sock(%d) -EINVAL\n", sock);
return -EINVAL;
}
- debug(3, "m32r_cfc: pcc_set_io_map: sock(%d)\n", sock);
+ dev_dbg(&s->dev, "pcc_set_io_map: sock(%d)\n", sock);
LOCKED(_pcc_set_io_map(sock, io));
}
@@ -675,16 +664,16 @@ static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
if (socket[sock].flags & IS_ALIVE) {
- debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
+ dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
return -EINVAL;
}
- debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d)\n", sock);
+ dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d)\n", sock);
LOCKED(_pcc_set_mem_map(sock, mem));
}
static int pcc_init(struct pcmcia_socket *s)
{
- debug(3, "m32r_cfc: pcc_init()\n");
+ dev_dbg(&s->dev, "pcc_init()\n");
return 0;
}
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index a0655839c8d3..72844c5a6d05 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -45,16 +45,6 @@
#define PCC_DEBUG_DBEX
-#ifdef CONFIG_PCMCIA_DEBUG
-static int m32r_pcc_debug;
-module_param(m32r_pcc_debug, int, 0644);
-#define debug(lvl, fmt, arg...) do { \
- if (m32r_pcc_debug > (lvl)) \
- printk(KERN_DEBUG "m32r_pcc: " fmt , ## arg); \
-} while (0)
-#else
-#define debug(n, args...) do { } while (0)
-#endif
/* Poll status interval -- 0 means default to interrupt */
static int poll_interval = 0;
@@ -358,7 +348,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
u_int events, active;
int handled = 0;
- debug(4, "m32r: pcc_interrupt(%d)\n", irq);
+ pr_debug("m32r_pcc: pcc_interrupt(%d)\n", irq);
for (j = 0; j < 20; j++) {
active = 0;
@@ -369,13 +359,14 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
handled = 1;
irc = pcc_get(i, PCIRC);
irc >>=16;
- debug(2, "m32r-pcc:interrupt: socket %d pcirc 0x%02x ", i, irc);
+ pr_debug("m32r_pcc: interrupt: socket %d pcirc 0x%02x ",
+ i, irc);
if (!irc)
continue;
events = (irc) ? SS_DETECT : 0;
events |= (pcc_get(i,PCCR) & PCCR_PCEN) ? SS_READY : 0;
- debug(2, " event 0x%02x\n", events);
+ pr_debug("m32r_pcc: event 0x%02x\n", events);
if (events)
pcmcia_parse_events(&socket[i].socket, events);
@@ -388,7 +379,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
if (j == 20)
printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n");
- debug(4, "m32r-pcc: interrupt done\n");
+ pr_debug("m32r_pcc: interrupt done\n");
return IRQ_RETVAL(handled);
} /* pcc_interrupt */
@@ -422,7 +413,7 @@ static int _pcc_get_status(u_short sock, u_int *value)
status = pcc_get(sock,PCCSIGCR);
*value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0;
- debug(3, "m32r-pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
+ pr_debug("m32r_pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
return 0;
} /* _get_status */
@@ -432,7 +423,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
{
u_long reg = 0;
- debug(3, "m32r-pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+ pr_debug("m32r_pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
"io_irq %d, csc_mask %#2.2x)", sock, state->flags,
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
@@ -448,11 +439,11 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
}
if (state->flags & SS_RESET) {
- debug(3, ":RESET\n");
+ pr_debug("m32r_pcc: :RESET\n");
reg |= PCCSIGCR_CRST;
}
if (state->flags & SS_OUTPUT_ENA){
- debug(3, ":OUTPUT_ENA\n");
+ pr_debug("m32r_pcc: :OUTPUT_ENA\n");
/* bit clear */
} else {
reg |= PCCSIGCR_SEN;
@@ -460,28 +451,26 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
pcc_set(sock,PCCSIGCR,reg);
-#ifdef CONFIG_PCMCIA_DEBUG
if(state->flags & SS_IOCARD){
- debug(3, ":IOCARD");
+ pr_debug("m32r_pcc: :IOCARD");
}
if (state->flags & SS_PWR_AUTO) {
- debug(3, ":PWR_AUTO");
+ pr_debug("m32r_pcc: :PWR_AUTO");
}
if (state->csc_mask & SS_DETECT)
- debug(3, ":csc-SS_DETECT");
+ pr_debug("m32r_pcc: :csc-SS_DETECT");
if (state->flags & SS_IOCARD) {
if (state->csc_mask & SS_STSCHG)
- debug(3, ":STSCHG");
+ pr_debug("m32r_pcc: :STSCHG");
} else {
if (state->csc_mask & SS_BATDEAD)
- debug(3, ":BATDEAD");
+ pr_debug("m32r_pcc: :BATDEAD");
if (state->csc_mask & SS_BATWARN)
- debug(3, ":BATWARN");
+ pr_debug("m32r_pcc: :BATWARN");
if (state->csc_mask & SS_READY)
- debug(3, ":READY");
+ pr_debug("m32r_pcc: :READY");
}
- debug(3, "\n");
-#endif
+ pr_debug("m32r_pcc: \n");
return 0;
} /* _set_socket */
@@ -491,9 +480,10 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
{
u_char map;
- debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
- "%#x-%#x)\n", sock, io->map, io->flags,
- io->speed, io->start, io->stop);
+ pr_debug("m32r_pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
+ "%#llx-%#llx)\n", sock, io->map, io->flags,
+ io->speed, (unsigned long long)io->start,
+ (unsigned long long)io->stop);
map = io->map;
return 0;
@@ -514,9 +504,10 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
#endif
#endif
- debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
- "%#lx, %#x)\n", sock, map, mem->flags,
- mem->speed, mem->static_start, mem->card_start);
+ pr_debug("m32r_pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
+ "%#llx, %#x)\n", sock, map, mem->flags,
+ mem->speed, (unsigned long long)mem->static_start,
+ mem->card_start);
/*
* sanity check
@@ -660,7 +651,7 @@ static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
static int pcc_init(struct pcmcia_socket *s)
{
- debug(4, "m32r-pcc: init call\n");
+ pr_debug("m32r_pcc: init call\n");
return 0;
}
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index c69f2c4fe520..7f79c4e169ae 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -64,14 +64,6 @@
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
-#ifdef CONFIG_PCMCIA_DEBUG
-static int pc_debug;
-module_param(pc_debug, int, 0);
-#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
-#else
-#define dprintk(args...)
-#endif
-
#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
@@ -565,7 +557,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
unsigned int i, events, pscr, pipr, per;
pcmconf8xx_t *pcmcia = socket[0].pcmcia;
- dprintk("Interrupt!\n");
+ pr_debug("m8xx_pcmcia: Interrupt!\n");
/* get interrupt sources */
pscr = in_be32(&pcmcia->pcmc_pscr);
@@ -614,7 +606,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
/* call the handler */
- dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, "
+ pr_debug("m8xx_pcmcia: slot %u: events = 0x%02x, pscr = 0x%08x, "
"pipr = 0x%08x\n", i, events, pscr, pipr);
if (events) {
@@ -641,7 +633,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
/* clear the interrupt sources */
out_be32(&pcmcia->pcmc_pscr, pscr);
- dprintk("Interrupt done.\n");
+ pr_debug("m8xx_pcmcia: Interrupt done.\n");
return IRQ_HANDLED;
}
@@ -815,7 +807,7 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
};
}
- dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value);
+ pr_debug("m8xx_pcmcia: GetStatus(%d) = %#2.2x\n", lsock, *value);
return 0;
}
@@ -828,7 +820,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t * state)
unsigned long flags;
pcmconf8xx_t *pcmcia = socket[0].pcmcia;
- dprintk("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+ pr_debug("m8xx_pcmcia: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
"io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
@@ -974,9 +966,10 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
#define M8XX_SIZE (io->stop - io->start + 1)
#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
- dprintk("SetIOMap(%d, %d, %#2.2x, %d ns, "
- "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
- io->speed, io->start, io->stop);
+ pr_debug("m8xx_pcmcia: SetIOMap(%d, %d, %#2.2x, %d ns, "
+ "%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags,
+ io->speed, (unsigned long long)io->start,
+ (unsigned long long)io->stop);
if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
|| (io->stop > 0xffff) || (io->stop < io->start))
@@ -987,7 +980,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
if (io->flags & MAP_ACTIVE) {
- dprintk("io->flags & MAP_ACTIVE\n");
+ pr_debug("m8xx_pcmcia: io->flags & MAP_ACTIVE\n");
winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
+ (lsock * PCMCIA_IO_WIN_NO) + io->map;
@@ -1017,8 +1010,8 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
out_be32(&w->or, reg);
- dprintk("Socket %u: Mapped io window %u at %#8.8x, "
- "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+ pr_debug("m8xx_pcmcia: Socket %u: Mapped io window %u at "
+ "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
} else {
/* shutdown IO window */
winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
@@ -1032,14 +1025,14 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
out_be32(&w->or, 0); /* turn off window */
out_be32(&w->br, 0); /* turn off base address */
- dprintk("Socket %u: Unmapped io window %u at %#8.8x, "
- "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+ pr_debug("m8xx_pcmcia: Socket %u: Unmapped io window %u at "
+ "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
}
/* copy the struct and modify the copy */
s->io_win[io->map] = *io;
s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
- dprintk("SetIOMap exit\n");
+ pr_debug("m8xx_pcmcia: SetIOMap exit\n");
return 0;
}
@@ -1054,9 +1047,10 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
unsigned int reg, winnr;
pcmconf8xx_t *pcmcia = s->pcmcia;
- dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
- "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
- mem->speed, mem->static_start, mem->card_start);
+ pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
+ "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
+ mem->speed, (unsigned long long)mem->static_start,
+ mem->card_start);
if ((mem->map >= PCMCIA_MEM_WIN_NO)
// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
@@ -1096,7 +1090,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
out_be32(&w->or, reg);
- dprintk("Socket %u: Mapped memory window %u at %#8.8x, "
+ pr_debug("m8xx_pcmcia: Socket %u: Mapped memory window %u at %#8.8x, "
"OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
if (mem->flags & MAP_ACTIVE) {
@@ -1106,9 +1100,10 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
+ mem->card_start;
}
- dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
- "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
- mem->speed, mem->static_start, mem->card_start);
+ pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
+ "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
+ mem->speed, (unsigned long long)mem->static_start,
+ mem->card_start);
/* copy the struct and modify the copy */
@@ -1126,7 +1121,7 @@ static int m8xx_sock_init(struct pcmcia_socket *sock)
pccard_io_map io = { 0, 0, 0, 0, 1 };
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
- dprintk("sock_init(%d)\n", s);
+ pr_debug("m8xx_pcmcia: sock_init(%d)\n", s);
m8xx_set_socket(sock, &dead_socket);
for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h
index 72188c462c9c..624442fc0d35 100644
--- a/drivers/pcmcia/o2micro.h
+++ b/drivers/pcmcia/o2micro.h
@@ -30,28 +30,6 @@
#ifndef _LINUX_O2MICRO_H
#define _LINUX_O2MICRO_H
-#ifndef PCI_VENDOR_ID_O2
-#define PCI_VENDOR_ID_O2 0x1217
-#endif
-#ifndef PCI_DEVICE_ID_O2_6729
-#define PCI_DEVICE_ID_O2_6729 0x6729
-#endif
-#ifndef PCI_DEVICE_ID_O2_6730
-#define PCI_DEVICE_ID_O2_6730 0x673a
-#endif
-#ifndef PCI_DEVICE_ID_O2_6832
-#define PCI_DEVICE_ID_O2_6832 0x6832
-#endif
-#ifndef PCI_DEVICE_ID_O2_6836
-#define PCI_DEVICE_ID_O2_6836 0x6836
-#endif
-#ifndef PCI_DEVICE_ID_O2_6812
-#define PCI_DEVICE_ID_O2_6812 0x6872
-#endif
-#ifndef PCI_DEVICE_ID_O2_6933
-#define PCI_DEVICE_ID_O2_6933 0x6933
-#endif
-
/* Additional PCI configuration registers */
#define O2_MUX_CONTROL 0x90 /* 32 bit */
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 32c44040c1e8..c4d7908fa37f 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -58,17 +58,6 @@ typedef struct user_info_t {
} user_info_t;
-#ifdef CONFIG_PCMCIA_DEBUG
-extern int ds_pc_debug;
-
-#define ds_dbg(lvl, fmt, arg...) do { \
- if (ds_pc_debug >= lvl) \
- printk(KERN_DEBUG "ds: " fmt , ## arg); \
-} while (0)
-#else
-#define ds_dbg(lvl, fmt, arg...) do { } while (0)
-#endif
-
static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
unsigned int function)
{
@@ -229,6 +218,61 @@ static int pcmcia_adjust_resource_info(adjust_t *adj)
return (ret);
}
+
+/** pcmcia_get_window
+ */
+static int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *wh_out,
+ window_handle_t wh, win_req_t *req)
+{
+ pccard_mem_map *win;
+ window_handle_t w;
+
+ wh--;
+ if (!s || !(s->state & SOCKET_PRESENT))
+ return -ENODEV;
+ if (wh >= MAX_WIN)
+ return -EINVAL;
+ for (w = wh; w < MAX_WIN; w++)
+ if (s->state & SOCKET_WIN_REQ(w))
+ break;
+ if (w == MAX_WIN)
+ return -EINVAL;
+ win = &s->win[w];
+ req->Base = win->res->start;
+ req->Size = win->res->end - win->res->start + 1;
+ req->AccessSpeed = win->speed;
+ req->Attributes = 0;
+ if (win->flags & MAP_ATTRIB)
+ req->Attributes |= WIN_MEMORY_TYPE_AM;
+ if (win->flags & MAP_ACTIVE)
+ req->Attributes |= WIN_ENABLE;
+ if (win->flags & MAP_16BIT)
+ req->Attributes |= WIN_DATA_WIDTH_16;
+ if (win->flags & MAP_USE_WAIT)
+ req->Attributes |= WIN_USE_WAIT;
+
+ *wh_out = w + 1;
+ return 0;
+} /* pcmcia_get_window */
+
+
+/** pcmcia_get_mem_page
+ *
+ * Change the card address of an already open memory window.
+ */
+static int pcmcia_get_mem_page(struct pcmcia_socket *skt, window_handle_t wh,
+ memreq_t *req)
+{
+ wh--;
+ if (wh >= MAX_WIN)
+ return -EINVAL;
+
+ req->Page = 0;
+ req->CardOffset = skt->win[wh].card_start;
+ return 0;
+} /* pcmcia_get_mem_page */
+
+
/** pccard_get_status
*
* Get the current socket state bits. We don't support the latched
@@ -431,7 +475,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
if (!s)
return -EINVAL;
- ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
+ pr_debug("bind_request(%d, '%s')\n", s->sock,
(char *)bind_info->dev_info);
p_drv = get_pcmcia_driver(&bind_info->dev_info);
@@ -623,7 +667,7 @@ static int ds_open(struct inode *inode, struct file *file)
static int warning_printed = 0;
int ret = 0;
- ds_dbg(0, "ds_open(socket %d)\n", i);
+ pr_debug("ds_open(socket %d)\n", i);
lock_kernel();
s = pcmcia_get_socket_by_nr(i);
@@ -685,7 +729,7 @@ static int ds_release(struct inode *inode, struct file *file)
struct pcmcia_socket *s;
user_info_t *user, **link;
- ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
+ pr_debug("ds_release(socket %d)\n", iminor(inode));
user = file->private_data;
if (CHECK_USER(user))
@@ -719,7 +763,7 @@ static ssize_t ds_read(struct file *file, char __user *buf,
user_info_t *user;
int ret;
- ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
+ pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
if (count < 4)
return -EINVAL;
@@ -744,7 +788,7 @@ static ssize_t ds_read(struct file *file, char __user *buf,
static ssize_t ds_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
- ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
+ pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
if (count != 4)
return -EINVAL;
@@ -762,7 +806,7 @@ static u_int ds_poll(struct file *file, poll_table *wait)
struct pcmcia_socket *s;
user_info_t *user;
- ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
+ pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
user = file->private_data;
if (CHECK_USER(user))
@@ -790,7 +834,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
ds_ioctl_arg_t *buf;
user_info_t *user;
- ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
+ pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
user = file->private_data;
if (CHECK_USER(user))
@@ -809,13 +853,13 @@ static int ds_ioctl(struct inode * inode, struct file * file,
if (cmd & IOC_IN) {
if (!access_ok(VERIFY_READ, uarg, size)) {
- ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
+ pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT);
return -EFAULT;
}
}
if (cmd & IOC_OUT) {
if (!access_ok(VERIFY_WRITE, uarg, size)) {
- ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
+ pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT);
return -EFAULT;
}
}
@@ -881,7 +925,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
mutex_lock(&s->skt_mutex);
pcmcia_validate_mem(s);
mutex_unlock(&s->skt_mutex);
- ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains);
+ ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
break;
case DS_SUSPEND_CARD:
ret = pcmcia_suspend_card(s);
@@ -927,15 +971,15 @@ static int ds_ioctl(struct inode * inode, struct file * file,
goto free_out;
break;
case DS_GET_FIRST_WINDOW:
- ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
+ ret = pcmcia_get_window(s, &buf->win_info.handle, 1,
&buf->win_info.window);
break;
case DS_GET_NEXT_WINDOW:
ret = pcmcia_get_window(s, &buf->win_info.handle,
- buf->win_info.handle->index + 1, &buf->win_info.window);
+ buf->win_info.handle + 1, &buf->win_info.window);
break;
case DS_GET_MEM_PAGE:
- ret = pcmcia_get_mem_page(buf->win_info.handle,
+ ret = pcmcia_get_mem_page(s, buf->win_info.handle,
&buf->win_info.map);
break;
case DS_REPLACE_CIS:
@@ -962,7 +1006,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
}
if ((err == 0) && (ret != 0)) {
- ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
+ pr_debug("ds_ioctl: ret = %d\n", ret);
switch (ret) {
case -ENODEV:
case -EINVAL:
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index d919e96c0afd..a8bf8c1b45ed 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/device.h>
+#include <linux/netdevice.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
@@ -43,21 +44,6 @@ static u8 pcmcia_used_irq[NR_IRQS];
#endif
-#ifdef CONFIG_PCMCIA_DEBUG
-extern int ds_pc_debug;
-
-#define ds_dbg(skt, lvl, fmt, arg...) do { \
- if (ds_pc_debug >= lvl) \
- dev_printk(KERN_DEBUG, &skt->dev, \
- "pcmcia_resource: " fmt, \
- ## arg); \
-} while (0)
-#else
-#define ds_dbg(skt, lvl, fmt, arg...) do { } while (0)
-#endif
-
-
-
/** alloc_io_space
*
* Special stuff for managing IO windows, because they are scarce
@@ -72,14 +58,14 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
align = (*base) ? (lines ? 1<<lines : 0) : 1;
if (align && (align < num)) {
if (*base) {
- ds_dbg(s, 0, "odd IO request: num %#x align %#x\n",
+ dev_dbg(&s->dev, "odd IO request: num %#x align %#x\n",
num, align);
align = 0;
} else
while (align && (align < num)) align <<= 1;
}
if (*base & ~(align-1)) {
- ds_dbg(s, 0, "odd IO request: base %#x align %#x\n",
+ dev_dbg(&s->dev, "odd IO request: base %#x align %#x\n",
*base, align);
align = 0;
}
@@ -173,8 +159,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
s = p_dev->socket;
c = p_dev->function_config;
- if (!(c->state & CONFIG_LOCKED))
+ if (!(c->state & CONFIG_LOCKED)) {
+ dev_dbg(&s->dev, "Configuration isnt't locked\n");
return -EACCES;
+ }
addr = (c->ConfigBase + reg->Offset) >> 1;
@@ -188,6 +176,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
pcmcia_write_cis_mem(s, 1, addr, 1, &val);
break;
default:
+ dev_dbg(&s->dev, "Invalid conf register request\n");
return -EINVAL;
break;
}
@@ -196,68 +185,21 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
EXPORT_SYMBOL(pcmcia_access_configuration_register);
-/** pcmcia_get_window
- */
-int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
- int idx, win_req_t *req)
-{
- window_t *win;
- int w;
-
- if (!s || !(s->state & SOCKET_PRESENT))
- return -ENODEV;
- for (w = idx; w < MAX_WIN; w++)
- if (s->state & SOCKET_WIN_REQ(w))
- break;
- if (w == MAX_WIN)
- return -EINVAL;
- win = &s->win[w];
- req->Base = win->ctl.res->start;
- req->Size = win->ctl.res->end - win->ctl.res->start + 1;
- req->AccessSpeed = win->ctl.speed;
- req->Attributes = 0;
- if (win->ctl.flags & MAP_ATTRIB)
- req->Attributes |= WIN_MEMORY_TYPE_AM;
- if (win->ctl.flags & MAP_ACTIVE)
- req->Attributes |= WIN_ENABLE;
- if (win->ctl.flags & MAP_16BIT)
- req->Attributes |= WIN_DATA_WIDTH_16;
- if (win->ctl.flags & MAP_USE_WAIT)
- req->Attributes |= WIN_USE_WAIT;
- *handle = win;
- return 0;
-} /* pcmcia_get_window */
-EXPORT_SYMBOL(pcmcia_get_window);
-
-
-/** pcmcia_get_mem_page
- *
- * Change the card address of an already open memory window.
- */
-int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
+int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
+ memreq_t *req)
{
- if ((win == NULL) || (win->magic != WINDOW_MAGIC))
- return -EINVAL;
- req->Page = 0;
- req->CardOffset = win->ctl.card_start;
- return 0;
-} /* pcmcia_get_mem_page */
-EXPORT_SYMBOL(pcmcia_get_mem_page);
-
+ struct pcmcia_socket *s = p_dev->socket;
-int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
-{
- struct pcmcia_socket *s;
- if ((win == NULL) || (win->magic != WINDOW_MAGIC))
+ wh--;
+ if (wh >= MAX_WIN)
return -EINVAL;
- s = win->sock;
if (req->Page != 0) {
- ds_dbg(s, 0, "failure: requested page is zero\n");
+ dev_dbg(&s->dev, "failure: requested page is zero\n");
return -EINVAL;
}
- win->ctl.card_start = req->CardOffset;
- if (s->ops->set_mem_map(s, &win->ctl) != 0) {
- ds_dbg(s, 0, "failed to set_mem_map\n");
+ s->win[wh].card_start = req->CardOffset;
+ if (s->ops->set_mem_map(s, &s->win[wh]) != 0) {
+ dev_dbg(&s->dev, "failed to set_mem_map\n");
return -EIO;
}
return 0;
@@ -278,10 +220,14 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
s = p_dev->socket;
c = p_dev->function_config;
- if (!(s->state & SOCKET_PRESENT))
+ if (!(s->state & SOCKET_PRESENT)) {
+ dev_dbg(&s->dev, "No card present\n");
return -ENODEV;
- if (!(c->state & CONFIG_LOCKED))
+ }
+ if (!(c->state & CONFIG_LOCKED)) {
+ dev_dbg(&s->dev, "Configuration isnt't locked\n");
return -EACCES;
+ }
if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
if (mod->Attributes & CONF_ENABLE_IRQ) {
@@ -295,7 +241,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
}
if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
- ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+ dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
return -EINVAL;
}
@@ -303,7 +249,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
if (mod->Vpp1 != mod->Vpp2) {
- ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n");
+ dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
return -EINVAL;
}
s->socket.Vpp = mod->Vpp1;
@@ -314,7 +260,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
}
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
- ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+ dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
return -EINVAL;
}
@@ -425,11 +371,11 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
if (c->state & CONFIG_LOCKED)
return -EACCES;
if (c->irq.Attributes != req->Attributes) {
- ds_dbg(s, 0, "IRQ attributes must match assigned ones\n");
+ dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n");
return -EINVAL;
}
if (s->irq.AssignedIRQ != req->AssignedIRQ) {
- ds_dbg(s, 0, "IRQ must match assigned one\n");
+ dev_dbg(&s->dev, "IRQ must match assigned one\n");
return -EINVAL;
}
if (--s->irq.Config == 0) {
@@ -437,8 +383,8 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
s->irq.AssignedIRQ = 0;
}
- if (req->Attributes & IRQ_HANDLE_PRESENT) {
- free_irq(req->AssignedIRQ, req->Instance);
+ if (req->Handler) {
+ free_irq(req->AssignedIRQ, p_dev->priv);
}
#ifdef CONFIG_PCMCIA_PROBE
@@ -449,30 +395,34 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
} /* pcmcia_release_irq */
-int pcmcia_release_window(window_handle_t win)
+int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
{
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
+ pccard_mem_map *win;
- if ((win == NULL) || (win->magic != WINDOW_MAGIC))
+ wh--;
+ if (wh >= MAX_WIN)
return -EINVAL;
- s = win->sock;
- if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
+
+ win = &s->win[wh];
+
+ if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) {
+ dev_dbg(&s->dev, "not releasing unknown window\n");
return -EINVAL;
+ }
/* Shut down memory window */
- win->ctl.flags &= ~MAP_ACTIVE;
- s->ops->set_mem_map(s, &win->ctl);
- s->state &= ~SOCKET_WIN_REQ(win->index);
+ win->flags &= ~MAP_ACTIVE;
+ s->ops->set_mem_map(s, win);
+ s->state &= ~SOCKET_WIN_REQ(wh);
/* Release system memory */
- if (win->ctl.res) {
- release_resource(win->ctl.res);
- kfree(win->ctl.res);
- win->ctl.res = NULL;
+ if (win->res) {
+ release_resource(win->res);
+ kfree(win->res);
+ win->res = NULL;
}
- win->handle->_win &= ~CLIENT_WIN_REQ(win->index);
-
- win->magic = 0;
+ p_dev->_win &= ~CLIENT_WIN_REQ(wh);
return 0;
} /* pcmcia_release_window */
@@ -492,12 +442,14 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
return -ENODEV;
if (req->IntType & INT_CARDBUS) {
- ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n");
+ dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n");
return -EINVAL;
}
c = p_dev->function_config;
- if (c->state & CONFIG_LOCKED)
+ if (c->state & CONFIG_LOCKED) {
+ dev_dbg(&s->dev, "Configuration is locked\n");
return -EACCES;
+ }
/* Do power control. We don't allow changes in Vcc. */
s->socket.Vpp = req->Vpp;
@@ -609,40 +561,44 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
struct pcmcia_socket *s = p_dev->socket;
config_t *c;
- if (!(s->state & SOCKET_PRESENT))
+ if (!(s->state & SOCKET_PRESENT)) {
+ dev_dbg(&s->dev, "No card present\n");
return -ENODEV;
+ }
if (!req)
return -EINVAL;
c = p_dev->function_config;
- if (c->state & CONFIG_LOCKED)
+ if (c->state & CONFIG_LOCKED) {
+ dev_dbg(&s->dev, "Configuration is locked\n");
return -EACCES;
+ }
if (c->state & CONFIG_IO_REQ) {
- ds_dbg(s, 0, "IO already configured\n");
+ dev_dbg(&s->dev, "IO already configured\n");
return -EBUSY;
}
if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
- ds_dbg(s, 0, "bad attribute setting for IO region 1\n");
+ dev_dbg(&s->dev, "bad attribute setting for IO region 1\n");
return -EINVAL;
}
if ((req->NumPorts2 > 0) &&
(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
- ds_dbg(s, 0, "bad attribute setting for IO region 2\n");
+ dev_dbg(&s->dev, "bad attribute setting for IO region 2\n");
return -EINVAL;
}
- ds_dbg(s, 1, "trying to allocate resource 1\n");
+ dev_dbg(&s->dev, "trying to allocate resource 1\n");
if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
req->NumPorts1, req->IOAddrLines)) {
- ds_dbg(s, 0, "allocation of resource 1 failed\n");
+ dev_dbg(&s->dev, "allocation of resource 1 failed\n");
return -EBUSY;
}
if (req->NumPorts2) {
- ds_dbg(s, 1, "trying to allocate resource 2\n");
+ dev_dbg(&s->dev, "trying to allocate resource 2\n");
if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
req->NumPorts2, req->IOAddrLines)) {
- ds_dbg(s, 0, "allocation of resource 2 failed\n");
+ dev_dbg(&s->dev, "allocation of resource 2 failed\n");
release_io_space(s, req->BasePort1, req->NumPorts1);
return -EBUSY;
}
@@ -680,13 +636,17 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
int ret = -EINVAL, irq = 0;
int type;
- if (!(s->state & SOCKET_PRESENT))
+ if (!(s->state & SOCKET_PRESENT)) {
+ dev_dbg(&s->dev, "No card present\n");
return -ENODEV;
+ }
c = p_dev->function_config;
- if (c->state & CONFIG_LOCKED)
+ if (c->state & CONFIG_LOCKED) {
+ dev_dbg(&s->dev, "Configuration is locked\n");
return -EACCES;
+ }
if (c->state & CONFIG_IRQ_REQ) {
- ds_dbg(s, 0, "IRQ already configured\n");
+ dev_dbg(&s->dev, "IRQ already configured\n");
return -EBUSY;
}
@@ -704,7 +664,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
/* if the underlying IRQ infrastructure allows for it, only allocate
* the IRQ, but do not enable it
*/
- if (!(req->Attributes & IRQ_HANDLE_PRESENT))
+ if (!(req->Handler))
type |= IRQ_NOAUTOEN;
#endif /* IRQ_NOAUTOEN */
@@ -714,7 +674,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
} else {
int try;
u32 mask = s->irq_mask;
- void *data = &p_dev->dev.driver; /* something unique to this device */
+ void *data = p_dev; /* something unique to this device */
for (try = 0; try < 64; try++) {
irq = try % 32;
@@ -731,12 +691,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
* registering a dummy handle works, i.e. if the IRQ isn't
* marked as used by the kernel resource management core */
ret = request_irq(irq,
- (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,
+ (req->Handler) ? req->Handler : test_action,
type,
p_dev->devname,
- (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
+ (req->Handler) ? p_dev->priv : data);
if (!ret) {
- if (!(req->Attributes & IRQ_HANDLE_PRESENT))
+ if (!req->Handler)
free_irq(irq, data);
break;
}
@@ -745,17 +705,22 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
#endif
/* only assign PCI irq if no IRQ already assigned */
if (ret && !s->irq.AssignedIRQ) {
- if (!s->pci_irq)
+ if (!s->pci_irq) {
+ dev_printk(KERN_INFO, &s->dev, "no IRQ found\n");
return ret;
+ }
type = IRQF_SHARED;
irq = s->pci_irq;
}
- if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
+ if (ret && req->Handler) {
ret = request_irq(irq, req->Handler, type,
- p_dev->devname, req->Instance);
- if (ret)
+ p_dev->devname, p_dev->priv);
+ if (ret) {
+ dev_printk(KERN_INFO, &s->dev,
+ "request_irq() failed\n");
return ret;
+ }
}
/* Make sure the fact the request type was overridden is passed back */
@@ -787,17 +752,19 @@ EXPORT_SYMBOL(pcmcia_request_irq);
* Request_window() establishes a mapping between card memory space
* and system memory space.
*/
-int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh)
+int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_handle_t *wh)
{
- struct pcmcia_socket *s = (*p_dev)->socket;
- window_t *win;
+ struct pcmcia_socket *s = p_dev->socket;
+ pccard_mem_map *win;
u_long align;
int w;
- if (!(s->state & SOCKET_PRESENT))
+ if (!(s->state & SOCKET_PRESENT)) {
+ dev_dbg(&s->dev, "No card present\n");
return -ENODEV;
+ }
if (req->Attributes & (WIN_PAGED | WIN_SHARED)) {
- ds_dbg(s, 0, "bad attribute setting for iomem region\n");
+ dev_dbg(&s->dev, "bad attribute setting for iomem region\n");
return -EINVAL;
}
@@ -808,12 +775,12 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
(req->Attributes & WIN_STRICT_ALIGN)) ?
req->Size : s->map_size);
if (req->Size & (s->map_size-1)) {
- ds_dbg(s, 0, "invalid map size\n");
+ dev_dbg(&s->dev, "invalid map size\n");
return -EINVAL;
}
if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
(req->Base & (align-1))) {
- ds_dbg(s, 0, "invalid base address\n");
+ dev_dbg(&s->dev, "invalid base address\n");
return -EINVAL;
}
if (req->Base)
@@ -823,52 +790,48 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
for (w = 0; w < MAX_WIN; w++)
if (!(s->state & SOCKET_WIN_REQ(w))) break;
if (w == MAX_WIN) {
- ds_dbg(s, 0, "all windows are used already\n");
+ dev_dbg(&s->dev, "all windows are used already\n");
return -EINVAL;
}
win = &s->win[w];
- win->magic = WINDOW_MAGIC;
- win->index = w;
- win->handle = *p_dev;
- win->sock = s;
if (!(s->features & SS_CAP_STATIC_MAP)) {
- win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
+ win->res = pcmcia_find_mem_region(req->Base, req->Size, align,
(req->Attributes & WIN_MAP_BELOW_1MB), s);
- if (!win->ctl.res) {
- ds_dbg(s, 0, "allocating mem region failed\n");
+ if (!win->res) {
+ dev_dbg(&s->dev, "allocating mem region failed\n");
return -EINVAL;
}
}
- (*p_dev)->_win |= CLIENT_WIN_REQ(w);
+ p_dev->_win |= CLIENT_WIN_REQ(w);
/* Configure the socket controller */
- win->ctl.map = w+1;
- win->ctl.flags = 0;
- win->ctl.speed = req->AccessSpeed;
+ win->map = w+1;
+ win->flags = 0;
+ win->speed = req->AccessSpeed;
if (req->Attributes & WIN_MEMORY_TYPE)
- win->ctl.flags |= MAP_ATTRIB;
+ win->flags |= MAP_ATTRIB;
if (req->Attributes & WIN_ENABLE)
- win->ctl.flags |= MAP_ACTIVE;
+ win->flags |= MAP_ACTIVE;
if (req->Attributes & WIN_DATA_WIDTH_16)
- win->ctl.flags |= MAP_16BIT;
+ win->flags |= MAP_16BIT;
if (req->Attributes & WIN_USE_WAIT)
- win->ctl.flags |= MAP_USE_WAIT;
- win->ctl.card_start = 0;
- if (s->ops->set_mem_map(s, &win->ctl) != 0) {
- ds_dbg(s, 0, "failed to set memory mapping\n");
+ win->flags |= MAP_USE_WAIT;
+ win->card_start = 0;
+ if (s->ops->set_mem_map(s, win) != 0) {
+ dev_dbg(&s->dev, "failed to set memory mapping\n");
return -EIO;
}
s->state |= SOCKET_WIN_REQ(w);
/* Return window handle */
if (s->features & SS_CAP_STATIC_MAP) {
- req->Base = win->ctl.static_start;
+ req->Base = win->static_start;
} else {
- req->Base = win->ctl.res->start;
+ req->Base = win->res->start;
}
- *wh = win;
+ *wh = w + 1;
return 0;
} /* pcmcia_request_window */
@@ -879,19 +842,46 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
pcmcia_release_io(p_dev, &p_dev->io);
pcmcia_release_irq(p_dev, &p_dev->irq);
if (p_dev->win)
- pcmcia_release_window(p_dev->win);
+ pcmcia_release_window(p_dev, p_dev->win);
}
EXPORT_SYMBOL(pcmcia_disable_device);
struct pcmcia_cfg_mem {
- tuple_t tuple;
+ struct pcmcia_device *p_dev;
+ void *priv_data;
+ int (*conf_check) (struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data);
cisparse_t parse;
- u8 buf[256];
cistpl_cftable_entry_t dflt;
};
/**
+ * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
+ *
+ * pcmcia_do_loop_config() is the internal callback for the call from
+ * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
+ * by a struct pcmcia_cfg_mem.
+ */
+static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
+{
+ cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
+ struct pcmcia_cfg_mem *cfg_mem = priv;
+
+ /* default values */
+ cfg_mem->p_dev->conf.ConfigIndex = cfg->index;
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ cfg_mem->dflt = *cfg;
+
+ return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt,
+ cfg_mem->p_dev->socket->socket.Vcc,
+ cfg_mem->priv_data);
+}
+
+/**
* pcmcia_loop_config() - loop over configuration options
* @p_dev: the struct pcmcia_device which we need to loop for.
* @conf_check: function to call for each configuration option.
@@ -913,48 +903,174 @@ int pcmcia_loop_config(struct pcmcia_device *p_dev,
void *priv_data)
{
struct pcmcia_cfg_mem *cfg_mem;
-
- tuple_t *tuple;
int ret;
- unsigned int vcc;
cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
if (cfg_mem == NULL)
return -ENOMEM;
- /* get the current Vcc setting */
- vcc = p_dev->socket->socket.Vcc;
+ cfg_mem->p_dev = p_dev;
+ cfg_mem->conf_check = conf_check;
+ cfg_mem->priv_data = priv_data;
- tuple = &cfg_mem->tuple;
- tuple->TupleData = cfg_mem->buf;
- tuple->TupleDataMax = 255;
- tuple->TupleOffset = 0;
- tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
- tuple->Attributes = 0;
+ ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
+ CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
+ cfg_mem, pcmcia_do_loop_config);
- ret = pcmcia_get_first_tuple(p_dev, tuple);
- while (!ret) {
- cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry;
+ kfree(cfg_mem);
+ return ret;
+}
+EXPORT_SYMBOL(pcmcia_loop_config);
+
+
+struct pcmcia_loop_mem {
+ struct pcmcia_device *p_dev;
+ void *priv_data;
+ int (*loop_tuple) (struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv_data);
+};
+
+/**
+ * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
+ *
+ * pcmcia_do_loop_tuple() is the internal callback for the call from
+ * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
+ * by a struct pcmcia_cfg_mem.
+ */
+static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
+{
+ struct pcmcia_loop_mem *loop = priv;
+
+ return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
+};
+
+/**
+ * pcmcia_loop_tuple() - loop over tuples in the CIS
+ * @p_dev: the struct pcmcia_device which we need to loop for.
+ * @code: which CIS code shall we look for?
+ * @priv_data: private data to be passed to the loop_tuple function.
+ * @loop_tuple: function to call for each CIS entry of type @function. IT
+ * gets passed the raw tuple and @priv_data.
+ *
+ * pcmcia_loop_tuple() loops over all CIS entries of type @function, and
+ * calls the @loop_tuple function for each entry. If the call to @loop_tuple
+ * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
+ */
+int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+ int (*loop_tuple) (struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv_data),
+ void *priv_data)
+{
+ struct pcmcia_loop_mem loop = {
+ .p_dev = p_dev,
+ .loop_tuple = loop_tuple,
+ .priv_data = priv_data};
- if (pcmcia_get_tuple_data(p_dev, tuple))
- goto next_entry;
+ return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
+ &loop, pcmcia_do_loop_tuple);
+};
+EXPORT_SYMBOL(pcmcia_loop_tuple);
- if (pcmcia_parse_tuple(tuple, &cfg_mem->parse))
- goto next_entry;
- /* default values */
- p_dev->conf.ConfigIndex = cfg->index;
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
- cfg_mem->dflt = *cfg;
+struct pcmcia_loop_get {
+ size_t len;
+ cisdata_t **buf;
+};
- ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data);
- if (!ret)
- break;
+/**
+ * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
+ *
+ * pcmcia_do_get_tuple() is the internal callback for the call from
+ * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
+ * the first tuple, return 0 unconditionally. Create a memory buffer large
+ * enough to hold the content of the tuple, and fill it with the tuple data.
+ * The caller is responsible to free the buffer.
+ */
+static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
+ void *priv)
+{
+ struct pcmcia_loop_get *get = priv;
+
+ *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
+ if (*get->buf) {
+ get->len = tuple->TupleDataLen;
+ memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
+ } else
+ dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
+ return 0;
+};
-next_entry:
- ret = pcmcia_get_next_tuple(p_dev, tuple);
+/**
+ * pcmcia_get_tuple() - get first tuple from CIS
+ * @p_dev: the struct pcmcia_device which we need to loop for.
+ * @code: which CIS code shall we look for?
+ * @buf: pointer to store the buffer to.
+ *
+ * pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
+ * It returns the buffer length (or zero). The caller is responsible to free
+ * the buffer passed in @buf.
+ */
+size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+ unsigned char **buf)
+{
+ struct pcmcia_loop_get get = {
+ .len = 0,
+ .buf = buf,
+ };
+
+ *get.buf = NULL;
+ pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
+
+ return get.len;
+};
+EXPORT_SYMBOL(pcmcia_get_tuple);
+
+
+/**
+ * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
+ *
+ * pcmcia_do_get_mac() is the internal callback for the call from
+ * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
+ * tuple contains a proper LAN_NODE_ID of length 6, and copy the data
+ * to struct net_device->dev_addr[i].
+ */
+static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
+ void *priv)
+{
+ struct net_device *dev = priv;
+ int i;
+
+ if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
+ return -EINVAL;
+ if (tuple->TupleDataLen < ETH_ALEN + 2) {
+ dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
+ "LAN_NODE_ID\n");
+ return -EINVAL;
}
- return ret;
-}
-EXPORT_SYMBOL(pcmcia_loop_config);
+ if (tuple->TupleData[1] != ETH_ALEN) {
+ dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = tuple->TupleData[i+2];
+ return 0;
+};
+
+/**
+ * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
+ * @p_dev: the struct pcmcia_device for which we want the address.
+ * @dev: a properly prepared struct net_device to store the info to.
+ *
+ * pcmcia_get_mac_from_cis() reads out the hardware MAC address from
+ * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
+ * must be set up properly by the driver (see examples!).
+ */
+int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
+{
+ return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
+};
+EXPORT_SYMBOL(pcmcia_get_mac_from_cis);
+
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 1c39d3438f20..e1741cd875aa 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -213,7 +213,8 @@ static irqreturn_t pd6729_interrupt(int irq, void *dev)
if (csc & I365_CSC_DETECT) {
events |= SS_DETECT;
- dprintk("Card detected in socket %i!\n", i);
+ dev_vdbg(&socket[i].socket.dev,
+ "Card detected in socket %i!\n", i);
}
if (indirect_read(&socket[i], I365_INTCTL)
@@ -331,11 +332,11 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
if (state->flags & SS_PWR_AUTO) {
- dprintk("Auto power\n");
+ dev_dbg(&sock->dev, "Auto power\n");
reg |= I365_PWR_AUTO; /* automatic power mngmnt */
}
if (state->flags & SS_OUTPUT_ENA) {
- dprintk("Power Enabled\n");
+ dev_dbg(&sock->dev, "Power Enabled\n");
reg |= I365_PWR_OUT; /* enable power */
}
@@ -343,40 +344,44 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
case 0:
break;
case 33:
- dprintk("setting voltage to Vcc to 3.3V on socket %i\n",
+ dev_dbg(&sock->dev,
+ "setting voltage to Vcc to 3.3V on socket %i\n",
socket->number);
reg |= I365_VCC_5V;
indirect_setbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
break;
case 50:
- dprintk("setting voltage to Vcc to 5V on socket %i\n",
+ dev_dbg(&sock->dev,
+ "setting voltage to Vcc to 5V on socket %i\n",
socket->number);
reg |= I365_VCC_5V;
indirect_resetbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
break;
default:
- dprintk("pd6729: pd6729_set_socket called with "
- "invalid VCC power value: %i\n",
- state->Vcc);
+ dev_dbg(&sock->dev,
+ "pd6729_set_socket called with invalid VCC power "
+ "value: %i\n", state->Vcc);
return -EINVAL;
}
switch (state->Vpp) {
case 0:
- dprintk("not setting Vpp on socket %i\n", socket->number);
+ dev_dbg(&sock->dev, "not setting Vpp on socket %i\n",
+ socket->number);
break;
case 33:
case 50:
- dprintk("setting Vpp to Vcc for socket %i\n", socket->number);
+ dev_dbg(&sock->dev, "setting Vpp to Vcc for socket %i\n",
+ socket->number);
reg |= I365_VPP1_5V;
break;
case 120:
- dprintk("setting Vpp to 12.0\n");
+ dev_dbg(&sock->dev, "setting Vpp to 12.0\n");
reg |= I365_VPP1_12V;
break;
default:
- dprintk("pd6729: pd6729_set_socket called with invalid VPP power value: %i\n",
- state->Vpp);
+ dev_dbg(&sock->dev, "pd6729: pd6729_set_socket called with "
+ "invalid VPP power value: %i\n", state->Vpp);
return -EINVAL;
}
@@ -438,7 +443,7 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock,
/* Check error conditions */
if (map > 1) {
- dprintk("pd6729_set_io_map with invalid map");
+ dev_dbg(&sock->dev, "pd6729_set_io_map with invalid map\n");
return -EINVAL;
}
@@ -446,7 +451,7 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock,
if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_IO(map))
indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_IO(map));
- /* dprintk("set_io_map: Setting range to %x - %x\n",
+ /* dev_dbg(&sock->dev, "set_io_map: Setting range to %x - %x\n",
io->start, io->stop);*/
/* write the new values */
@@ -478,12 +483,12 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock,
map = mem->map;
if (map > 4) {
- printk("pd6729_set_mem_map: invalid map");
+ dev_warn(&sock->dev, "invalid map requested\n");
return -EINVAL;
}
if ((mem->res->start > mem->res->end) || (mem->speed > 1000)) {
- printk("pd6729_set_mem_map: invalid address / speed");
+ dev_warn(&sock->dev, "invalid invalid address / speed\n");
return -EINVAL;
}
@@ -529,12 +534,12 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock,
if (mem->flags & MAP_WRPROT)
i |= I365_MEM_WRPROT;
if (mem->flags & MAP_ATTRIB) {
- /* dprintk("requesting attribute memory for socket %i\n",
- socket->number);*/
+ /* dev_dbg(&sock->dev, "requesting attribute memory for "
+ "socket %i\n", socket->number);*/
i |= I365_MEM_REG;
} else {
- /* dprintk("requesting normal memory for socket %i\n",
- socket->number);*/
+ /* dev_dbg(&sock->dev, "requesting normal memory for "
+ "socket %i\n", socket->number);*/
}
indirect_write16(socket, base + I365_W_OFF, i);
@@ -577,7 +582,7 @@ static struct pccard_operations pd6729_operations = {
static irqreturn_t pd6729_test(int irq, void *dev)
{
- dprintk("-> hit on irq %d\n", irq);
+ pr_devel("-> hit on irq %d\n", irq);
return IRQ_HANDLED;
}
@@ -641,8 +646,14 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
if ((ret = pci_enable_device(dev)))
goto err_out_free_mem;
- printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge "
- "at 0x%llx on irq %d\n",
+ if (!pci_resource_start(dev, 0)) {
+ dev_warn(&dev->dev, "refusing to load the driver as the "
+ "io_base is NULL.\n");
+ goto err_out_free_mem;
+ }
+
+ dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx "
+ "on irq %d\n",
(unsigned long long)pci_resource_start(dev, 0), dev->irq);
/*
* Since we have no memory BARs some firmware may not
@@ -650,14 +661,14 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
*/
pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
if (!(configbyte & PCI_COMMAND_MEMORY)) {
- printk(KERN_DEBUG "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
+ dev_dbg(&dev->dev, "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
configbyte |= PCI_COMMAND_MEMORY;
pci_write_config_byte(dev, PCI_COMMAND, configbyte);
}
ret = pci_request_regions(dev, "pd6729");
if (ret) {
- printk(KERN_INFO "pd6729: pci request region failed.\n");
+ dev_warn(&dev->dev, "pci request region failed.\n");
goto err_out_disable;
}
@@ -666,7 +677,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
mask = pd6729_isa_scan();
if (irq_mode == 0 && mask == 0) {
- printk(KERN_INFO "pd6729: no ISA interrupt is available.\n");
+ dev_warn(&dev->dev, "no ISA interrupt is available.\n");
goto err_out_free_res;
}
@@ -691,8 +702,8 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
/* Register the interrupt handler */
if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
"pd6729", socket))) {
- printk(KERN_ERR "pd6729: Failed to register irq %d, "
- "aborting\n", dev->irq);
+ dev_err(&dev->dev, "Failed to register irq %d\n",
+ dev->irq);
goto err_out_free_res;
}
} else {
@@ -707,8 +718,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
for (i = 0; i < MAX_SOCKETS; i++) {
ret = pcmcia_register_socket(&socket[i].socket);
if (ret) {
- printk(KERN_INFO "pd6729: pcmcia_register_socket "
- "failed.\n");
+ dev_warn(&dev->dev, "pcmcia_register_socket failed.\n");
for (j = 0; j < i ; j++)
pcmcia_unregister_socket(&socket[j].socket);
goto err_out_free_res2;
diff --git a/drivers/pcmcia/pd6729.h b/drivers/pcmcia/pd6729.h
index f392e458cdfd..41418d394c55 100644
--- a/drivers/pcmcia/pd6729.h
+++ b/drivers/pcmcia/pd6729.h
@@ -1,13 +1,6 @@
#ifndef _INCLUDE_GUARD_PD6729_H_
#define _INCLUDE_GUARD_PD6729_H_
-/* Debuging defines */
-#ifdef NOTRACE
-#define dprintk(fmt, args...) printk(fmt , ## args)
-#else
-#define dprintk(fmt, args...) do {} while (0)
-#endif
-
/* Flags for I365_GENCTL */
#define I365_DF_VS1 0x40 /* DF-step Voltage Sense */
#define I365_DF_VS2 0x80
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 0e35acb1366b..84dde7768ad5 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -228,9 +228,43 @@ static const char *skt_names[] = {
#define SKT_DEV_INFO_SIZE(n) \
(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
+int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
+{
+ skt->res_skt.start = _PCMCIA(skt->nr);
+ skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+ skt->res_skt.name = skt_names[skt->nr];
+ skt->res_skt.flags = IORESOURCE_MEM;
+
+ skt->res_io.start = _PCMCIAIO(skt->nr);
+ skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+ skt->res_io.name = "io";
+ skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ skt->res_mem.start = _PCMCIAMem(skt->nr);
+ skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+ skt->res_mem.name = "memory";
+ skt->res_mem.flags = IORESOURCE_MEM;
+
+ skt->res_attr.start = _PCMCIAAttr(skt->nr);
+ skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+ skt->res_attr.name = "attribute";
+ skt->res_attr.flags = IORESOURCE_MEM;
+
+ return soc_pcmcia_add_one(skt);
+}
+
+void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
+{
+ /* Provide our PXA2xx specific timing routines. */
+ ops->set_timing = pxa2xx_pcmcia_set_timing;
+#ifdef CONFIG_CPU_FREQ
+ ops->frequency_change = pxa2xx_pcmcia_frequency_change;
+#endif
+}
+
int __pxa2xx_drv_pcmcia_probe(struct device *dev)
{
- int i, ret;
+ int i, ret = 0;
struct pcmcia_low_level *ops;
struct skt_dev_info *sinfo;
struct soc_pcmcia_socket *skt;
@@ -240,6 +274,8 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
ops = (struct pcmcia_low_level *)dev->platform_data;
+ pxa2xx_drv_pcmcia_ops(ops);
+
sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
if (!sinfo)
return -ENOMEM;
@@ -250,40 +286,25 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
for (i = 0; i < ops->nr; i++) {
skt = &sinfo->skt[i];
- skt->nr = ops->first + i;
- skt->irq = NO_IRQ;
-
- skt->res_skt.start = _PCMCIA(skt->nr);
- skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
- skt->res_skt.name = skt_names[skt->nr];
- skt->res_skt.flags = IORESOURCE_MEM;
-
- skt->res_io.start = _PCMCIAIO(skt->nr);
- skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
- skt->res_io.name = "io";
- skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ skt->nr = ops->first + i;
+ skt->ops = ops;
+ skt->socket.owner = ops->owner;
+ skt->socket.dev.parent = dev;
+ skt->socket.pci_irq = NO_IRQ;
- skt->res_mem.start = _PCMCIAMem(skt->nr);
- skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
- skt->res_mem.name = "memory";
- skt->res_mem.flags = IORESOURCE_MEM;
-
- skt->res_attr.start = _PCMCIAAttr(skt->nr);
- skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
- skt->res_attr.name = "attribute";
- skt->res_attr.flags = IORESOURCE_MEM;
+ ret = pxa2xx_drv_pcmcia_add_one(skt);
+ if (ret)
+ break;
}
- /* Provide our PXA2xx specific timing routines. */
- ops->set_timing = pxa2xx_pcmcia_set_timing;
-#ifdef CONFIG_CPU_FREQ
- ops->frequency_change = pxa2xx_pcmcia_frequency_change;
-#endif
-
- ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo);
-
- if (!ret)
+ if (ret) {
+ while (--i >= 0)
+ soc_pcmcia_remove_one(&sinfo->skt[i]);
+ kfree(sinfo);
+ } else {
pxa2xx_configure_sockets(dev);
+ dev_set_drvdata(dev, sinfo);
+ }
return ret;
}
@@ -297,7 +318,16 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
{
- return soc_common_drv_pcmcia_remove(&dev->dev);
+ struct skt_dev_info *sinfo = platform_get_drvdata(dev);
+ int i;
+
+ platform_set_drvdata(dev, NULL);
+
+ for (i = 0; i < sinfo->nskt; i++)
+ soc_pcmcia_remove_one(&sinfo->skt[i]);
+
+ kfree(sinfo);
+ return 0;
}
static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h
index 235d681652c3..cb5efaec886f 100644
--- a/drivers/pcmcia/pxa2xx_base.h
+++ b/drivers/pcmcia/pxa2xx_base.h
@@ -1,3 +1,6 @@
/* temporary measure */
extern int __pxa2xx_drv_pcmcia_probe(struct device *);
+int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
+void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
+
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
index 5143a760153b..05913d0bbdbe 100644
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -44,7 +44,7 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
return ret;
gpio_direction_output(GPIO_PCMCIA_RESET, 0);
- skt->irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
+ skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
if (!ret)
gpio_free(GPIO_PCMCIA_RESET);
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index a7b943d01e34..5662646b84da 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -38,7 +38,7 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
return ret;
gpio_direction_output(GPIO_PCMCIA_RESET, 0);
- skt->irq = PCMCIA_S0_RDYINT;
+ skt->socket.pci_irq = PCMCIA_S0_RDYINT;
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
if (!ret)
gpio_free(GPIO_PCMCIA_RESET);
diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c
index d09c0dc4a31a..8bfbd4dca131 100644
--- a/drivers/pcmcia/pxa2xx_e740.c
+++ b/drivers/pcmcia/pxa2xx_e740.c
@@ -38,7 +38,7 @@ static struct pcmcia_irqs cd_irqs[] = {
static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
- skt->irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) :
+ skt->socket.pci_irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) :
IRQ_GPIO(GPIO_E740_PCMCIA_RDY1);
return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1);
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
index 6cbb1b1f7cfd..b9f8c8fb42bd 100644
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ b/drivers/pcmcia/pxa2xx_lubbock.c
@@ -32,6 +32,7 @@ static int
lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
+ struct sa1111_pcmcia_socket *s = to_skt(skt);
unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
int ret = 0;
@@ -149,7 +150,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
if (ret == 0) {
lubbock_set_misc_wr(misc_mask, misc_set);
- sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+ sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
}
#if 1
@@ -175,7 +176,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
* Switch to 5V, Configure socket with 5V voltage
*/
lubbock_set_misc_wr(misc_mask, 0);
- sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, 0);
+ sa1111_set_io(s->dev, pa_dwr_mask, 0);
/*
* It takes about 100ms to turn off Vcc.
@@ -200,12 +201,8 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
static struct pcmcia_low_level lubbock_pcmcia_ops = {
.owner = THIS_MODULE,
- .hw_init = sa1111_pcmcia_hw_init,
- .hw_shutdown = sa1111_pcmcia_hw_shutdown,
- .socket_state = sa1111_pcmcia_socket_state,
.configure_socket = lubbock_pcmcia_configure_socket,
.socket_init = sa1111_pcmcia_socket_init,
- .socket_suspend = sa1111_pcmcia_socket_suspend,
.first = 0,
.nr = 2,
};
@@ -228,8 +225,9 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev)
/* Set CF Socket 1 power to standby mode. */
lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
- sadev->dev.platform_data = &lubbock_pcmcia_ops;
- ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev);
+ pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
+ ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
+ pxa2xx_drv_pcmcia_add_one);
}
return ret;
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 1138551ba8f6..92016fe932b4 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -44,7 +44,7 @@ static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
* before we enable them as outputs.
*/
- skt->irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
+ skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c
index 5ba9b3664a00..6fb6f7f0672e 100644
--- a/drivers/pcmcia/pxa2xx_palmld.c
+++ b/drivers/pcmcia/pxa2xx_palmld.c
@@ -45,7 +45,7 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
if (ret)
goto err4;
- skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
+ skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
return 0;
err4:
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c
index e07b5c51ec5b..b07b247a399f 100644
--- a/drivers/pcmcia/pxa2xx_palmtx.c
+++ b/drivers/pcmcia/pxa2xx_palmtx.c
@@ -53,7 +53,7 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
if (ret)
goto err5;
- skt->irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
+ skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
return 0;
err5:
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index bc43f78f6f0b..0ea3b29440e6 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -66,7 +66,7 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
}
}
- skt->irq = SCOOP_DEV[skt->nr].irq;
+ skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq;
return 0;
}
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c
index e0e5cb339b4a..b7e596620db1 100644
--- a/drivers/pcmcia/pxa2xx_trizeps4.c
+++ b/drivers/pcmcia/pxa2xx_trizeps4.c
@@ -53,7 +53,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
gpio_free(GPIO_PRDY);
return -EINVAL;
}
- skt->irq = IRQ_GPIO(GPIO_PRDY);
+ skt->socket.pci_irq = IRQ_GPIO(GPIO_PRDY);
break;
#ifndef CONFIG_MACH_TRIZEPS_CONXS
@@ -63,7 +63,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
break;
}
/* release the reset of this card */
- pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->irq);
+ pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq);
/* supplementory irqs for the socket */
for (i = 0; i < ARRAY_SIZE(irqs); i++) {
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c
index 17871360fe99..27be2e154df2 100644
--- a/drivers/pcmcia/pxa2xx_viper.c
+++ b/drivers/pcmcia/pxa2xx_viper.c
@@ -40,7 +40,7 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
unsigned long flags;
- skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
+ skt->socket.pci_irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
goto err_request_cd;
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index e592e0e0d7ed..de0e770ce6a3 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -18,6 +18,7 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
#include "cs_internal.h"
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 9ca22c7aafb2..7039f3cf5b77 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -206,6 +206,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
/* First, what does a floating port look like? */
b = kzalloc(256, GFP_KERNEL);
if (!b) {
+ printk("\n");
dev_printk(KERN_ERR, &s->dev,
"do_io_probe: unable to kmalloc 256 bytes");
return;
@@ -275,7 +276,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res,
s->cis_mem.res = res;
s->cis_virt = ioremap(res->start, s->map_size);
if (s->cis_virt) {
- ret = pccard_validate_cis(s, BIND_FN_ALL, count);
+ ret = pccard_validate_cis(s, count);
/* invalidate mapping and CIS cache */
iounmap(s->cis_virt);
s->cis_virt = NULL;
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index ac8aa09ba0da..fd013a1ef47a 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = {
static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
- skt->irq = ASSABET_IRQ_GPIO_CF_IRQ;
+ skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
diff --git a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1100_badge4.c
index 1ca9737ea79e..1ce53f493bef 100644
--- a/drivers/pcmcia/sa1100_badge4.c
+++ b/drivers/pcmcia/sa1100_badge4.c
@@ -127,13 +127,10 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state
static struct pcmcia_low_level badge4_pcmcia_ops = {
.owner = THIS_MODULE,
- .hw_init = sa1111_pcmcia_hw_init,
- .hw_shutdown = sa1111_pcmcia_hw_shutdown,
- .socket_state = sa1111_pcmcia_socket_state,
.configure_socket = badge4_pcmcia_configure_socket,
-
.socket_init = sa1111_pcmcia_socket_init,
- .socket_suspend = sa1111_pcmcia_socket_suspend,
+ .first = 0,
+ .nr = 2,
};
int pcmcia_badge4_init(struct device *dev)
@@ -146,7 +143,9 @@ int pcmcia_badge4_init(struct device *dev)
__func__,
badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
- ret = sa11xx_drv_pcmcia_probe(dev, &badge4_pcmcia_ops, 0, 2);
+ sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops);
+ ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops,
+ sa11xx_drv_pcmcia_add_one);
}
return ret;
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
index 63e6bc431a0d..9bf088b17275 100644
--- a/drivers/pcmcia/sa1100_cerf.c
+++ b/drivers/pcmcia/sa1100_cerf.c
@@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = {
static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
- skt->irq = CERF_IRQ_GPIO_CF_IRQ;
+ skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 2d0e99751530..11cc3ba1260a 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -83,7 +83,16 @@ static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
{
- return soc_common_drv_pcmcia_remove(&dev->dev);
+ struct skt_dev_info *sinfo = platform_get_drvdata(dev);
+ int i;
+
+ platform_set_drvdata(dev, NULL);
+
+ for (i = 0; i < sinfo->nskt; i++)
+ soc_pcmcia_remove_one(&sinfo->skt[i]);
+
+ kfree(sinfo);
+ return 0;
}
static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index 0cc3748f3758..3a121ac697d6 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -25,8 +25,8 @@ static struct pcmcia_irqs irqs[] = {
static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
- skt->irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
- : IRQ_GPIO_H3600_PCMCIA_IRQ0;
+ skt->socket.pci_irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
+ : IRQ_GPIO_H3600_PCMCIA_IRQ0;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c
index 7eedb42f800c..6bcabee6bde4 100644
--- a/drivers/pcmcia/sa1100_jornada720.c
+++ b/drivers/pcmcia/sa1100_jornada720.c
@@ -22,25 +22,10 @@
#define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3)
#define SOCKET1_3V GPIO_GPIO3
-static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
- unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
- /*
- * What is all this crap for?
- */
- GRER |= 0x00000002;
- /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
- sa1111_set_io_dir(SA1111_DEV(skt->dev), pin, 0, 0);
- sa1111_set_io(SA1111_DEV(skt->dev), pin, 0);
- sa1111_set_sleep_io(SA1111_DEV(skt->dev), pin, 0);
-
- return sa1111_pcmcia_hw_init(skt);
-}
-
static int
jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
+ struct sa1111_pcmcia_socket *s = to_skt(skt);
unsigned int pa_dwr_mask, pa_dwr_set;
int ret;
@@ -97,7 +82,7 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
unsigned long flags;
local_irq_save(flags);
- sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+ sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
local_irq_restore(flags);
}
@@ -106,21 +91,30 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
static struct pcmcia_low_level jornada720_pcmcia_ops = {
.owner = THIS_MODULE,
- .hw_init = jornada720_pcmcia_hw_init,
- .hw_shutdown = sa1111_pcmcia_hw_shutdown,
- .socket_state = sa1111_pcmcia_socket_state,
.configure_socket = jornada720_pcmcia_configure_socket,
-
.socket_init = sa1111_pcmcia_socket_init,
- .socket_suspend = sa1111_pcmcia_socket_suspend,
+ .first = 0,
+ .nr = 2,
};
int __devinit pcmcia_jornada720_init(struct device *dev)
{
int ret = -ENODEV;
- if (machine_is_jornada720())
- ret = sa11xx_drv_pcmcia_probe(dev, &jornada720_pcmcia_ops, 0, 2);
+ if (machine_is_jornada720()) {
+ unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
+
+ GRER |= 0x00000002;
+
+ /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
+ sa1111_set_io_dir(dev, pin, 0, 0);
+ sa1111_set_io(dev, pin, 0);
+ sa1111_set_sleep_io(dev, pin, 0);
+
+ sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
+ ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
+ sa11xx_drv_pcmcia_add_one);
+ }
return ret;
}
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
index 0c76d337815b..c95639b5f2a0 100644
--- a/drivers/pcmcia/sa1100_neponset.c
+++ b/drivers/pcmcia/sa1100_neponset.c
@@ -43,6 +43,7 @@
static int
neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
+ struct sa1111_pcmcia_socket *s = to_skt(skt);
unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
int ret;
@@ -99,7 +100,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta
NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
local_irq_restore(flags);
- sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+ sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
}
return 0;
@@ -115,12 +116,10 @@ static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
static struct pcmcia_low_level neponset_pcmcia_ops = {
.owner = THIS_MODULE,
- .hw_init = sa1111_pcmcia_hw_init,
- .hw_shutdown = sa1111_pcmcia_hw_shutdown,
- .socket_state = sa1111_pcmcia_socket_state,
.configure_socket = neponset_pcmcia_configure_socket,
.socket_init = neponset_pcmcia_socket_init,
- .socket_suspend = sa1111_pcmcia_socket_suspend,
+ .first = 0,
+ .nr = 2,
};
int pcmcia_neponset_init(struct sa1111_dev *sadev)
@@ -135,7 +134,9 @@ int pcmcia_neponset_init(struct sa1111_dev *sadev)
sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
- ret = sa11xx_drv_pcmcia_probe(&sadev->dev, &neponset_pcmcia_ops, 0, 2);
+ sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
+ ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
+ sa11xx_drv_pcmcia_add_one);
}
return ret;
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index 46d8c1977c2a..c4d51867a050 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -28,7 +28,7 @@ static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 |
SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
- skt->irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
+ skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index 33a08ae09fdf..05bd504e6f18 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -28,7 +28,7 @@ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
- skt->irq = IRQ_GPIO_CF_IRQ;
+ skt->socket.pci_irq = IRQ_GPIO_CF_IRQ;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 4be4e172ffa1..de6bc333d299 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -28,23 +28,20 @@ static struct pcmcia_irqs irqs[] = {
{ 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1" },
};
-int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
- if (skt->irq == NO_IRQ)
- skt->irq = skt->nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
-
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
-void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{
- struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
- unsigned long status = sa1111_readl(sadev->mapbase + SA1111_PCSR);
+ struct sa1111_pcmcia_socket *s = to_skt(skt);
+ unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR);
switch (skt->nr) {
case 0:
@@ -71,7 +68,7 @@ void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_sta
int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
- struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
+ struct sa1111_pcmcia_socket *s = to_skt(skt);
unsigned int pccr_skt_mask, pccr_set_mask, val;
unsigned long flags;
@@ -100,10 +97,10 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT;
local_irq_save(flags);
- val = sa1111_readl(sadev->mapbase + SA1111_PCCR);
+ val = sa1111_readl(s->dev->mapbase + SA1111_PCCR);
val &= ~pccr_skt_mask;
val |= pccr_set_mask & pccr_skt_mask;
- sa1111_writel(val, sadev->mapbase + SA1111_PCCR);
+ sa1111_writel(val, s->dev->mapbase + SA1111_PCCR);
local_irq_restore(flags);
return 0;
@@ -114,15 +111,51 @@ void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
-void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
+int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
+ int (*add)(struct soc_pcmcia_socket *))
+{
+ struct sa1111_pcmcia_socket *s;
+ int i, ret = 0;
+
+ ops->hw_init = sa1111_pcmcia_hw_init;
+ ops->hw_shutdown = sa1111_pcmcia_hw_shutdown;
+ ops->socket_state = sa1111_pcmcia_socket_state;
+ ops->socket_suspend = sa1111_pcmcia_socket_suspend;
+
+ for (i = 0; i < ops->nr; i++) {
+ s = kzalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ s->soc.nr = ops->first + i;
+ s->soc.ops = ops;
+ s->soc.socket.owner = ops->owner;
+ s->soc.socket.dev.parent = &dev->dev;
+ s->soc.socket.pci_irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
+ s->dev = dev;
+
+ ret = add(&s->soc);
+ if (ret == 0) {
+ s->next = dev_get_drvdata(&dev->dev);
+ dev_set_drvdata(&dev->dev, s);
+ } else
+ kfree(s);
+ }
+
+ return ret;
+}
+
static int pcmcia_probe(struct sa1111_dev *dev)
{
void __iomem *base;
+ dev_set_drvdata(&dev->dev, NULL);
+
if (!request_mem_region(dev->res.start, 512,
SA1111_DRIVER_NAME(dev)))
return -EBUSY;
@@ -152,7 +185,15 @@ static int pcmcia_probe(struct sa1111_dev *dev)
static int __devexit pcmcia_remove(struct sa1111_dev *dev)
{
- soc_common_drv_pcmcia_remove(&dev->dev);
+ struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev);
+
+ dev_set_drvdata(&dev->dev, NULL);
+
+ for (; next = s->next, s; s = next) {
+ soc_pcmcia_remove_one(&s->soc);
+ kfree(s);
+ }
+
release_mem_region(dev->res.start, 512);
return 0;
}
diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h
index 10ced4a210d7..02dc8577cdaf 100644
--- a/drivers/pcmcia/sa1111_generic.h
+++ b/drivers/pcmcia/sa1111_generic.h
@@ -1,12 +1,23 @@
#include "soc_common.h"
#include "sa11xx_base.h"
-extern int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *);
-extern void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *);
+struct sa1111_pcmcia_socket {
+ struct soc_pcmcia_socket soc;
+ struct sa1111_dev *dev;
+ struct sa1111_pcmcia_socket *next;
+};
+
+static inline struct sa1111_pcmcia_socket *to_skt(struct soc_pcmcia_socket *s)
+{
+ return container_of(s, struct sa1111_pcmcia_socket, soc);
+}
+
+int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
+ int (*add)(struct soc_pcmcia_socket *));
+
extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
-extern void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *);
extern int pcmcia_badge4_init(struct device *);
extern int pcmcia_jornada720_init(struct device *);
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index e15d59f2d8a9..fc9a6527019b 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -171,12 +171,58 @@ static const char *skt_names[] = {
#define SKT_DEV_INFO_SIZE(n) \
(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
+int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
+{
+ skt->res_skt.start = _PCMCIA(skt->nr);
+ skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+ skt->res_skt.name = skt_names[skt->nr];
+ skt->res_skt.flags = IORESOURCE_MEM;
+
+ skt->res_io.start = _PCMCIAIO(skt->nr);
+ skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+ skt->res_io.name = "io";
+ skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ skt->res_mem.start = _PCMCIAMem(skt->nr);
+ skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+ skt->res_mem.name = "memory";
+ skt->res_mem.flags = IORESOURCE_MEM;
+
+ skt->res_attr.start = _PCMCIAAttr(skt->nr);
+ skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+ skt->res_attr.name = "attribute";
+ skt->res_attr.flags = IORESOURCE_MEM;
+
+ return soc_pcmcia_add_one(skt);
+}
+EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one);
+
+void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
+{
+ /*
+ * set default MECR calculation if the board specific
+ * code did not specify one...
+ */
+ if (!ops->get_timing)
+ ops->get_timing = sa1100_pcmcia_default_mecr_timing;
+
+ /* Provide our SA11x0 specific timing routines. */
+ ops->set_timing = sa1100_pcmcia_set_timing;
+ ops->show_timing = sa1100_pcmcia_show_timing;
+#ifdef CONFIG_CPU_FREQ
+ ops->frequency_change = sa1100_pcmcia_frequency_change;
+#endif
+}
+EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops);
+
int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
int first, int nr)
{
struct skt_dev_info *sinfo;
struct soc_pcmcia_socket *skt;
- int i;
+ int i, ret = 0;
+
+ sa11xx_drv_pcmcia_ops(ops);
sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
if (!sinfo)
@@ -188,45 +234,26 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
for (i = 0; i < nr; i++) {
skt = &sinfo->skt[i];
- skt->nr = first + i;
- skt->irq = NO_IRQ;
-
- skt->res_skt.start = _PCMCIA(skt->nr);
- skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
- skt->res_skt.name = skt_names[skt->nr];
- skt->res_skt.flags = IORESOURCE_MEM;
-
- skt->res_io.start = _PCMCIAIO(skt->nr);
- skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
- skt->res_io.name = "io";
- skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ skt->nr = first + i;
+ skt->ops = ops;
+ skt->socket.owner = ops->owner;
+ skt->socket.dev.parent = dev;
+ skt->socket.pci_irq = NO_IRQ;
- skt->res_mem.start = _PCMCIAMem(skt->nr);
- skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
- skt->res_mem.name = "memory";
- skt->res_mem.flags = IORESOURCE_MEM;
-
- skt->res_attr.start = _PCMCIAAttr(skt->nr);
- skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
- skt->res_attr.name = "attribute";
- skt->res_attr.flags = IORESOURCE_MEM;
+ ret = sa11xx_drv_pcmcia_add_one(skt);
+ if (ret)
+ break;
}
- /*
- * set default MECR calculation if the board specific
- * code did not specify one...
- */
- if (!ops->get_timing)
- ops->get_timing = sa1100_pcmcia_default_mecr_timing;
-
- /* Provide our SA11x0 specific timing routines. */
- ops->set_timing = sa1100_pcmcia_set_timing;
- ops->show_timing = sa1100_pcmcia_show_timing;
-#ifdef CONFIG_CPU_FREQ
- ops->frequency_change = sa1100_pcmcia_frequency_change;
-#endif
+ if (ret) {
+ while (--i >= 0)
+ soc_pcmcia_remove_one(&sinfo->skt[i]);
+ kfree(sinfo);
+ } else {
+ dev_set_drvdata(dev, sinfo);
+ }
- return soc_common_drv_pcmcia_probe(dev, ops, sinfo);
+ return ret;
}
EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
diff --git a/drivers/pcmcia/sa11xx_base.h b/drivers/pcmcia/sa11xx_base.h
index 7bc208280527..3d76d720f463 100644
--- a/drivers/pcmcia/sa11xx_base.h
+++ b/drivers/pcmcia/sa11xx_base.h
@@ -118,6 +118,8 @@ static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz,
}
+int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
+void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
#endif /* !defined(_PCMCIA_SA1100_H) */
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 163cf98e2386..6f1a86b43c60 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -144,10 +144,10 @@ soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *stat
*/
if (skt->irq_state != 1 && state->io_irq) {
skt->irq_state = 1;
- set_irq_type(skt->irq, IRQ_TYPE_EDGE_FALLING);
+ set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING);
} else if (skt->irq_state == 1 && state->io_irq == 0) {
skt->irq_state = 0;
- set_irq_type(skt->irq, IRQ_TYPE_NONE);
+ set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
}
skt->cs_state = *state;
@@ -336,8 +336,9 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
unsigned short speed = map->speed;
- debug(skt, 2, "map %u speed %u start 0x%08x stop 0x%08x\n",
- map->map, map->speed, map->start, map->stop);
+ debug(skt, 2, "map %u speed %u start 0x%08llx stop 0x%08llx\n",
+ map->map, map->speed, (unsigned long long)map->start,
+ (unsigned long long)map->stop);
debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
(map->flags==0)?"<NONE>":"",
(map->flags&MAP_ACTIVE)?"ACTIVE ":"",
@@ -491,7 +492,8 @@ static ssize_t show_status(struct device *dev, struct device_attribute *attr, ch
p+=sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc);
p+=sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp);
- p+=sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq, skt->irq);
+ p+=sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq,
+ skt->socket.pci_irq);
if (skt->ops->show_timing)
p+=skt->ops->show_timing(skt, p);
@@ -573,7 +575,7 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
-LIST_HEAD(soc_pcmcia_sockets);
+static LIST_HEAD(soc_pcmcia_sockets);
static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
#ifdef CONFIG_CPU_FREQ
@@ -608,177 +610,137 @@ static int soc_pcmcia_cpufreq_register(void)
"notifier for PCMCIA (%d)\n", ret);
return ret;
}
+fs_initcall(soc_pcmcia_cpufreq_register);
static void soc_pcmcia_cpufreq_unregister(void)
{
cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
}
+module_exit(soc_pcmcia_cpufreq_unregister);
-#else
-static int soc_pcmcia_cpufreq_register(void) { return 0; }
-static void soc_pcmcia_cpufreq_unregister(void) {}
#endif
-int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
- struct skt_dev_info *sinfo)
+void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
{
- struct soc_pcmcia_socket *skt;
- int ret, i;
-
mutex_lock(&soc_pcmcia_sockets_lock);
+ del_timer_sync(&skt->poll_timer);
- /*
- * Initialise the per-socket structure.
- */
- for (i = 0; i < sinfo->nskt; i++) {
- skt = &sinfo->skt[i];
+ pcmcia_unregister_socket(&skt->socket);
- skt->socket.ops = &soc_common_pcmcia_operations;
- skt->socket.owner = ops->owner;
- skt->socket.dev.parent = dev;
+ flush_scheduled_work();
- init_timer(&skt->poll_timer);
- skt->poll_timer.function = soc_common_pcmcia_poll_event;
- skt->poll_timer.data = (unsigned long)skt;
- skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
+ skt->ops->hw_shutdown(skt);
- skt->dev = dev;
- skt->ops = ops;
+ soc_common_pcmcia_config_skt(skt, &dead_socket);
- ret = request_resource(&iomem_resource, &skt->res_skt);
- if (ret)
- goto out_err_1;
+ list_del(&skt->node);
+ mutex_unlock(&soc_pcmcia_sockets_lock);
- ret = request_resource(&skt->res_skt, &skt->res_io);
- if (ret)
- goto out_err_2;
+ iounmap(skt->virt_io);
+ skt->virt_io = NULL;
+ release_resource(&skt->res_attr);
+ release_resource(&skt->res_mem);
+ release_resource(&skt->res_io);
+ release_resource(&skt->res_skt);
+}
+EXPORT_SYMBOL(soc_pcmcia_remove_one);
- ret = request_resource(&skt->res_skt, &skt->res_mem);
- if (ret)
- goto out_err_3;
+int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
+{
+ int ret;
- ret = request_resource(&skt->res_skt, &skt->res_attr);
- if (ret)
- goto out_err_4;
+ init_timer(&skt->poll_timer);
+ skt->poll_timer.function = soc_common_pcmcia_poll_event;
+ skt->poll_timer.data = (unsigned long)skt;
+ skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
- skt->virt_io = ioremap(skt->res_io.start, 0x10000);
- if (skt->virt_io == NULL) {
- ret = -ENOMEM;
- goto out_err_5;
- }
+ ret = request_resource(&iomem_resource, &skt->res_skt);
+ if (ret)
+ goto out_err_1;
- if (list_empty(&soc_pcmcia_sockets))
- soc_pcmcia_cpufreq_register();
+ ret = request_resource(&skt->res_skt, &skt->res_io);
+ if (ret)
+ goto out_err_2;
- list_add(&skt->node, &soc_pcmcia_sockets);
+ ret = request_resource(&skt->res_skt, &skt->res_mem);
+ if (ret)
+ goto out_err_3;
- /*
- * We initialize default socket timing here, because
- * we are not guaranteed to see a SetIOMap operation at
- * runtime.
- */
- ops->set_timing(skt);
+ ret = request_resource(&skt->res_skt, &skt->res_attr);
+ if (ret)
+ goto out_err_4;
- ret = ops->hw_init(skt);
- if (ret)
- goto out_err_6;
+ skt->virt_io = ioremap(skt->res_io.start, 0x10000);
+ if (skt->virt_io == NULL) {
+ ret = -ENOMEM;
+ goto out_err_5;
+ }
- skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
- skt->socket.resource_ops = &pccard_static_ops;
- skt->socket.irq_mask = 0;
- skt->socket.map_size = PAGE_SIZE;
- skt->socket.pci_irq = skt->irq;
- skt->socket.io_offset = (unsigned long)skt->virt_io;
+ mutex_lock(&soc_pcmcia_sockets_lock);
- skt->status = soc_common_pcmcia_skt_state(skt);
+ list_add(&skt->node, &soc_pcmcia_sockets);
- ret = pcmcia_register_socket(&skt->socket);
- if (ret)
- goto out_err_7;
+ /*
+ * We initialize default socket timing here, because
+ * we are not guaranteed to see a SetIOMap operation at
+ * runtime.
+ */
+ skt->ops->set_timing(skt);
- WARN_ON(skt->socket.sock != i);
+ ret = skt->ops->hw_init(skt);
+ if (ret)
+ goto out_err_6;
- add_timer(&skt->poll_timer);
+ skt->socket.ops = &soc_common_pcmcia_operations;
+ skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
+ skt->socket.resource_ops = &pccard_static_ops;
+ skt->socket.irq_mask = 0;
+ skt->socket.map_size = PAGE_SIZE;
+ skt->socket.io_offset = (unsigned long)skt->virt_io;
- ret = device_create_file(&skt->socket.dev, &dev_attr_status);
- if (ret)
- goto out_err_8;
- }
+ skt->status = soc_common_pcmcia_skt_state(skt);
- dev_set_drvdata(dev, sinfo);
- ret = 0;
- goto out;
+ ret = pcmcia_register_socket(&skt->socket);
+ if (ret)
+ goto out_err_7;
- do {
- skt = &sinfo->skt[i];
+ add_timer(&skt->poll_timer);
+
+ mutex_unlock(&soc_pcmcia_sockets_lock);
+
+ ret = device_create_file(&skt->socket.dev, &dev_attr_status);
+ if (ret)
+ goto out_err_8;
+
+ return ret;
- device_remove_file(&skt->socket.dev, &dev_attr_status);
out_err_8:
- del_timer_sync(&skt->poll_timer);
- pcmcia_unregister_socket(&skt->socket);
+ mutex_lock(&soc_pcmcia_sockets_lock);
+ del_timer_sync(&skt->poll_timer);
+ pcmcia_unregister_socket(&skt->socket);
out_err_7:
- flush_scheduled_work();
+ flush_scheduled_work();
- ops->hw_shutdown(skt);
+ skt->ops->hw_shutdown(skt);
out_err_6:
- list_del(&skt->node);
- iounmap(skt->virt_io);
+ list_del(&skt->node);
+ mutex_unlock(&soc_pcmcia_sockets_lock);
+ iounmap(skt->virt_io);
out_err_5:
- release_resource(&skt->res_attr);
+ release_resource(&skt->res_attr);
out_err_4:
- release_resource(&skt->res_mem);
+ release_resource(&skt->res_mem);
out_err_3:
- release_resource(&skt->res_io);
+ release_resource(&skt->res_io);
out_err_2:
- release_resource(&skt->res_skt);
+ release_resource(&skt->res_skt);
out_err_1:
- i--;
- } while (i > 0);
- kfree(sinfo);
-
- out:
- mutex_unlock(&soc_pcmcia_sockets_lock);
return ret;
}
+EXPORT_SYMBOL(soc_pcmcia_add_one);
-int soc_common_drv_pcmcia_remove(struct device *dev)
-{
- struct skt_dev_info *sinfo = dev_get_drvdata(dev);
- int i;
-
- dev_set_drvdata(dev, NULL);
-
- mutex_lock(&soc_pcmcia_sockets_lock);
- for (i = 0; i < sinfo->nskt; i++) {
- struct soc_pcmcia_socket *skt = &sinfo->skt[i];
-
- del_timer_sync(&skt->poll_timer);
-
- pcmcia_unregister_socket(&skt->socket);
-
- flush_scheduled_work();
-
- skt->ops->hw_shutdown(skt);
-
- soc_common_pcmcia_config_skt(skt, &dead_socket);
-
- list_del(&skt->node);
- iounmap(skt->virt_io);
- skt->virt_io = NULL;
- release_resource(&skt->res_attr);
- release_resource(&skt->res_mem);
- release_resource(&skt->res_io);
- release_resource(&skt->res_skt);
- }
- if (list_empty(&soc_pcmcia_sockets))
- soc_pcmcia_cpufreq_unregister();
-
- mutex_unlock(&soc_pcmcia_sockets_lock);
-
- kfree(sinfo);
-
- return 0;
-}
-EXPORT_SYMBOL(soc_common_drv_pcmcia_remove);
+MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: Common SoC support");
+MODULE_LICENSE("Dual MPL/GPL");
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 290e143839ee..e40824ce6b0b 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -30,14 +30,12 @@ struct soc_pcmcia_socket {
/*
* Info from low level handler
*/
- struct device *dev;
unsigned int nr;
- unsigned int irq;
/*
* Core PCMCIA state
*/
- struct pcmcia_low_level *ops;
+ const struct pcmcia_low_level *ops;
unsigned int status;
socket_state_t cs_state;
@@ -135,10 +133,8 @@ extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_
extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
-extern struct list_head soc_pcmcia_sockets;
-
-extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo);
-extern int soc_common_drv_pcmcia_remove(struct device *dev);
+void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
+int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
#ifdef CONFIG_PCMCIA_DEBUG
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index ff9a3bb3c88d..78d5aab542f7 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -300,7 +300,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
if (!(s->state & SOCKET_PRESENT))
return -ENODEV;
- if (pccard_validate_cis(s, BIND_FN_ALL, &chains))
+ if (pccard_validate_cis(s, &chains))
return -EIO;
if (!chains)
return -ENODATA;
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 582413fcb62f..12c49ee135e1 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -55,21 +55,6 @@
#include <pcmcia/ss.h>
#include "tcic.h"
-#ifdef CONFIG_PCMCIA_DEBUG
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-static const char version[] =
-"tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
-
-#define debug(lvl, fmt, arg...) do { \
- if (pc_debug > (lvl)) \
- printk(KERN_DEBUG "tcic: " fmt , ## arg); \
-} while (0)
-#else
-#define debug(lvl, fmt, arg...) do { } while (0)
-#endif
-
MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
MODULE_LICENSE("Dual MPL/GPL");
@@ -574,7 +559,7 @@ static irqreturn_t tcic_interrupt(int irq, void *dev)
} else
active = 1;
- debug(2, "tcic_interrupt()\n");
+ pr_debug("tcic_interrupt()\n");
for (i = 0; i < sockets; i++) {
psock = socket_table[i].psock;
@@ -611,13 +596,13 @@ static irqreturn_t tcic_interrupt(int irq, void *dev)
}
active = 0;
- debug(2, "interrupt done\n");
+ pr_debug("interrupt done\n");
return IRQ_HANDLED;
} /* tcic_interrupt */
static void tcic_timer(u_long data)
{
- debug(2, "tcic_timer()\n");
+ pr_debug("tcic_timer()\n");
tcic_timer_pending = 0;
tcic_interrupt(0, NULL);
} /* tcic_timer */
@@ -644,7 +629,7 @@ static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
reg = tcic_getb(TCIC_PWR);
if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
*value |= SS_POWERON;
- debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
+ dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value);
return 0;
} /* tcic_get_status */
@@ -656,7 +641,7 @@ static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
u_char reg;
u_short scf1, scf2;
- debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+ dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
"io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
@@ -731,9 +716,9 @@ static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
u_int addr;
u_short base, len, ioctl;
- debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
- "%#x-%#x)\n", psock, io->map, io->flags,
- io->speed, io->start, io->stop);
+ dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, "
+ "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
+ (unsigned long long)io->start, (unsigned long long)io->stop);
if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
(io->stop < io->start)) return -EINVAL;
tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
@@ -768,7 +753,7 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
u_short addr, ctl;
u_long base, len, mmap;
- debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
+ dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, "
"%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
mem->speed, (unsigned long long)mem->res->start,
(unsigned long long)mem->res->end, mem->card_start);
diff --git a/drivers/pcmcia/topic.h b/drivers/pcmcia/topic.h
index edccfa5bb400..615a45a8fe86 100644
--- a/drivers/pcmcia/topic.h
+++ b/drivers/pcmcia/topic.h
@@ -114,22 +114,17 @@ static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff)
reg_zv |= TOPIC97_ZV_CONTROL_ENABLE;
config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
- reg = config_readb(socket, TOPIC97_MISC2);
- reg |= TOPIC97_MISC2_ZV_ENABLE;
- config_writeb(socket, TOPIC97_MISC2, reg);
-
- /* not sure this is needed, doc is unclear */
-#if 0
reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
reg |= TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL;
config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
-#endif
- }
- else {
+ } else {
reg_zv &= ~TOPIC97_ZV_CONTROL_ENABLE;
config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
- }
+ reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
+ reg &= ~(TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL);
+ config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
+ }
}
static int topic97_override(struct yenta_socket *socket)
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index abe0e44c6e9e..8be4cc447a17 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -1275,16 +1275,26 @@ static int yenta_dev_resume_noirq(struct device *dev)
if (socket->type && socket->type->restore_state)
socket->type->restore_state(socket);
- return pcmcia_socket_dev_resume(dev);
+ pcmcia_socket_dev_early_resume(dev);
+ return 0;
+}
+
+static int yenta_dev_resume(struct device *dev)
+{
+ pcmcia_socket_dev_late_resume(dev);
+ return 0;
}
static struct dev_pm_ops yenta_pm_ops = {
.suspend_noirq = yenta_dev_suspend_noirq,
.resume_noirq = yenta_dev_resume_noirq,
+ .resume = yenta_dev_resume,
.freeze_noirq = yenta_dev_suspend_noirq,
.thaw_noirq = yenta_dev_resume_noirq,
+ .thaw = yenta_dev_resume,
.poweroff_noirq = yenta_dev_suspend_noirq,
.restore_noirq = yenta_dev_resume_noirq,
+ .restore = yenta_dev_resume,
};
#define YENTA_PM_OPS (&yenta_pm_ops)
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 0a8f735f6c4a..ab64522aaa64 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -52,7 +52,7 @@
*/
#undef START_IN_KERNEL_MODE
-#define DRV_VER "0.5.17"
+#define DRV_VER "0.5.18"
/*
* According to the Atom N270 datasheet,
@@ -61,7 +61,7 @@
* measured by the on-die thermal monitor are within 0 <= Tj <= 90. So,
* assume 89°C is critical temperature.
*/
-#define ACERHDF_TEMP_CRIT 89
+#define ACERHDF_TEMP_CRIT 89000
#define ACERHDF_FAN_OFF 0
#define ACERHDF_FAN_AUTO 1
@@ -69,7 +69,7 @@
* No matter what value the user puts into the fanon variable, turn on the fan
* at 80 degree Celsius to prevent hardware damage
*/
-#define ACERHDF_MAX_FANON 80
+#define ACERHDF_MAX_FANON 80000
/*
* Maximum interval between two temperature checks is 15 seconds, as the die
@@ -85,8 +85,8 @@ static int kernelmode;
#endif
static unsigned int interval = 10;
-static unsigned int fanon = 63;
-static unsigned int fanoff = 58;
+static unsigned int fanon = 63000;
+static unsigned int fanoff = 58000;
static unsigned int verbose;
static unsigned int fanstate = ACERHDF_FAN_AUTO;
static char force_bios[16];
@@ -171,7 +171,7 @@ static int acerhdf_get_temp(int *temp)
if (ec_read(bios_cfg->tempreg, &read_temp))
return -EINVAL;
- *temp = read_temp;
+ *temp = read_temp * 1000;
return 0;
}
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 749e2102b2be..4226e5352738 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -350,13 +350,14 @@ static const struct rfkill_ops eeepc_rfkill_ops = {
.set_block = eeepc_rfkill_set,
};
-static void __init eeepc_enable_camera(void)
+static void __devinit eeepc_enable_camera(void)
{
/*
* If the following call to set_acpi() fails, it's because there's no
* camera so we can ignore the error.
*/
- set_acpi(CM_ASL_CAMERA, 1);
+ if (get_acpi(CM_ASL_CAMERA) == 0)
+ set_acpi(CM_ASL_CAMERA, 1);
}
/*
@@ -1189,7 +1190,7 @@ static int eeepc_input_init(struct device *dev)
return 0;
}
-static int eeepc_hotk_add(struct acpi_device *device)
+static int __devinit eeepc_hotk_add(struct acpi_device *device)
{
struct device *dev;
int result;
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index f35aee5c2149..bcd4ba8be7db 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -944,7 +944,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device);
struct input_dev *input = fujitsu_hotkey->input;
-#ifdef CONFIG_LEDS_CLASS
+#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
if (fujitsu_hotkey->logolamp_registered)
led_classdev_unregister(&logolamp_led);
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index d93108d148fc..a848c7e20aeb 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -1680,36 +1680,48 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
| (__bv1) << 8 | (__bv2) }
#define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2, \
- __eid1, __eid2, __ev1, __ev2) \
+ __eid, __ev1, __ev2) \
{ .vendor = (__v), \
.bios = TPID(__bid1, __bid2), \
- .ec = TPID(__eid1, __eid2), \
+ .ec = __eid, \
.quirks = (__ev1) << 24 | (__ev2) << 16 \
| (__bv1) << 8 | (__bv2) }
#define TPV_QI0(__id1, __id2, __bv1, __bv2) \
TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2)
+/* Outdated IBM BIOSes often lack the EC id string */
#define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \
- __bv1, __bv2, __id1, __id2, __ev1, __ev2)
+ __bv1, __bv2, TPID(__id1, __id2), \
+ __ev1, __ev2), \
+ TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \
+ __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \
+ __ev1, __ev2)
+/* Outdated IBM BIOSes often lack the EC id string */
#define TPV_QI2(__bid1, __bid2, __bv1, __bv2, \
__eid1, __eid2, __ev1, __ev2) \
TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \
- __bv1, __bv2, __eid1, __eid2, __ev1, __ev2)
+ __bv1, __bv2, TPID(__eid1, __eid2), \
+ __ev1, __ev2), \
+ TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \
+ __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \
+ __ev1, __ev2)
#define TPV_QL0(__id1, __id2, __bv1, __bv2) \
TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2)
#define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2, \
- __bv1, __bv2, __id1, __id2, __ev1, __ev2)
+ __bv1, __bv2, TPID(__id1, __id2), \
+ __ev1, __ev2)
#define TPV_QL2(__bid1, __bid2, __bv1, __bv2, \
__eid1, __eid2, __ev1, __ev2) \
TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2, \
- __bv1, __bv2, __eid1, __eid2, __ev1, __ev2)
+ __bv1, __bv2, TPID(__eid1, __eid2), \
+ __ev1, __ev2)
static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {
/* Numeric models ------------------ */
@@ -6313,7 +6325,7 @@ static int brightness_write(char *buf)
* Doing it this way makes the syscall restartable in case of EINTR
*/
rc = brightness_set(level);
- return (rc == -EINTR)? ERESTARTSYS : rc;
+ return (rc == -EINTR)? -ERESTARTSYS : rc;
}
static struct ibm_struct brightness_driver_data = {
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index 35a0b192d768..2d414e23d390 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -271,6 +271,7 @@ void pps_event(int source, struct pps_ktime *ts, int event, void *data)
{
struct pps_device *pps;
unsigned long flags;
+ int captured = 0;
if ((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0) {
printk(KERN_ERR "pps: unknown event (%x) for source %d\n",
@@ -293,7 +294,8 @@ void pps_event(int source, struct pps_ktime *ts, int event, void *data)
/* Check the event */
pps->current_mode = pps->params.mode;
- if (event & PPS_CAPTUREASSERT) {
+ if ((event & PPS_CAPTUREASSERT) &
+ (pps->params.mode & PPS_CAPTUREASSERT)) {
/* We have to add an offset? */
if (pps->params.mode & PPS_OFFSETASSERT)
pps_add_offset(ts, &pps->params.assert_off_tu);
@@ -303,8 +305,11 @@ void pps_event(int source, struct pps_ktime *ts, int event, void *data)
pps->assert_sequence++;
pr_debug("capture assert seq #%u for source %d\n",
pps->assert_sequence, source);
+
+ captured = ~0;
}
- if (event & PPS_CAPTURECLEAR) {
+ if ((event & PPS_CAPTURECLEAR) &
+ (pps->params.mode & PPS_CAPTURECLEAR)) {
/* We have to add an offset? */
if (pps->params.mode & PPS_OFFSETCLEAR)
pps_add_offset(ts, &pps->params.clear_off_tu);
@@ -314,12 +319,17 @@ void pps_event(int source, struct pps_ktime *ts, int event, void *data)
pps->clear_sequence++;
pr_debug("capture clear seq #%u for source %d\n",
pps->clear_sequence, source);
+
+ captured = ~0;
}
- pps->go = ~0;
- wake_up_interruptible(&pps->queue);
+ /* Wake up iif captured somthing */
+ if (captured) {
+ pps->go = ~0;
+ wake_up_interruptible(&pps->queue);
- kill_fasync(&pps->async_queue, SIGIO, POLL_IN);
+ kill_fasync(&pps->async_queue, SIGIO, POLL_IN);
+ }
spin_unlock_irqrestore(&pps->lock, flags);
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index fea17e7805e9..ca5183bdad85 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -71,9 +71,14 @@ static long pps_cdev_ioctl(struct file *file,
case PPS_GETPARAMS:
pr_debug("PPS_GETPARAMS: source %d\n", pps->id);
- /* Return current parameters */
- err = copy_to_user(uarg, &pps->params,
- sizeof(struct pps_kparams));
+ spin_lock_irq(&pps->lock);
+
+ /* Get the current parameters */
+ params = pps->params;
+
+ spin_unlock_irq(&pps->lock);
+
+ err = copy_to_user(uarg, &params, sizeof(struct pps_kparams));
if (err)
return -EFAULT;
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 744ea1d0b59b..efe568deda12 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1283,7 +1283,8 @@ static int _regulator_disable(struct regulator_dev *rdev)
return -EIO;
/* are we the last user and permitted to disable ? */
- if (rdev->use_count == 1 && !rdev->constraints->always_on) {
+ if (rdev->use_count == 1 &&
+ (rdev->constraints && !rdev->constraints->always_on)) {
/* we are last user */
if (_regulator_can_change_status(rdev) &&
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index f8b295700d7d..f9f516a3028a 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -196,11 +196,10 @@ static int regulator_fixed_voltage_remove(struct platform_device *pdev)
struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev);
regulator_unregister(drvdata->dev);
- kfree(drvdata->desc.name);
- kfree(drvdata);
-
if (gpio_is_valid(drvdata->gpio))
gpio_free(drvdata->gpio);
+ kfree(drvdata->desc.name);
+ kfree(drvdata);
return 0;
}
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index 1d8d9879d3a1..48857008758c 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -167,6 +167,8 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ isink->wm831x = wm831x;
+
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (res == NULL) {
dev_err(&pdev->dev, "No I/O resource\n");
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index bb61aede4801..902db56ce099 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -175,18 +175,18 @@ static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev)
struct wm831x *wm831x = ldo->wm831x;
int ctrl_reg = ldo->base + WM831X_LDO_CONTROL;
int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
- unsigned int ret;
+ int ret;
ret = wm831x_reg_read(wm831x, on_reg);
if (ret < 0)
- return 0;
+ return ret;
if (!(ret & WM831X_LDO1_ON_MODE))
return REGULATOR_MODE_NORMAL;
ret = wm831x_reg_read(wm831x, ctrl_reg);
if (ret < 0)
- return 0;
+ return ret;
if (ret & WM831X_LDO1_LP_MODE)
return REGULATOR_MODE_STANDBY;
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 7fe1fa26c52c..03ea530981d1 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -58,7 +58,16 @@ static irqreturn_t coh901331_interrupt(int irq, void *data)
clk_enable(rtap->clk);
/* Ack IRQ */
writel(1, rtap->virtbase + COH901331_IRQ_EVENT);
+ /*
+ * Disable the interrupt. This is necessary because
+ * the RTC lives on a lower-clocked line and will
+ * not release the IRQ line until after a few (slower)
+ * clock cycles. The interrupt will be re-enabled when
+ * a new alarm is set anyway.
+ */
+ writel(0, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
+
/* Set alarm flag */
rtc_update_irq(rtap->rtc, 1, RTC_AF);
@@ -128,6 +137,8 @@ static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled)
else
writel(0, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
+
+ return 0;
}
static struct rtc_class_ops coh901331_ops = {
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
index f4dd87e29075..4c5d5d0c4cfc 100644
--- a/drivers/rtc/rtc-pcf50633.c
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -70,7 +70,7 @@ static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50633_time *pcf)
rtc->tm_hour = bcd2bin(pcf->time[PCF50633_TI_HOUR]);
rtc->tm_wday = bcd2bin(pcf->time[PCF50633_TI_WKDAY]);
rtc->tm_mday = bcd2bin(pcf->time[PCF50633_TI_DAY]);
- rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]);
+ rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]) - 1;
rtc->tm_year = bcd2bin(pcf->time[PCF50633_TI_YEAR]) + 100;
}
@@ -81,7 +81,7 @@ static void rtc2pcf_time(struct pcf50633_time *pcf, struct rtc_time *rtc)
pcf->time[PCF50633_TI_HOUR] = bin2bcd(rtc->tm_hour);
pcf->time[PCF50633_TI_WKDAY] = bin2bcd(rtc->tm_wday);
pcf->time[PCF50633_TI_DAY] = bin2bcd(rtc->tm_mday);
- pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon);
+ pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon + 1);
pcf->time[PCF50633_TI_YEAR] = bin2bcd(rtc->tm_year % 100);
}
@@ -245,8 +245,9 @@ static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA,
PCF50633_TI_EXTENT, &pcf_tm.time[0]);
- if (!alarm_masked)
+ if (!alarm_masked || alrm->enabled)
pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
+ rtc->alarm_enabled = alrm->enabled;
return ret;
}
@@ -291,8 +292,9 @@ static int __devinit pcf50633_rtc_probe(struct platform_device *pdev)
&pcf50633_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
+ int ret = PTR_ERR(rtc->rtc_dev);
kfree(rtc);
- return PTR_ERR(rtc->rtc_dev);
+ return ret;
}
pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM,
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index ad164056feb6..423cd5a30b10 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -96,7 +96,7 @@ static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit)
static unsigned char v3020_mmio_read_bit(struct v3020 *chip)
{
- return readl(chip->ioaddress) & (1 << chip->leftshift);
+ return !!(readl(chip->ioaddress) & (1 << chip->leftshift));
}
static struct v3020_chip_ops v3020_mmio_ops = {
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index 2c839d0d21bd..fadddac1e5a4 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -209,19 +209,18 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq)
{
- unsigned long count;
+ u64 count;
if (!is_power_of_2(freq))
return -EINVAL;
count = RTC_FREQUENCY;
do_div(count, freq);
- periodic_count = count;
-
spin_lock_irq(&rtc_lock);
- rtc1_write(RTCL1LREG, count);
- rtc1_write(RTCL1HREG, count >> 16);
+ periodic_count = count;
+ rtc1_write(RTCL1LREG, periodic_count);
+ rtc1_write(RTCL1HREG, periodic_count >> 16);
spin_unlock_irq(&rtc_lock);
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 310c10795e9a..6583c1a8b070 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -195,7 +195,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
/* year, since the rtc epoch*/
buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
buf[CCR_WDAY] = tm->tm_wday & 0x07;
- buf[CCR_Y2K] = bin2bcd(tm->tm_year / 100);
+ buf[CCR_Y2K] = bin2bcd((tm->tm_year + 1900) / 100);
}
/* If writing alarm registers, set compare bits on registers 0-4 */
@@ -280,9 +280,9 @@ static int x1205_fix_osc(struct i2c_client *client)
int err;
struct rtc_time tm;
- tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+ memset(&tm, 0, sizeof(tm));
- err = x1205_set_datetime(client, &tm, 0, X1205_CCR_BASE, 0);
+ err = x1205_set_datetime(client, &tm, 1, X1205_CCR_BASE, 0);
if (err < 0)
dev_err(&client->dev, "unable to restart the oscillator\n");
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 53b8c255360a..aaccc8ecfa8f 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2533,6 +2533,7 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
{
struct dasd_ccw_req *cqr;
struct ccw1 *ccw;
+ unsigned long *idaw;
cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device);
@@ -2546,9 +2547,17 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
ccw = cqr->cpaddr;
ccw->cmd_code = CCW_CMD_RDC;
- ccw->cda = (__u32)(addr_t)rdc_buffer;
- ccw->count = rdc_buffer_size;
+ if (idal_is_needed(rdc_buffer, rdc_buffer_size)) {
+ idaw = (unsigned long *) (cqr->data);
+ ccw->cda = (__u32)(addr_t) idaw;
+ ccw->flags = CCW_FLAG_IDA;
+ idaw = idal_create_words(idaw, rdc_buffer, rdc_buffer_size);
+ } else {
+ ccw->cda = (__u32)(addr_t) rdc_buffer;
+ ccw->flags = 0;
+ }
+ ccw->count = rdc_buffer_size;
cqr->startdev = device;
cqr->memdev = device;
cqr->expires = 10*HZ;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 0be7c15f45c5..417b97cd3f94 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -3216,6 +3216,7 @@ int dasd_eckd_restore_device(struct dasd_device *device)
struct dasd_eckd_characteristics temp_rdc_data;
int is_known, rc;
struct dasd_uid temp_uid;
+ unsigned long flags;
private = (struct dasd_eckd_private *) device->private;
@@ -3228,7 +3229,8 @@ int dasd_eckd_restore_device(struct dasd_device *device)
rc = dasd_eckd_generate_uid(device, &private->uid);
dasd_get_uid(device->cdev, &temp_uid);
if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0)
- dev_err(&device->cdev->dev, "The UID of the DASD has changed\n");
+ dev_err(&device->cdev->dev, "The UID of the DASD has "
+ "changed\n");
if (rc)
goto out_err;
dasd_set_uid(device->cdev, &private->uid);
@@ -3256,9 +3258,9 @@ int dasd_eckd_restore_device(struct dasd_device *device)
"device: %s", rc, dev_name(&device->cdev->dev));
goto out_err;
}
- spin_lock(get_ccwdev_lock(device->cdev));
+ spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
memcpy(&private->rdc_data, &temp_rdc_data, sizeof(temp_rdc_data));
- spin_unlock(get_ccwdev_lock(device->cdev));
+ spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
/* add device to alias management */
dasd_alias_add_device(device);
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index 89ece1c235aa..66e21dd23154 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -357,6 +357,7 @@ static int mon_close(struct inode *inode, struct file *filp)
atomic_set(&monpriv->msglim_count, 0);
monpriv->write_index = 0;
monpriv->read_index = 0;
+ dev_set_drvdata(monreader_device, NULL);
for (i = 0; i < MON_MSGLIM; i++)
kfree(monpriv->msg_array[i]);
diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c
index daaec185ed36..b44462a6c6d3 100644
--- a/drivers/s390/char/sclp_async.c
+++ b/drivers/s390/char/sclp_async.c
@@ -26,7 +26,6 @@ static struct sclp_async_sccb *sccb;
static int sclp_async_send_wait(char *message);
static struct ctl_table_header *callhome_sysctl_header;
static DEFINE_SPINLOCK(sclp_async_lock);
-static char nodename[64];
#define SCLP_NORMAL_WRITE 0x00
struct async_evbuf {
@@ -52,9 +51,10 @@ static struct sclp_register sclp_async_register = {
static int call_home_on_panic(struct notifier_block *self,
unsigned long event, void *data)
{
- strncat(data, nodename, strlen(nodename));
- sclp_async_send_wait(data);
- return NOTIFY_DONE;
+ strncat(data, init_utsname()->nodename,
+ sizeof(init_utsname()->nodename));
+ sclp_async_send_wait(data);
+ return NOTIFY_DONE;
}
static struct notifier_block call_home_panic_nb = {
@@ -62,21 +62,20 @@ static struct notifier_block call_home_panic_nb = {
.priority = INT_MAX,
};
-static int proc_handler_callhome(ctl_table *ctl, int write, struct file *filp,
+static int proc_handler_callhome(struct ctl_table *ctl, int write,
void __user *buffer, size_t *count,
loff_t *ppos)
{
unsigned long val;
int len, rc;
- char buf[2];
+ char buf[3];
- if (!*count | (*ppos && !write)) {
+ if (!*count || (*ppos && !write)) {
*count = 0;
return 0;
}
if (!write) {
- len = sprintf(buf, "%d\n", callhome_enabled);
- buf[len] = '\0';
+ len = snprintf(buf, sizeof(buf), "%d\n", callhome_enabled);
rc = copy_to_user(buffer, buf, sizeof(buf));
if (rc != 0)
return -EFAULT;
@@ -100,7 +99,7 @@ static struct ctl_table callhome_table[] = {
{
.procname = "callhome",
.mode = 0644,
- .proc_handler = &proc_handler_callhome,
+ .proc_handler = proc_handler_callhome,
},
{ .ctl_name = 0 }
};
@@ -171,39 +170,29 @@ static int __init sclp_async_init(void)
rc = sclp_register(&sclp_async_register);
if (rc)
return rc;
- callhome_sysctl_header = register_sysctl_table(kern_dir_table);
- if (!callhome_sysctl_header) {
- rc = -ENOMEM;
- goto out_sclp;
- }
- if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK)) {
- rc = -EOPNOTSUPP;
+ rc = -EOPNOTSUPP;
+ if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK))
goto out_sclp;
- }
rc = -ENOMEM;
+ callhome_sysctl_header = register_sysctl_table(kern_dir_table);
+ if (!callhome_sysctl_header)
+ goto out_sclp;
request = kzalloc(sizeof(struct sclp_req), GFP_KERNEL);
- if (!request)
- goto out_sys;
sccb = (struct sclp_async_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
- if (!sccb)
+ if (!request || !sccb)
goto out_mem;
- rc = atomic_notifier_chain_register(&panic_notifier_list,
- &call_home_panic_nb);
- if (rc)
- goto out_mem;
-
- strncpy(nodename, init_utsname()->nodename, 64);
- return 0;
-
+ rc = atomic_notifier_chain_register(&panic_notifier_list,
+ &call_home_panic_nb);
+ if (!rc)
+ goto out;
out_mem:
kfree(request);
free_page((unsigned long) sccb);
-out_sys:
unregister_sysctl_table(callhome_sysctl_header);
out_sclp:
sclp_unregister(&sclp_async_register);
+out:
return rc;
-
}
module_init(sclp_async_init);
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c
index 84c191c1cd62..05909a7df8b3 100644
--- a/drivers/s390/char/sclp_quiesce.c
+++ b/drivers/s390/char/sclp_quiesce.c
@@ -20,9 +20,12 @@
#include "sclp.h"
+static void (*old_machine_restart)(char *);
+static void (*old_machine_halt)(void);
+static void (*old_machine_power_off)(void);
+
/* Shutdown handler. Signal completion of shutdown by loading special PSW. */
-static void
-do_machine_quiesce(void)
+static void do_machine_quiesce(void)
{
psw_t quiesce_psw;
@@ -33,23 +36,48 @@ do_machine_quiesce(void)
}
/* Handler for quiesce event. Start shutdown procedure. */
-static void
-sclp_quiesce_handler(struct evbuf_header *evbuf)
+static void sclp_quiesce_handler(struct evbuf_header *evbuf)
{
- _machine_restart = (void *) do_machine_quiesce;
- _machine_halt = do_machine_quiesce;
- _machine_power_off = do_machine_quiesce;
+ if (_machine_restart != (void *) do_machine_quiesce) {
+ old_machine_restart = _machine_restart;
+ old_machine_halt = _machine_halt;
+ old_machine_power_off = _machine_power_off;
+ _machine_restart = (void *) do_machine_quiesce;
+ _machine_halt = do_machine_quiesce;
+ _machine_power_off = do_machine_quiesce;
+ }
ctrl_alt_del();
}
+/* Undo machine restart/halt/power_off modification on resume */
+static void sclp_quiesce_pm_event(struct sclp_register *reg,
+ enum sclp_pm_event sclp_pm_event)
+{
+ switch (sclp_pm_event) {
+ case SCLP_PM_EVENT_RESTORE:
+ if (old_machine_restart) {
+ _machine_restart = old_machine_restart;
+ _machine_halt = old_machine_halt;
+ _machine_power_off = old_machine_power_off;
+ old_machine_restart = NULL;
+ old_machine_halt = NULL;
+ old_machine_power_off = NULL;
+ }
+ break;
+ case SCLP_PM_EVENT_FREEZE:
+ case SCLP_PM_EVENT_THAW:
+ break;
+ }
+}
+
static struct sclp_register sclp_quiesce_event = {
.receive_mask = EVTYP_SIGQUIESCE_MASK,
- .receiver_fn = sclp_quiesce_handler
+ .receiver_fn = sclp_quiesce_handler,
+ .pm_event_fn = sclp_quiesce_pm_event
};
/* Initialize quiesce driver. */
-static int __init
-sclp_quiesce_init(void)
+static int __init sclp_quiesce_init(void)
{
return sclp_register(&sclp_quiesce_event);
}
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 178724f2a4c3..b9d2a007e93b 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -705,21 +705,6 @@ out_driver:
}
__initcall(sclp_vt220_tty_init);
-#ifdef CONFIG_SCLP_VT220_CONSOLE
-
-static void
-sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count)
-{
- __sclp_vt220_write((const unsigned char *) buf, count, 1, 1, 0);
-}
-
-static struct tty_driver *
-sclp_vt220_con_device(struct console *c, int *index)
-{
- *index = 0;
- return sclp_vt220_driver;
-}
-
static void __sclp_vt220_flush_buffer(void)
{
unsigned long flags;
@@ -776,6 +761,21 @@ static void sclp_vt220_pm_event_fn(struct sclp_register *reg,
}
}
+#ifdef CONFIG_SCLP_VT220_CONSOLE
+
+static void
+sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count)
+{
+ __sclp_vt220_write((const unsigned char *) buf, count, 1, 1, 0);
+}
+
+static struct tty_driver *
+sclp_vt220_con_device(struct console *c, int *index)
+{
+ *index = 0;
+ return sclp_vt220_driver;
+}
+
static int
sclp_vt220_notify(struct notifier_block *self,
unsigned long event, void *data)
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index 64f57ef2763c..0c0705b91c28 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -162,9 +162,10 @@ tapeblock_requeue(struct work_struct *work) {
spin_lock_irq(&device->blk_data.request_queue_lock);
while (
!blk_queue_plugged(queue) &&
- (req = blk_fetch_request(queue)) &&
+ blk_peek_request(queue) &&
nr_queued < TAPEBLOCK_MIN_REQUEUE
) {
+ req = blk_fetch_request(queue);
if (rq_data_dir(req) == WRITE) {
DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
spin_unlock_irq(&device->blk_data.request_queue_lock);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 2ee093ec86e4..2490b741e16a 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1250,8 +1250,7 @@ static int io_subchannel_probe(struct subchannel *sch)
unsigned long flags;
struct ccw_dev_id dev_id;
- cdev = sch_get_cdev(sch);
- if (cdev) {
+ if (cio_is_console(sch->schid)) {
rc = sysfs_create_group(&sch->dev.kobj,
&io_subchannel_attr_group);
if (rc)
@@ -1260,13 +1259,13 @@ static int io_subchannel_probe(struct subchannel *sch)
"0.%x.%04x (rc=%d)\n",
sch->schid.ssid, sch->schid.sch_no, rc);
/*
- * This subchannel already has an associated ccw_device.
+ * The console subchannel already has an associated ccw_device.
* Throw the delayed uevent for the subchannel, register
- * the ccw_device and exit. This happens for all early
- * devices, e.g. the console.
+ * the ccw_device and exit.
*/
dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
+ cdev = sch_get_cdev(sch);
cdev->dev.groups = ccwdev_attr_groups;
device_initialize(&cdev->dev);
ccw_device_register(cdev);
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 102000d1af6f..3012355f8304 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -158,7 +158,12 @@ static int smsg_pm_restore_thaw(struct device *dev)
smsg_path->flags = 0;
rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ",
NULL, NULL, NULL);
- printk(KERN_ERR "iucv_path_connect returned with rc %i\n", rc);
+#ifdef CONFIG_PM_DEBUG
+ if (rc)
+ printk(KERN_ERR
+ "iucv_path_connect returned with rc %i\n", rc);
+#endif
+ cpcmd("SET SMSG IUCV", NULL, 0, NULL);
}
return 0;
}
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 0f79f3af4f54..2889e5f2dfd3 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -128,12 +128,13 @@ out_ccwdev:
static void __init zfcp_init_device_setup(char *devstr)
{
char *token;
- char *str;
+ char *str, *str_saved;
char busid[ZFCP_BUS_ID_SIZE];
u64 wwpn, lun;
/* duplicate devstr and keep the original for sysfs presentation*/
- str = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
+ str_saved = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
+ str = str_saved;
if (!str)
return;
@@ -152,12 +153,12 @@ static void __init zfcp_init_device_setup(char *devstr)
if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun))
goto err_out;
- kfree(str);
+ kfree(str_saved);
zfcp_init_device_configure(busid, wwpn, lun);
return;
- err_out:
- kfree(str);
+err_out:
+ kfree(str_saved);
pr_err("%s is not a valid SCSI device\n", devstr);
}
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 73d366ba31e5..f73e2180f333 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -858,10 +858,7 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
return zfcp_erp_open_ptp_port(act);
if (!port->d_id) {
- zfcp_port_get(port);
- if (!queue_work(adapter->work_queue,
- &port->gid_pn_work))
- zfcp_port_put(port);
+ zfcp_fc_trigger_did_lookup(port);
return ZFCP_ERP_EXIT;
}
return zfcp_erp_port_strategy_open_port(act);
@@ -869,12 +866,11 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
case ZFCP_ERP_STEP_PORT_OPENING:
/* D_ID might have changed during open */
if (p_status & ZFCP_STATUS_COMMON_OPEN) {
- if (port->d_id)
- return ZFCP_ERP_SUCCEEDED;
- else {
- act->step = ZFCP_ERP_STEP_PORT_CLOSING;
- return ZFCP_ERP_CONTINUES;
+ if (!port->d_id) {
+ zfcp_fc_trigger_did_lookup(port);
+ return ZFCP_ERP_EXIT;
}
+ return ZFCP_ERP_SUCCEEDED;
}
if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) {
port->d_id = 0;
@@ -889,19 +885,21 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
{
struct zfcp_port *port = erp_action->port;
+ int p_status = atomic_read(&port->status);
- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC)
+ if ((p_status & ZFCP_STATUS_COMMON_NOESC) &&
+ !(p_status & ZFCP_STATUS_COMMON_OPEN))
goto close_init_done;
switch (erp_action->step) {
case ZFCP_ERP_STEP_UNINITIALIZED:
zfcp_erp_port_strategy_clearstati(port);
- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)
+ if (p_status & ZFCP_STATUS_COMMON_OPEN)
return zfcp_erp_port_strategy_close(erp_action);
break;
case ZFCP_ERP_STEP_PORT_CLOSING:
- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)
+ if (p_status & ZFCP_STATUS_COMMON_OPEN)
return ZFCP_ERP_FAILED;
break;
}
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 629edec70405..b3f28deb4505 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -96,6 +96,7 @@ extern int zfcp_fc_scan_ports(struct zfcp_adapter *);
extern void _zfcp_fc_scan_ports_later(struct work_struct *);
extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
extern void zfcp_fc_port_did_lookup(struct work_struct *);
+extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *);
extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
extern void zfcp_fc_test_link(struct zfcp_port *);
extern void zfcp_fc_link_test_work(struct work_struct *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 722f22de8753..df23bcead23d 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -361,6 +361,17 @@ out:
}
/**
+ * zfcp_fc_trigger_did_lookup - trigger the d_id lookup using a GID_PN request
+ * @port: The zfcp_port to lookup the d_id for.
+ */
+void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
+{
+ zfcp_port_get(port);
+ if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
+ zfcp_port_put(port);
+}
+
+/**
* zfcp_fc_plogi_evaluate - evaluate PLOGI playload
* @port: zfcp_port structure
* @plogi: plogi payload
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 38a7e4a6b639..4e41baa0c141 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1079,7 +1079,7 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
/* common settings for ct/gs and els requests */
req->qtcb->bottom.support.service_class = FSF_CLASS_3;
req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
- zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10);
+ zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ);
return 0;
}
@@ -1475,9 +1475,16 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
if (req->qtcb->bottom.support.els1_length >=
FSF_PLOGI_MIN_LEN) {
- if (plogi->serv_param.wwpn != port->wwpn)
+ if (plogi->serv_param.wwpn != port->wwpn) {
port->d_id = 0;
- else {
+ dev_warn(&port->adapter->ccw_device->dev,
+ "A port opened with WWPN 0x%016Lx "
+ "returned data that identifies it as "
+ "WWPN 0x%016Lx\n",
+ (unsigned long long) port->wwpn,
+ (unsigned long long)
+ plogi->serv_param.wwpn);
+ } else {
port->wwnn = plogi->serv_param.wwnn;
zfcp_fc_plogi_evaluate(port, plogi);
}
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 079a8cf518a3..d31000886ca8 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -224,6 +224,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
zfcp_erp_wait(unit->port->adapter);
+ flush_work(&unit->scsi_work);
zfcp_unit_put(unit);
out:
mutex_unlock(&zfcp_data.config_mutex);
diff --git a/drivers/scsi/bfa/bfad_fwimg.c b/drivers/scsi/bfa/bfad_fwimg.c
index b2f6949bc8d3..bd34b0db2d6b 100644
--- a/drivers/scsi/bfa/bfad_fwimg.c
+++ b/drivers/scsi/bfa/bfad_fwimg.c
@@ -41,6 +41,8 @@ u32 *bfi_image_cb;
#define BFAD_FW_FILE_CT "ctfw.bin"
#define BFAD_FW_FILE_CB "cbfw.bin"
+MODULE_FIRMWARE(BFAD_FW_FILE_CT);
+MODULE_FIRMWARE(BFAD_FW_FILE_CB);
u32 *
bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 158c99243c08..55d012a9a668 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -948,7 +948,7 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
if (bfad_supported_fc4s & (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM))
/* For FCP type 0x08 */
fc_host_supported_fc4s(host)[2] = 1;
- if (bfad_supported_fc4s | BFA_PORT_ROLE_FCP_IPFC)
+ if (bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IPFC)
/* For LLC/SNAP type 0x05 */
fc_host_supported_fc4s(host)[3] = 0x20;
/* For fibre channel services type 0x20 */
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index b6af63ca980b..496764349c41 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -1918,6 +1918,10 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
}
size = size>>16;
size *= 4;
+ if (size > MAX_MESSAGE_SIZE) {
+ rcode = -EINVAL;
+ goto cleanup;
+ }
/* Copy in the user's I2O command */
if (copy_from_user (msg, user_msg, size)) {
rcode = -EFAULT;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 185e6bc4dd40..9e8fce0f0c1b 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2900,7 +2900,7 @@ static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr)
eindex = handle;
estr->event_source = 0;
- if (eindex >= MAX_EVENTS) {
+ if (eindex < 0 || eindex >= MAX_EVENTS) {
spin_unlock_irqrestore(&ha->smp_lock, flags);
return eindex;
}
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 5fd2da494d08..c968cc31cd86 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -164,8 +164,8 @@ void scsi_remove_host(struct Scsi_Host *shost)
return;
}
spin_unlock_irqrestore(shost->host_lock, flags);
- mutex_unlock(&shost->scan_mutex);
scsi_forget_host(shost);
+ mutex_unlock(&shost->scan_mutex);
scsi_proc_host_rm(shost);
spin_lock_irqsave(shost->host_lock, flags);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 5f045505a1f4..76d294fc7846 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4189,6 +4189,25 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
}
/**
+ * ipr_isr_eh - Interrupt service routine error handler
+ * @ioa_cfg: ioa config struct
+ * @msg: message to log
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_isr_eh(struct ipr_ioa_cfg *ioa_cfg, char *msg)
+{
+ ioa_cfg->errors_logged++;
+ dev_err(&ioa_cfg->pdev->dev, "%s\n", msg);
+
+ if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
+ ioa_cfg->sdt_state = GET_DUMP;
+
+ ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+}
+
+/**
* ipr_isr - Interrupt service routine
* @irq: irq number
* @devp: pointer to ioa config struct
@@ -4203,6 +4222,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
volatile u32 int_reg, int_mask_reg;
u32 ioasc;
u16 cmd_index;
+ int num_hrrq = 0;
struct ipr_cmnd *ipr_cmd;
irqreturn_t rc = IRQ_NONE;
@@ -4233,13 +4253,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
IPR_HRRQ_REQ_RESP_HANDLE_MASK) >> IPR_HRRQ_REQ_RESP_HANDLE_SHIFT;
if (unlikely(cmd_index >= IPR_NUM_CMD_BLKS)) {
- ioa_cfg->errors_logged++;
- dev_err(&ioa_cfg->pdev->dev, "Invalid response handle from IOA\n");
-
- if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
- ioa_cfg->sdt_state = GET_DUMP;
-
- ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+ ipr_isr_eh(ioa_cfg, "Invalid response handle from IOA");
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
return IRQ_HANDLED;
}
@@ -4266,8 +4280,18 @@ static irqreturn_t ipr_isr(int irq, void *devp)
if (ipr_cmd != NULL) {
/* Clear the PCI interrupt */
- writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg);
- int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+ do {
+ writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+ } while (int_reg & IPR_PCII_HRRQ_UPDATED &&
+ num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
+
+ if (int_reg & IPR_PCII_HRRQ_UPDATED) {
+ ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return IRQ_HANDLED;
+ }
+
} else
break;
}
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 163245a1c3e5..19bbcf39f0c9 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -144,6 +144,7 @@
#define IPR_IOA_MAX_SECTORS 32767
#define IPR_VSET_MAX_SECTORS 512
#define IPR_MAX_CDB_LEN 16
+#define IPR_MAX_HRRQ_RETRIES 3
#define IPR_DEFAULT_BUS_WIDTH 16
#define IPR_80MBs_SCSI_RATE ((80 * 10) / (IPR_DEFAULT_BUS_WIDTH / 8))
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index b3381959acce..33cf988c8c8a 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -960,7 +960,6 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
}
}
- res = 0;
}
return res;
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 67cde0138061..528733b4a392 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -54,15 +54,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"aha152x_cs.c 1.54 2000/06/12 21:27:25 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -103,7 +94,7 @@ static int aha152x_probe(struct pcmcia_device *link)
{
scsi_info_t *info;
- DEBUG(0, "aha152x_attach()\n");
+ dev_dbg(&link->dev, "aha152x_attach()\n");
/* Create new SCSI device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -115,7 +106,6 @@ static int aha152x_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
@@ -127,7 +117,7 @@ static int aha152x_probe(struct pcmcia_device *link)
static void aha152x_detach(struct pcmcia_device *link)
{
- DEBUG(0, "aha152x_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "aha152x_detach\n");
aha152x_release_cs(link);
@@ -137,9 +127,6 @@ static void aha152x_detach(struct pcmcia_device *link)
/*====================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int aha152x_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
@@ -164,19 +151,22 @@ static int aha152x_config_cs(struct pcmcia_device *link)
{
scsi_info_t *info = link->priv;
struct aha152x_setup s;
- int last_ret, last_fn;
+ int ret;
struct Scsi_Host *host;
- DEBUG(0, "aha152x_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "aha152x_config\n");
- last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
- if (last_ret) {
- cs_error(link, RequestIO, last_ret);
- goto failed;
- }
+ ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
+ if (ret)
+ goto failed;
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/* Set configuration options for the aha152x driver */
memset(&s, 0, sizeof(s));
@@ -194,7 +184,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
host = aha152x_probe_one(&s);
if (host == NULL) {
printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
- goto cs_failed;
+ goto failed;
}
sprintf(info->node.dev_name, "scsi%d", host->host_no);
@@ -203,8 +193,6 @@ static int aha152x_config_cs(struct pcmcia_device *link)
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
aha152x_release_cs(link);
return -ENODEV;
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index 06254f46a0dd..914040684079 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -59,16 +59,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
MODULE_LICENSE("Dual MPL/GPL");
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"fdomain_cs.c 1.47 2001/10/13 00:08:52 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
/*====================================================================*/
typedef struct scsi_info_t {
@@ -86,7 +76,7 @@ static int fdomain_probe(struct pcmcia_device *link)
{
scsi_info_t *info;
- DEBUG(0, "fdomain_attach()\n");
+ dev_dbg(&link->dev, "fdomain_attach()\n");
/* Create new SCSI device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -99,7 +89,6 @@ static int fdomain_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
@@ -111,7 +100,7 @@ static int fdomain_probe(struct pcmcia_device *link)
static void fdomain_detach(struct pcmcia_device *link)
{
- DEBUG(0, "fdomain_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "fdomain_detach\n");
fdomain_release(link);
@@ -120,9 +109,6 @@ static void fdomain_detach(struct pcmcia_device *link)
/*====================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int fdomain_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
@@ -137,20 +123,22 @@ static int fdomain_config_check(struct pcmcia_device *p_dev,
static int fdomain_config(struct pcmcia_device *link)
{
scsi_info_t *info = link->priv;
- int last_ret, last_fn;
+ int ret;
char str[22];
struct Scsi_Host *host;
- DEBUG(0, "fdomain_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "fdomain_config\n");
- last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
- if (last_ret) {
- cs_error(link, RequestIO, last_ret);
+ ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
+ if (ret)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/* A bad hack... */
release_region(link->io.BasePort1, link->io.NumPorts1);
@@ -162,11 +150,11 @@ static int fdomain_config(struct pcmcia_device *link)
host = __fdomain_16x0_detect(&fdomain_driver_template);
if (!host) {
printk(KERN_INFO "fdomain_cs: no SCSI devices found\n");
- goto cs_failed;
+ goto failed;
}
if (scsi_add_host(host, NULL))
- goto cs_failed;
+ goto failed;
scsi_scan_host(host);
sprintf(info->node.dev_name, "scsi%d", host->host_no);
@@ -175,8 +163,6 @@ static int fdomain_config(struct pcmcia_device *link)
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
fdomain_release(link);
return -ENODEV;
@@ -188,7 +174,7 @@ static void fdomain_release(struct pcmcia_device *link)
{
scsi_info_t *info = link->priv;
- DEBUG(0, "fdomain_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "fdomain_release\n");
scsi_remove_host(info->host);
pcmcia_disable_device(link);
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index e32c344d7ad8..c2341af587a3 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1564,12 +1564,10 @@ static int nsp_cs_probe(struct pcmcia_device *link)
link->io.IOAddrLines = 10; /* not used */
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
/* Interrupt handler */
link->irq.Handler = &nspintr;
- link->irq.Instance = info;
link->irq.Attributes |= IRQF_SHARED;
/* General socket configuration */
@@ -1684,10 +1682,10 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev,
if (cfg_mem->req.Size < 0x1000)
cfg_mem->req.Size = 0x1000;
cfg_mem->req.AccessSpeed = 0;
- if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
+ if (pcmcia_request_window(p_dev, &cfg_mem->req, &p_dev->win) != 0)
goto next_entry;
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
- if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+ if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
goto next_entry;
cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 20c3e5e6d88a..f85f094870b4 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -62,15 +62,6 @@
static char qlogic_name[] = "qlogic_cs";
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "qlogic_cs.c 1.79-ac 2002/10/26 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
static struct scsi_host_template qlogicfas_driver_template = {
.module = THIS_MODULE,
.name = qlogic_name,
@@ -159,7 +150,7 @@ static int qlogic_probe(struct pcmcia_device *link)
{
scsi_info_t *info;
- DEBUG(0, "qlogic_attach()\n");
+ dev_dbg(&link->dev, "qlogic_attach()\n");
/* Create new SCSI device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -171,7 +162,6 @@ static int qlogic_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
@@ -183,7 +173,7 @@ static int qlogic_probe(struct pcmcia_device *link)
static void qlogic_detach(struct pcmcia_device *link)
{
- DEBUG(0, "qlogic_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "qlogic_detach\n");
qlogic_release(link);
kfree(link->priv);
@@ -192,9 +182,6 @@ static void qlogic_detach(struct pcmcia_device *link)
/*====================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int qlogic_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
@@ -213,19 +200,22 @@ static int qlogic_config_check(struct pcmcia_device *p_dev,
static int qlogic_config(struct pcmcia_device * link)
{
scsi_info_t *info = link->priv;
- int last_ret, last_fn;
+ int ret;
struct Scsi_Host *host;
- DEBUG(0, "qlogic_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "qlogic_config\n");
- last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
- if (last_ret) {
- cs_error(link, RequestIO, last_ret);
+ ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
/* set ATAcmd */
@@ -244,7 +234,7 @@ static int qlogic_config(struct pcmcia_device * link)
if (!host) {
printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
- goto cs_failed;
+ goto failed;
}
sprintf(info->node.dev_name, "scsi%d", host->host_no);
@@ -253,12 +243,9 @@ static int qlogic_config(struct pcmcia_device * link)
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
- pcmcia_disable_device(link);
failed:
+ pcmcia_disable_device(link);
return -ENODEV;
-
} /* qlogic_config */
/*====================================================================*/
@@ -267,7 +254,7 @@ static void qlogic_release(struct pcmcia_device *link)
{
scsi_info_t *info = link->priv;
- DEBUG(0, "qlogic_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "qlogic_release\n");
scsi_remove_host(info->host);
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index b330c11a1752..e7564d8f0cbf 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -77,17 +77,6 @@
#include <pcmcia/ds.h>
#include <pcmcia/ciscode.h>
-/* ================================================================== */
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"sym53c500_cs.c 0.9c 2004/10/27 (Bob Tracy)";
-#else
-#define DEBUG(n, args...)
-#endif
/* ================================================================== */
@@ -525,7 +514,7 @@ SYM53C500_release(struct pcmcia_device *link)
struct scsi_info_t *info = link->priv;
struct Scsi_Host *shost = info->host;
- DEBUG(0, "SYM53C500_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "SYM53C500_release\n");
/*
* Do this before releasing/freeing resources.
@@ -697,9 +686,6 @@ static struct scsi_host_template sym53c500_driver_template = {
.shost_attrs = SYM53C500_shost_attrs
};
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int SYM53C500_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
@@ -719,24 +705,27 @@ static int
SYM53C500_config(struct pcmcia_device *link)
{
struct scsi_info_t *info = link->priv;
- int last_ret, last_fn;
+ int ret;
int irq_level, port_base;
struct Scsi_Host *host;
struct scsi_host_template *tpnt = &sym53c500_driver_template;
struct sym53c500_data *data;
- DEBUG(0, "SYM53C500_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "SYM53C500_config\n");
info->manf_id = link->manf_id;
- last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
- if (last_ret) {
- cs_error(link, RequestIO, last_ret);
+ ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*
* That's the trouble with copying liberally from another driver.
@@ -824,8 +813,6 @@ err_release:
printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
return -ENODEV;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
SYM53C500_release(link);
return -ENODEV;
@@ -855,7 +842,7 @@ static int sym53c500_resume(struct pcmcia_device *link)
static void
SYM53C500_detach(struct pcmcia_device *link)
{
- DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "SYM53C500_detach\n");
SYM53C500_release(link);
@@ -868,7 +855,7 @@ SYM53C500_probe(struct pcmcia_device *link)
{
struct scsi_info_t *info;
- DEBUG(0, "SYM53C500_attach()\n");
+ dev_dbg(&link->dev, "SYM53C500_attach()\n");
/* Create new SCSI device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -880,7 +867,6 @@ SYM53C500_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index f7c70e2a8224..0a97bc9074bb 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -1071,7 +1071,7 @@ static struct pmcraid_cmd *pmcraid_init_hcam
ioarcb->data_transfer_length = cpu_to_le32(rcb_size);
- ioadl[0].flags |= cpu_to_le32(IOADL_FLAGS_READ_LAST);
+ ioadl[0].flags |= IOADL_FLAGS_READ_LAST;
ioadl[0].data_len = cpu_to_le32(rcb_size);
ioadl[0].address = cpu_to_le32(dma);
@@ -2251,7 +2251,7 @@ static void pmcraid_request_sense(struct pmcraid_cmd *cmd)
ioadl->address = cpu_to_le64(cmd->sense_buffer_dma);
ioadl->data_len = cpu_to_le32(SCSI_SENSE_BUFFERSIZE);
- ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+ ioadl->flags = IOADL_FLAGS_LAST_DESC;
/* request sense might be called as part of error response processing
* which runs in tasklets context. It is possible that mid-layer might
@@ -3017,7 +3017,7 @@ static int pmcraid_build_ioadl(
ioadl[i].flags = 0;
}
/* setup last descriptor */
- ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+ ioadl[i - 1].flags = IOADL_FLAGS_LAST_DESC;
return 0;
}
@@ -3387,7 +3387,7 @@ static int pmcraid_build_passthrough_ioadls(
}
/* setup the last descriptor */
- ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+ ioadl[i - 1].flags = IOADL_FLAGS_LAST_DESC;
return 0;
}
@@ -5314,7 +5314,7 @@ static void pmcraid_querycfg(struct pmcraid_cmd *cmd)
cpu_to_le32(sizeof(struct pmcraid_config_table));
ioadl = &(ioarcb->add_data.u.ioadl[0]);
- ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+ ioadl->flags = IOADL_FLAGS_LAST_DESC;
ioadl->address = cpu_to_le64(pinstance->cfg_table_bus_addr);
ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_config_table));
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index c44783801402..47291bcff0d5 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -317,6 +317,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
out_device_destroy:
scsi_device_set_state(sdev, SDEV_DEL);
transport_destroy_device(&sdev->sdev_gendev);
+ put_device(&sdev->sdev_dev);
put_device(&sdev->sdev_gendev);
out:
if (display_failure_msg)
@@ -951,15 +952,6 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
return SCSI_SCAN_LUN_PRESENT;
}
-static inline void scsi_destroy_sdev(struct scsi_device *sdev)
-{
- scsi_device_set_state(sdev, SDEV_DEL);
- if (sdev->host->hostt->slave_destroy)
- sdev->host->hostt->slave_destroy(sdev);
- transport_destroy_device(&sdev->sdev_gendev);
- put_device(&sdev->sdev_gendev);
-}
-
#ifdef CONFIG_SCSI_LOGGING
/**
* scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace
@@ -1137,7 +1129,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
}
}
} else
- scsi_destroy_sdev(sdev);
+ __scsi_remove_device(sdev);
out:
return res;
}
@@ -1498,7 +1490,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
/*
* the sdev we used didn't appear in the report luns scan
*/
- scsi_destroy_sdev(sdev);
+ __scsi_remove_device(sdev);
return ret;
}
@@ -1708,7 +1700,7 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
shost_for_each_device(sdev, shost) {
if (!scsi_host_scan_allowed(shost) ||
scsi_sysfs_add_sdev(sdev) != 0)
- scsi_destroy_sdev(sdev);
+ __scsi_remove_device(sdev);
}
}
@@ -1941,7 +1933,7 @@ void scsi_free_host_dev(struct scsi_device *sdev)
{
BUG_ON(sdev->id != sdev->host->this_id);
- scsi_destroy_sdev(sdev);
+ __scsi_remove_device(sdev);
}
EXPORT_SYMBOL(scsi_free_host_dev);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index fde54537d715..392d8db33905 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -854,85 +854,73 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
transport_configure_device(&starget->dev);
error = device_add(&sdev->sdev_gendev);
if (error) {
- put_device(sdev->sdev_gendev.parent);
printk(KERN_INFO "error 1\n");
- return error;
+ goto out_remove;
}
error = device_add(&sdev->sdev_dev);
if (error) {
printk(KERN_INFO "error 2\n");
- goto clean_device;
+ device_del(&sdev->sdev_gendev);
+ goto out_remove;
}
-
- /* take a reference for the sdev_dev; this is
- * released by the sdev_class .release */
- get_device(&sdev->sdev_gendev);
+ transport_add_device(&sdev->sdev_gendev);
+ sdev->is_visible = 1;
/* create queue files, which may be writable, depending on the host */
if (sdev->host->hostt->change_queue_depth)
error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw);
else
error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
- if (error) {
- __scsi_remove_device(sdev);
- goto out;
- }
+ if (error)
+ goto out_remove;
+
if (sdev->host->hostt->change_queue_type)
error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw);
else
error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type);
- if (error) {
- __scsi_remove_device(sdev);
- goto out;
- }
+ if (error)
+ goto out_remove;
error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL);
if (error)
+ /* we're treating error on bsg register as non-fatal,
+ * so pretend nothing went wrong */
sdev_printk(KERN_INFO, sdev,
"Failed to register bsg queue, errno=%d\n", error);
- /* we're treating error on bsg register as non-fatal, so pretend
- * nothing went wrong */
- error = 0;
-
/* add additional host specific attributes */
if (sdev->host->hostt->sdev_attrs) {
for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
error = device_create_file(&sdev->sdev_gendev,
sdev->host->hostt->sdev_attrs[i]);
- if (error) {
- __scsi_remove_device(sdev);
- goto out;
- }
+ if (error)
+ goto out_remove;
}
}
- transport_add_device(&sdev->sdev_gendev);
- out:
- return error;
-
- clean_device:
- scsi_device_set_state(sdev, SDEV_CANCEL);
-
- device_del(&sdev->sdev_gendev);
- transport_destroy_device(&sdev->sdev_gendev);
- put_device(&sdev->sdev_gendev);
+ return 0;
+ out_remove:
+ __scsi_remove_device(sdev);
return error;
+
}
void __scsi_remove_device(struct scsi_device *sdev)
{
struct device *dev = &sdev->sdev_gendev;
- if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
- return;
+ if (sdev->is_visible) {
+ if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
+ return;
- bsg_unregister_queue(sdev->request_queue);
- device_unregister(&sdev->sdev_dev);
- transport_remove_device(dev);
- device_del(dev);
+ bsg_unregister_queue(sdev->request_queue);
+ device_unregister(&sdev->sdev_dev);
+ transport_remove_device(dev);
+ device_del(dev);
+ } else
+ put_device(&sdev->sdev_dev);
scsi_device_set_state(sdev, SDEV_DEL);
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
@@ -1065,7 +1053,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
device_initialize(&sdev->sdev_dev);
- sdev->sdev_dev.parent = &sdev->sdev_gendev;
+ sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev);
sdev->sdev_dev.class = &sdev_class;
dev_set_name(&sdev->sdev_dev, "%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index a67fed10598a..c6f70dae9b2e 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3656,6 +3656,7 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
fail_host_msg:
/* return the errno failure code as the only status */
BUG_ON(job->reply_len < sizeof(uint32_t));
+ job->reply->reply_payload_rcv_len = 0;
job->reply->result = ret;
job->reply_len = sizeof(uint32_t);
fc_bsg_jobdone(job);
@@ -3741,6 +3742,7 @@ check_bidi:
fail_rport_msg:
/* return the errno failure code as the only status */
BUG_ON(job->reply_len < sizeof(uint32_t));
+ job->reply->reply_payload_rcv_len = 0;
job->reply->result = ret;
job->reply_len = sizeof(uint32_t);
fc_bsg_jobdone(job);
@@ -3797,6 +3799,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
/* check if we have the msgcode value at least */
if (job->request_len < sizeof(uint32_t)) {
BUG_ON(job->reply_len < sizeof(uint32_t));
+ job->reply->reply_payload_rcv_len = 0;
job->reply->result = -ENOMSG;
job->reply_len = sizeof(uint32_t);
fc_bsg_jobdone(job);
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 88da97745710..84be62149c6c 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -418,7 +418,7 @@ error:
__func__, virt, phys, be32_to_cpu(sdt->ref_tag),
be16_to_cpu(sdt->app_tag));
- return -EIO;
+ return -EILSEQ;
}
/*
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index b1ae774016f1..737b4c960971 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1089,7 +1089,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
return;
- DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ",
+ DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ",
serial_index(&up->port), up->port.iobase, up->port.membase);
/*
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index e7108e75653d..b28af13c45a1 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1561,11 +1561,16 @@ enum pci_board_num_t {
pbn_exar_XR17C152,
pbn_exar_XR17C154,
pbn_exar_XR17C158,
+ pbn_exar_ibm_saturn,
pbn_pasemi_1682M,
pbn_ni8430_2,
pbn_ni8430_4,
pbn_ni8430_8,
pbn_ni8430_16,
+ pbn_ADDIDATA_PCIe_1_3906250,
+ pbn_ADDIDATA_PCIe_2_3906250,
+ pbn_ADDIDATA_PCIe_4_3906250,
+ pbn_ADDIDATA_PCIe_8_3906250,
};
/*
@@ -2146,6 +2151,13 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 921600,
.uart_offset = 0x200,
},
+ [pbn_exar_ibm_saturn] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 921600,
+ .uart_offset = 0x200,
+ },
+
/*
* PA Semi PWRficient PA6T-1682M on-chip UART
*/
@@ -2185,6 +2197,37 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.uart_offset = 0x10,
.first_offset = 0x800,
},
+ /*
+ * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com>
+ */
+ [pbn_ADDIDATA_PCIe_1_3906250] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 3906250,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_ADDIDATA_PCIe_2_3906250] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 3906250,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_ADDIDATA_PCIe_4_3906250] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 3906250,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
+ [pbn_ADDIDATA_PCIe_8_3906250] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 3906250,
+ .uart_offset = 0x200,
+ .first_offset = 0x1000,
+ },
};
static const struct pci_device_id softmodem_blacklist[] = {
@@ -2340,7 +2383,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
break;
#ifdef SERIAL_DEBUG_PCI
- printk(KERN_DEBUG "Setup PCI port: port %x, irq %d, type %d\n",
+ printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n",
serial_port.iobase, serial_port.irq, serial_port.iotype);
#endif
@@ -2649,6 +2692,9 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0,
pbn_b0_8_1843200_200 },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+ PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT,
+ 0, 0, pbn_exar_ibm_saturn },
{ PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
@@ -3093,6 +3139,12 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_bt_2_115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_115200 },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_bt_4_460800 },
@@ -3556,6 +3608,38 @@ static struct pci_device_id serial_pci_tbl[] = {
0,
pbn_b0_8_115200 },
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCIe7500,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_ADDIDATA_PCIe_4_3906250 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCIe7420,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_ADDIDATA_PCIe_2_3906250 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCIe7300,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_ADDIDATA_PCIe_1_3906250 },
+
+ { PCI_VENDOR_ID_ADDIDATA,
+ PCI_DEVICE_ID_ADDIDATA_APCIe7800,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0,
+ 0,
+ pbn_ADDIDATA_PCIe_8_3906250 },
+
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
PCI_VENDOR_ID_IBM, 0x0299,
0, 0, pbn_b0_bt_2_115200 },
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 3551c5cb7094..9d948bccafaf 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -1531,7 +1531,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
void *data;
int ret;
- BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE));
+ BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
port = &atmel_ports[pdev->id];
port->backup_imr = 0;
diff --git a/drivers/serial/bcm63xx_uart.c b/drivers/serial/bcm63xx_uart.c
index beddaa6e9069..37ad0c449937 100644
--- a/drivers/serial/bcm63xx_uart.c
+++ b/drivers/serial/bcm63xx_uart.c
@@ -242,7 +242,7 @@ static void bcm_uart_do_rx(struct uart_port *port)
* higher than fifo size anyway since we're much faster than
* serial port */
max_count = 32;
- tty = port->info->port.tty;
+ tty = port->state->port.tty;
do {
unsigned int iestat, c, cstat;
char flag;
@@ -318,7 +318,7 @@ static void bcm_uart_do_tx(struct uart_port *port)
return;
}
- xmit = &port->info->xmit;
+ xmit = &port->state->xmit;
if (uart_circ_empty(xmit))
goto txq_empty;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index d7bcd074d383..7ce9e9f567a3 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -705,7 +705,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
return -EINVAL;
if ((ser->irq != port->irq) ||
- (ser->io_type != SERIAL_IO_MEM) ||
+ (ser->io_type != UPIO_MEM) ||
(ser->baud_base != port->uartclk) ||
(ser->iomem_base != (void *)port->mapbase) ||
(ser->hub6 != 0))
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index 02406ba6da1c..cdf172eda2e3 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -161,6 +161,7 @@ static int of_platform_serial_remove(struct of_device *ofdev)
static struct of_device_id __devinitdata of_platform_serial_table[] = {
{ .type = "serial", .compatible = "ns8250", .data = (void *)PORT_8250, },
{ .type = "serial", .compatible = "ns16450", .data = (void *)PORT_16450, },
+ { .type = "serial", .compatible = "ns16550a", .data = (void *)PORT_16550A, },
{ .type = "serial", .compatible = "ns16550", .data = (void *)PORT_16550, },
{ .type = "serial", .compatible = "ns16750", .data = (void *)PORT_16750, },
{ .type = "serial", .compatible = "ns16850", .data = (void *)PORT_16850, },
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index ff4617e21426..fc413f0f8dd2 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -54,14 +54,6 @@
#include "8250.h"
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -121,24 +113,20 @@ static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_
static int quirk_post_ibm(struct pcmcia_device *link)
{
conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
- int last_ret, last_fn;
+ int ret;
+
+ ret = pcmcia_access_configuration_register(link, &reg);
+ if (ret)
+ goto failed;
- last_ret = pcmcia_access_configuration_register(link, &reg);
- if (last_ret) {
- last_fn = AccessConfigurationRegister;
- goto cs_failed;
- }
reg.Action = CS_WRITE;
reg.Value = reg.Value | 1;
- last_ret = pcmcia_access_configuration_register(link, &reg);
- if (last_ret) {
- last_fn = AccessConfigurationRegister;
- goto cs_failed;
- }
+ ret = pcmcia_access_configuration_register(link, &reg);
+ if (ret)
+ goto failed;
return 0;
- cs_failed:
- cs_error(link, last_fn, last_ret);
+ failed:
return -ENODEV;
}
@@ -283,7 +271,7 @@ static void serial_remove(struct pcmcia_device *link)
struct serial_info *info = link->priv;
int i;
- DEBUG(0, "serial_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "serial_release\n");
/*
* Recheck to see if the device is still configured.
@@ -334,7 +322,7 @@ static int serial_probe(struct pcmcia_device *link)
{
struct serial_info *info;
- DEBUG(0, "serial_attach()\n");
+ dev_dbg(&link->dev, "serial_attach()\n");
/* Create new serial device */
info = kzalloc(sizeof (*info), GFP_KERNEL);
@@ -346,7 +334,6 @@ static int serial_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
if (do_sound) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -370,7 +357,7 @@ static void serial_detach(struct pcmcia_device *link)
{
struct serial_info *info = link->priv;
- DEBUG(0, "serial_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "serial_detach\n");
/*
* Ensure any outstanding scheduled tasks are completed.
@@ -399,7 +386,7 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
port.irq = irq;
port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
port.uartclk = 1843200;
- port.dev = &handle_to_dev(handle);
+ port.dev = &handle->dev;
if (buggy_uart)
port.flags |= UPF_BUGGY_UART;
@@ -426,21 +413,6 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
/*====================================================================*/
-static int
-first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
-{
- int i;
- i = pcmcia_get_first_tuple(handle, tuple);
- if (i != 0)
- return i;
- i = pcmcia_get_tuple_data(handle, tuple);
- if (i != 0)
- return i;
- return pcmcia_parse_tuple(tuple, parse);
-}
-
-/*====================================================================*/
-
static int simple_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
@@ -522,15 +494,13 @@ static int simple_config(struct pcmcia_device *link)
printk(KERN_NOTICE
"serial_cs: no usable port range found, giving up\n");
- cs_error(link, RequestIO, i);
return -1;
found_port:
i = pcmcia_request_irq(link, &link->irq);
- if (i != 0) {
- cs_error(link, RequestIRQ, i);
+ if (i != 0)
link->irq.AssignedIRQ = 0;
- }
+
if (info->multi && (info->manfid == MANFID_3COM))
link->conf.ConfigIndex &= ~(0x08);
@@ -541,10 +511,8 @@ found_port:
info->quirk->config(link);
i = pcmcia_request_configuration(link, &link->conf);
- if (i != 0) {
- cs_error(link, RequestConfiguration, i);
+ if (i != 0)
return -1;
- }
return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
}
@@ -613,7 +581,6 @@ static int multi_config(struct pcmcia_device *link)
/* FIXME: comment does not fit, error handling does not fit */
printk(KERN_NOTICE
"serial_cs: no usable port range found, giving up\n");
- cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
@@ -624,10 +591,8 @@ static int multi_config(struct pcmcia_device *link)
info->quirk->config(link);
i = pcmcia_request_configuration(link, &link->conf);
- if (i != 0) {
- cs_error(link, RequestConfiguration, i);
+ if (i != 0)
return -ENODEV;
- }
/* The Oxford Semiconductor OXCF950 cards are in fact single-port:
* 8 registers are for the UART, the others are extra registers.
@@ -665,6 +630,25 @@ static int multi_config(struct pcmcia_device *link)
return 0;
}
+static int serial_check_for_multi(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cf,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ struct serial_info *info = p_dev->priv;
+
+ if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
+ info->multi = cf->io.win[0].len >> 3;
+
+ if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
+ (cf->io.win[1].len == 8))
+ info->multi = 2;
+
+ return 0; /* break */
+}
+
+
/*======================================================================
serial_config() is scheduled to run after a CARD_INSERTION event
@@ -676,46 +660,14 @@ static int multi_config(struct pcmcia_device *link)
static int serial_config(struct pcmcia_device * link)
{
struct serial_info *info = link->priv;
- struct serial_cfg_mem *cfg_mem;
- tuple_t *tuple;
- u_char *buf;
- cisparse_t *parse;
- cistpl_cftable_entry_t *cf;
- int i, last_ret, last_fn;
-
- DEBUG(0, "serial_config(0x%p)\n", link);
-
- cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- goto failed;
+ int i;
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- cf = &parse->cftable_entry;
- buf = cfg_mem->buf;
-
- tuple->TupleData = (cisdata_t *) buf;
- tuple->TupleOffset = 0;
- tuple->TupleDataMax = 255;
- tuple->Attributes = 0;
-
- /* Get configuration register information */
- tuple->DesiredTuple = CISTPL_CONFIG;
- last_ret = first_tuple(link, tuple, parse);
- if (last_ret != 0) {
- last_fn = ParseTuple;
- goto cs_failed;
- }
- link->conf.ConfigBase = parse->config.base;
- link->conf.Present = parse->config.rmask[0];
+ dev_dbg(&link->dev, "serial_config\n");
/* Is this a compliant multifunction card? */
- tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
- tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
- info->multi = (first_tuple(link, tuple, parse) == 0);
+ info->multi = (link->socket->functions > 1);
/* Is this a multiport card? */
- tuple->DesiredTuple = CISTPL_MANFID;
info->manfid = link->manf_id;
info->prodid = link->card_id;
@@ -730,20 +682,11 @@ static int serial_config(struct pcmcia_device * link)
/* Another check for dual-serial cards: look for either serial or
multifunction cards that ask for appropriate IO port ranges */
- tuple->DesiredTuple = CISTPL_FUNCID;
if ((info->multi == 0) &&
(link->has_func_id) &&
((link->func_id == CISTPL_FUNCID_MULTI) ||
- (link->func_id == CISTPL_FUNCID_SERIAL))) {
- tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
- if (first_tuple(link, tuple, parse) == 0) {
- if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
- info->multi = cf->io.win[0].len >> 3;
- if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
- (cf->io.win[1].len == 8))
- info->multi = 2;
- }
- }
+ (link->func_id == CISTPL_FUNCID_SERIAL)))
+ pcmcia_loop_config(link, serial_check_for_multi, info);
/*
* Apply any multi-port quirk.
@@ -768,14 +711,10 @@ static int serial_config(struct pcmcia_device * link)
goto failed;
link->dev_node = &info->node[0];
- kfree(cfg_mem);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
serial_remove(link);
- kfree(cfg_mem);
return -ENODEV;
}
@@ -879,10 +818,10 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
- PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
- PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
- PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
+ PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
+ PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
+ PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
+ PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 85119fb7cb50..6498bd1fb6dd 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -1143,7 +1143,7 @@ static void serial_console_write(struct console *co, const char *s,
while ((sci_in(port, SCxSR) & bits) != bits)
cpu_relax();
- if (sci_port->disable);
+ if (sci_port->disable)
sci_port->disable(port);
}
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index a2d4a19550ab..ed7d958b0a01 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -53,20 +53,21 @@ void sunserial_unregister_minors(struct uart_driver *drv, int count)
EXPORT_SYMBOL(sunserial_unregister_minors);
int sunserial_console_match(struct console *con, struct device_node *dp,
- struct uart_driver *drv, int line)
+ struct uart_driver *drv, int line, bool ignore_line)
{
- int off;
-
if (!con || of_console_device != dp)
return 0;
- off = 0;
- if (of_console_options &&
- *of_console_options == 'b')
- off = 1;
+ if (!ignore_line) {
+ int off = 0;
- if ((line & 1) != off)
- return 0;
+ if (of_console_options &&
+ *of_console_options == 'b')
+ off = 1;
+
+ if ((line & 1) != off)
+ return 0;
+ }
con->index = line;
drv->cons = con;
@@ -76,23 +77,24 @@ int sunserial_console_match(struct console *con, struct device_node *dp,
}
EXPORT_SYMBOL(sunserial_console_match);
-void
-sunserial_console_termios(struct console *con)
+void sunserial_console_termios(struct console *con, struct device_node *uart_dp)
{
- struct device_node *dp;
- const char *od, *mode, *s;
+ const char *mode, *s;
char mode_prop[] = "ttyX-mode";
int baud, bits, stop, cflag;
char parity;
- dp = of_find_node_by_path("/options");
- od = of_get_property(dp, "output-device", NULL);
- if (!strcmp(od, "rsc")) {
- mode = of_get_property(of_console_device,
+ if (!strcmp(uart_dp->name, "rsc") ||
+ !strcmp(uart_dp->name, "rsc-console") ||
+ !strcmp(uart_dp->name, "rsc-control")) {
+ mode = of_get_property(uart_dp,
"ssp-console-modes", NULL);
if (!mode)
mode = "115200,8,n,1,-";
+ } else if (!strcmp(uart_dp->name, "lom-console")) {
+ mode = "9600,8,n,1,-";
} else {
+ struct device_node *dp;
char c;
c = 'a';
@@ -101,6 +103,7 @@ sunserial_console_termios(struct console *con)
mode_prop[3] = c;
+ dp = of_find_node_by_path("/options");
mode = of_get_property(dp, mode_prop, NULL);
if (!mode)
mode = "9600,8,n,1,-";
diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h
index 042668aa602e..db2057936c31 100644
--- a/drivers/serial/suncore.h
+++ b/drivers/serial/suncore.h
@@ -26,7 +26,8 @@ extern int sunserial_register_minors(struct uart_driver *, int);
extern void sunserial_unregister_minors(struct uart_driver *, int);
extern int sunserial_console_match(struct console *, struct device_node *,
- struct uart_driver *, int);
-extern void sunserial_console_termios(struct console *);
+ struct uart_driver *, int, bool);
+extern void sunserial_console_termios(struct console *,
+ struct device_node *);
#endif /* !(_SERIAL_SUN_H) */
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index d548652dee50..d14cca7fb88d 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -566,7 +566,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
goto out_free_con_read_page;
sunserial_console_match(&sunhv_console, op->node,
- &sunhv_reg, port->line);
+ &sunhv_reg, port->line, false);
err = uart_add_one_port(&sunhv_reg, port);
if (err)
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index d1ad34128635..d514e28d0755 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options)
printk("Console: ttyS%d (SAB82532)\n",
(sunsab_reg.minor - 64) + con->index);
- sunserial_console_termios(con);
+ sunserial_console_termios(con, to_of_device(up->port.dev)->node);
switch (con->cflag & CBAUD) {
case B150: baud = 150; break;
@@ -1027,10 +1027,12 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
goto out1;
sunserial_console_match(SUNSAB_CONSOLE(), op->node,
- &sunsab_reg, up[0].port.line);
+ &sunsab_reg, up[0].port.line,
+ false);
sunserial_console_match(SUNSAB_CONSOLE(), op->node,
- &sunsab_reg, up[1].port.line);
+ &sunsab_reg, up[1].port.line,
+ false);
err = uart_add_one_port(&sunsab_reg, &up[0].port);
if (err)
@@ -1116,7 +1118,6 @@ static int __init sunsab_init(void)
if (!sunsab_ports)
return -ENOMEM;
- sunsab_reg.cons = SUNSAB_CONSOLE();
err = sunserial_register_minors(&sunsab_reg, num_channels);
if (err) {
kfree(sunsab_ports);
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 68d262b15749..170d3d68c8f0 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1329,11 +1329,9 @@ static void sunsu_console_write(struct console *co, const char *s,
*/
static int __init sunsu_console_setup(struct console *co, char *options)
{
+ static struct ktermios dummy;
+ struct ktermios termios;
struct uart_port *port;
- int baud = 9600;
- int bits = 8;
- int parity = 'n';
- int flow = 'n';
printk("Console: ttyS%d (SU)\n",
(sunsu_reg.minor - 64) + co->index);
@@ -1352,10 +1350,15 @@ static int __init sunsu_console_setup(struct console *co, char *options)
*/
spin_lock_init(&port->lock);
- if (options)
- uart_parse_options(options, &baud, &parity, &bits, &flow);
+ /* Get firmware console settings. */
+ sunserial_console_termios(co, to_of_device(port->dev)->node);
- return uart_set_options(port, co, baud, parity, bits, flow);
+ memset(&termios, 0, sizeof(struct ktermios));
+ termios.c_cflag = co->cflag;
+ port->mctrl |= TIOCM_DTR;
+ port->ops->set_termios(port, &termios, &dummy);
+
+ return 0;
}
static struct console sunsu_console = {
@@ -1409,6 +1412,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
struct uart_sunsu_port *up;
struct resource *rp;
enum su_type type;
+ bool ignore_line;
int err;
type = su_get_type(dp);
@@ -1467,8 +1471,14 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
up->port.ops = &sunsu_pops;
+ ignore_line = false;
+ if (!strcmp(dp->name, "rsc-console") ||
+ !strcmp(dp->name, "lom-console"))
+ ignore_line = true;
+
sunserial_console_match(SUNSU_CONSOLE(), dp,
- &sunsu_reg, up->port.line);
+ &sunsu_reg, up->port.line,
+ ignore_line);
err = uart_add_one_port(&sunsu_reg, &up->port);
if (err)
goto out_unmap;
@@ -1517,6 +1527,10 @@ static const struct of_device_id su_match[] = {
.name = "serial",
.compatible = "su",
},
+ {
+ .type = "serial",
+ .compatible = "su",
+ },
{},
};
MODULE_DEVICE_TABLE(of, su_match);
@@ -1548,6 +1562,12 @@ static int __init sunsu_init(void)
num_uart++;
}
}
+ for_each_node_by_type(dp, "serial") {
+ if (of_device_is_compatible(dp, "su")) {
+ if (su_get_type(dp) == SU_PORT_PORT)
+ num_uart++;
+ }
+ }
if (num_uart) {
err = sunserial_register_minors(&sunsu_reg, num_uart);
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index ef693ae22e7f..2c7a66af4f52 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
(sunzilog_reg.minor - 64) + con->index, con->index);
/* Get firmware console settings. */
- sunserial_console_termios(con);
+ sunserial_console_termios(con, to_of_device(up->port.dev)->node);
/* Firmware console speed is limited to 150-->38400 baud so
* this hackish cflag thing is OK.
@@ -1416,7 +1416,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
if (!keyboard_mouse) {
if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
- &sunzilog_reg, up[0].port.line))
+ &sunzilog_reg, up[0].port.line,
+ false))
up->flags |= SUNZILOG_FLAG_IS_CONS;
err = uart_add_one_port(&sunzilog_reg, &up[0].port);
if (err) {
@@ -1425,7 +1426,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
return err;
}
if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
- &sunzilog_reg, up[1].port.line))
+ &sunzilog_reg, up[1].port.line,
+ false))
up->flags |= SUNZILOG_FLAG_IS_CONS;
err = uart_add_one_port(&sunzilog_reg, &up[1].port);
if (err) {
diff --git a/drivers/spi/spi_stmp.c b/drivers/spi/spi_stmp.c
index d871dc23909c..2552bb364005 100644
--- a/drivers/spi/spi_stmp.c
+++ b/drivers/spi/spi_stmp.c
@@ -242,7 +242,7 @@ static int stmp_spi_txrx_dma(struct stmp_spi *ss, int cs,
wait_for_completion(&ss->done);
if (!busy_wait(readl(ss->regs + HW_SSP_CTRL0) & BM_SSP_CTRL0_RUN))
- status = ETIMEDOUT;
+ status = -ETIMEDOUT;
if (!dma_buf)
dma_unmap_single(ss->master_dev, spi_buf_dma, len, dir);
diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c
index 96057de133ad..19f75627c3de 100644
--- a/drivers/spi/spi_txx9.c
+++ b/drivers/spi/spi_txx9.c
@@ -29,6 +29,8 @@
#define SPI_FIFO_SIZE 4
+#define SPI_MAX_DIVIDER 0xff /* Max. value for SPCR1.SER */
+#define SPI_MIN_DIVIDER 1 /* Min. value for SPCR1.SER */
#define TXx9_SPMCR 0x00
#define TXx9_SPCR0 0x04
@@ -193,11 +195,8 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m)
if (prev_speed_hz != speed_hz
|| prev_bits_per_word != bits_per_word) {
- u32 n = (c->baseclk + speed_hz - 1) / speed_hz;
- if (n < 1)
- n = 1;
- else if (n > 0xff)
- n = 0xff;
+ int n = DIV_ROUND_UP(c->baseclk, speed_hz) - 1;
+ n = clamp(n, SPI_MIN_DIVIDER, SPI_MAX_DIVIDER);
/* enter config mode */
txx9spi_wr(c, mcr | TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR,
TXx9_SPMCR);
@@ -370,8 +369,8 @@ static int __init txx9spi_probe(struct platform_device *dev)
goto exit;
}
c->baseclk = clk_get_rate(c->clk);
- c->min_speed_hz = (c->baseclk + 0xff - 1) / 0xff;
- c->max_speed_hz = c->baseclk;
+ c->min_speed_hz = DIV_ROUND_UP(c->baseclk, SPI_MAX_DIVIDER + 1);
+ c->max_speed_hz = c->baseclk / (SPI_MIN_DIVIDER + 1);
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res)
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index 100e7a5c5ea1..e72f4046a5e0 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -617,136 +617,140 @@ static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
} \
} while (0)
-int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
- struct ssb_init_invariants *iv)
+static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
{
- tuple_t tuple;
- int res;
- unsigned char buf[32];
+ struct ssb_sprom *sprom = priv;
+
+ if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
+ return -EINVAL;
+ if (tuple->TupleDataLen != ETH_ALEN + 2)
+ return -EINVAL;
+ if (tuple->TupleData[1] != ETH_ALEN)
+ return -EINVAL;
+ memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
+ return 0;
+};
+
+static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
+{
+ struct ssb_init_invariants *iv = priv;
struct ssb_sprom *sprom = &iv->sprom;
struct ssb_boardinfo *bi = &iv->boardinfo;
const char *error_description;
+ GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
+ switch (tuple->TupleData[0]) {
+ case SSB_PCMCIA_CIS_ID:
+ GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
+ (tuple->TupleDataLen != 7),
+ "id tpl size");
+ bi->vendor = tuple->TupleData[1] |
+ ((u16)tuple->TupleData[2] << 8);
+ break;
+ case SSB_PCMCIA_CIS_BOARDREV:
+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
+ "boardrev tpl size");
+ sprom->board_rev = tuple->TupleData[1];
+ break;
+ case SSB_PCMCIA_CIS_PA:
+ GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
+ (tuple->TupleDataLen != 10),
+ "pa tpl size");
+ sprom->pa0b0 = tuple->TupleData[1] |
+ ((u16)tuple->TupleData[2] << 8);
+ sprom->pa0b1 = tuple->TupleData[3] |
+ ((u16)tuple->TupleData[4] << 8);
+ sprom->pa0b2 = tuple->TupleData[5] |
+ ((u16)tuple->TupleData[6] << 8);
+ sprom->itssi_a = tuple->TupleData[7];
+ sprom->itssi_bg = tuple->TupleData[7];
+ sprom->maxpwr_a = tuple->TupleData[8];
+ sprom->maxpwr_bg = tuple->TupleData[8];
+ break;
+ case SSB_PCMCIA_CIS_OEMNAME:
+ /* We ignore this. */
+ break;
+ case SSB_PCMCIA_CIS_CCODE:
+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
+ "ccode tpl size");
+ sprom->country_code = tuple->TupleData[1];
+ break;
+ case SSB_PCMCIA_CIS_ANTENNA:
+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
+ "ant tpl size");
+ sprom->ant_available_a = tuple->TupleData[1];
+ sprom->ant_available_bg = tuple->TupleData[1];
+ break;
+ case SSB_PCMCIA_CIS_ANTGAIN:
+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
+ "antg tpl size");
+ sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
+ sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
+ sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
+ sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
+ sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
+ sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
+ sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
+ sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
+ break;
+ case SSB_PCMCIA_CIS_BFLAGS:
+ GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
+ (tuple->TupleDataLen != 5),
+ "bfl tpl size");
+ sprom->boardflags_lo = tuple->TupleData[1] |
+ ((u16)tuple->TupleData[2] << 8);
+ break;
+ case SSB_PCMCIA_CIS_LEDS:
+ GOTO_ERROR_ON(tuple->TupleDataLen != 5,
+ "leds tpl size");
+ sprom->gpio0 = tuple->TupleData[1];
+ sprom->gpio1 = tuple->TupleData[2];
+ sprom->gpio2 = tuple->TupleData[3];
+ sprom->gpio3 = tuple->TupleData[4];
+ break;
+ }
+ return -ENOSPC; /* continue with next entry */
+
+error:
+ ssb_printk(KERN_ERR PFX
+ "PCMCIA: Failed to fetch device invariants: %s\n",
+ error_description);
+ return -ENODEV;
+}
+
+
+int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
+ struct ssb_init_invariants *iv)
+{
+ struct ssb_sprom *sprom = &iv->sprom;
+ int res;
+
memset(sprom, 0xFF, sizeof(*sprom));
sprom->revision = 1;
sprom->boardflags_lo = 0;
sprom->boardflags_hi = 0;
/* First fetch the MAC address. */
- memset(&tuple, 0, sizeof(tuple));
- tuple.DesiredTuple = CISTPL_FUNCE;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
- GOTO_ERROR_ON(res != 0, "MAC first tpl");
- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
- GOTO_ERROR_ON(res != 0, "MAC first tpl data");
- while (1) {
- GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
- if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
- break;
- res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
- GOTO_ERROR_ON(res != 0, "MAC next tpl");
- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
- GOTO_ERROR_ON(res != 0, "MAC next tpl data");
+ res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
+ ssb_pcmcia_get_mac, sprom);
+ if (res != 0) {
+ ssb_printk(KERN_ERR PFX
+ "PCMCIA: Failed to fetch MAC address\n");
+ return -ENODEV;
}
- GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
- memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
/* Fetch the vendor specific tuples. */
- memset(&tuple, 0, sizeof(tuple));
- tuple.DesiredTuple = SSB_PCMCIA_CIS;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
- GOTO_ERROR_ON(res != 0, "VEN first tpl");
- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
- GOTO_ERROR_ON(res != 0, "VEN first tpl data");
- while (1) {
- GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
- switch (tuple.TupleData[0]) {
- case SSB_PCMCIA_CIS_ID:
- GOTO_ERROR_ON((tuple.TupleDataLen != 5) &&
- (tuple.TupleDataLen != 7),
- "id tpl size");
- bi->vendor = tuple.TupleData[1] |
- ((u16)tuple.TupleData[2] << 8);
- break;
- case SSB_PCMCIA_CIS_BOARDREV:
- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
- "boardrev tpl size");
- sprom->board_rev = tuple.TupleData[1];
- break;
- case SSB_PCMCIA_CIS_PA:
- GOTO_ERROR_ON((tuple.TupleDataLen != 9) &&
- (tuple.TupleDataLen != 10),
- "pa tpl size");
- sprom->pa0b0 = tuple.TupleData[1] |
- ((u16)tuple.TupleData[2] << 8);
- sprom->pa0b1 = tuple.TupleData[3] |
- ((u16)tuple.TupleData[4] << 8);
- sprom->pa0b2 = tuple.TupleData[5] |
- ((u16)tuple.TupleData[6] << 8);
- sprom->itssi_a = tuple.TupleData[7];
- sprom->itssi_bg = tuple.TupleData[7];
- sprom->maxpwr_a = tuple.TupleData[8];
- sprom->maxpwr_bg = tuple.TupleData[8];
- break;
- case SSB_PCMCIA_CIS_OEMNAME:
- /* We ignore this. */
- break;
- case SSB_PCMCIA_CIS_CCODE:
- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
- "ccode tpl size");
- sprom->country_code = tuple.TupleData[1];
- break;
- case SSB_PCMCIA_CIS_ANTENNA:
- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
- "ant tpl size");
- sprom->ant_available_a = tuple.TupleData[1];
- sprom->ant_available_bg = tuple.TupleData[1];
- break;
- case SSB_PCMCIA_CIS_ANTGAIN:
- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
- "antg tpl size");
- sprom->antenna_gain.ghz24.a0 = tuple.TupleData[1];
- sprom->antenna_gain.ghz24.a1 = tuple.TupleData[1];
- sprom->antenna_gain.ghz24.a2 = tuple.TupleData[1];
- sprom->antenna_gain.ghz24.a3 = tuple.TupleData[1];
- sprom->antenna_gain.ghz5.a0 = tuple.TupleData[1];
- sprom->antenna_gain.ghz5.a1 = tuple.TupleData[1];
- sprom->antenna_gain.ghz5.a2 = tuple.TupleData[1];
- sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
- break;
- case SSB_PCMCIA_CIS_BFLAGS:
- GOTO_ERROR_ON((tuple.TupleDataLen != 3) &&
- (tuple.TupleDataLen != 5),
- "bfl tpl size");
- sprom->boardflags_lo = tuple.TupleData[1] |
- ((u16)tuple.TupleData[2] << 8);
- break;
- case SSB_PCMCIA_CIS_LEDS:
- GOTO_ERROR_ON(tuple.TupleDataLen != 5,
- "leds tpl size");
- sprom->gpio0 = tuple.TupleData[1];
- sprom->gpio1 = tuple.TupleData[2];
- sprom->gpio2 = tuple.TupleData[3];
- sprom->gpio3 = tuple.TupleData[4];
- break;
- }
- res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
- if (res == -ENOSPC)
- break;
- GOTO_ERROR_ON(res != 0, "VEN next tpl");
- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
- GOTO_ERROR_ON(res != 0, "VEN next tpl data");
- }
+ res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
+ ssb_pcmcia_do_get_invariants, sprom);
+ if ((res == 0) || (res == -ENOSPC))
+ return 0;
- return 0;
-error:
ssb_printk(KERN_ERR PFX
- "PCMCIA: Failed to fetch device invariants: %s\n",
- error_description);
+ "PCMCIA: Failed to fetch device invariants\n");
return -ENODEV;
}
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index b74212d698c7..e8b89e8ac9bd 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -162,6 +162,8 @@ static u8 chipid_to_nrcores(u16 chipid)
static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
u16 offset)
{
+ u32 lo, hi;
+
switch (bus->bustype) {
case SSB_BUSTYPE_SSB:
offset += current_coreidx * SSB_CORE_SIZE;
@@ -174,7 +176,9 @@ static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
offset -= 0x800;
} else
ssb_pcmcia_switch_segment(bus, 0);
- break;
+ lo = readw(bus->mmio + offset);
+ hi = readw(bus->mmio + offset + 2);
+ return lo | (hi << 16);
case SSB_BUSTYPE_SDIO:
offset += current_coreidx * SSB_CORE_SIZE;
return ssb_sdio_scan_read32(bus, offset);
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 7df3ba4f1f4d..d21b3469f6d7 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -93,8 +93,6 @@ source "drivers/staging/dst/Kconfig"
source "drivers/staging/pohmelfs/Kconfig"
-source "drivers/staging/stlc45xx/Kconfig"
-
source "drivers/staging/b3dfg/Kconfig"
source "drivers/staging/phison/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 747571172269..8cbf1aebea2e 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_ANDROID) += android/
obj-$(CONFIG_ANDROID) += dream/
obj-$(CONFIG_DST) += dst/
obj-$(CONFIG_POHMELFS) += pohmelfs/
-obj-$(CONFIG_STLC45XX) += stlc45xx/
obj-$(CONFIG_B3DFG) += b3dfg/
obj-$(CONFIG_IDE_PHISON) += phison/
obj-$(CONFIG_PLAN9AUTH) += p9auth/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 247194992374..eb675635ae60 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -2,6 +2,7 @@ menu "Android"
config ANDROID
bool "Android Drivers"
+ depends on BROKEN
default N
---help---
Enable support for various drivers needed on the Android platform
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
index 94c5d27d24d7..cda26bb493b3 100644
--- a/drivers/staging/b3dfg/b3dfg.c
+++ b/drivers/staging/b3dfg/b3dfg.c
@@ -36,6 +36,7 @@
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/uaccess.h>
+#include <linux/sched.h>
static unsigned int b3dfg_nbuf = 2;
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index 80c0df8656f3..39923cb388be 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -141,37 +141,14 @@ static int das16cs_timer_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data);
-static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
-{
- tuple_t tuple;
- u_short buf[128];
- int prodid = 0;
-
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.DesiredTuple = CISTPL_MANFID;
- tuple.Attributes = TUPLE_RETURN_COMMON;
- if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
- (pcmcia_get_tuple_data(link, &tuple) == 0)) {
- prodid = le16_to_cpu(buf[1]);
- }
-
- return prodid;
-}
-
static const struct das16cs_board *das16cs_probe(struct comedi_device *dev,
struct pcmcia_device *link)
{
- int id;
int i;
- id = get_prodid(dev, link);
-
for (i = 0; i < n_boards; i++) {
- if (das16cs_boards[i].device_id == id) {
+ if (das16cs_boards[i].device_id == link->card_id)
return das16cs_boards + i;
- }
}
printk("unknown board!\n");
@@ -660,27 +637,8 @@ static int das16cs_timer_insn_config(struct comedi_device *dev,
======================================================================*/
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
- "cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
-
static void das16cs_pcmcia_config(struct pcmcia_device *link);
static void das16cs_pcmcia_release(struct pcmcia_device *link);
static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev);
@@ -733,7 +691,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
{
struct local_info_t *local;
- DEBUG(0, "das16cs_pcmcia_attach()\n");
+ dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -745,7 +703,6 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
/* Initialize the pcmcia_device structure */
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
link->conf.Attributes = 0;
@@ -760,7 +717,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
static void das16cs_pcmcia_detach(struct pcmcia_device *link)
{
- DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "das16cs_pcmcia_detach\n");
if (link->dev_node) {
((struct local_info_t *)link->priv)->stop = 1;
@@ -771,118 +728,55 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
kfree(link->priv);
} /* das16cs_pcmcia_detach */
-static void das16cs_pcmcia_config(struct pcmcia_device *link)
-{
- struct local_info_t *dev = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_fn, last_ret;
- u_char buf[64];
- cistpl_cftable_entry_t dflt = { 0 };
- DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);
-
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- last_fn = GetFirstTuple;
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret != 0)
- goto cs_failed;
-
- last_fn = GetTupleData;
- last_ret = pcmcia_get_tuple_data(link, &tuple);
- if (last_ret != 0)
- goto cs_failed;
-
- last_fn = ParseTuple;
- last_ret = pcmcia_parse_tuple(&tuple, &parse);
- if (last_ret != 0)
- goto cs_failed;
-
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->index == 0)
+ return -EINVAL;
- /*
- In this loop, we scan the CIS for configuration table entries,
- each of which describes a valid card configuration, including
- voltage, IO window, memory window, and interrupt settings.
-
- We make no assumptions about the card to be configured: we use
- just the information available in the CIS. In an ideal world,
- this would work for any PCMCIA card, but it requires a complete
- and accurate CIS. In practice, a driver usually "knows" most of
- these things without consulting the CIS, and most client drivers
- will only use the CIS to fill in implementation-defined details.
- */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- last_fn = GetFirstTuple;
-
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret)
- goto cs_failed;
-
- while (1) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
- if (pcmcia_get_tuple_data(link, &tuple))
- goto next_entry;
- if (pcmcia_parse_tuple(&tuple, &parse))
- goto next_entry;
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
- dflt = *cfg;
- if (cfg->index == 0)
- goto next_entry;
- link->conf.ConfigIndex = cfg->index;
-
- /* Does this card need audio output? */
-/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
-*/
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = link->io.NumPorts2 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- if (io->nwin > 1) {
- link->io.Attributes2 = link->io.Attributes1;
- link->io.BasePort2 = io->win[1].base;
- link->io.NumPorts2 = io->win[1].len;
- }
- /* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(link, &link->io))
- goto next_entry;
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
}
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+ }
- /* If we got this far, we're cool! */
- break;
+ return 0;
+}
+
+static void das16cs_pcmcia_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ int ret;
-next_entry:
- last_fn = GetNextTuple;
+ dev_dbg(&link->dev, "das16cs_pcmcia_config\n");
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- if (last_ret)
- goto cs_failed;
+ ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
+ if (ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto failed;
}
/*
@@ -891,21 +785,18 @@ next_entry:
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
- last_fn = RequestIRQ;
-
- last_ret = pcmcia_request_irq(link, &link->irq);
- if (last_ret)
- goto cs_failed;
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
}
/*
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- last_fn = RequestConfiguration;
- last_ret = pcmcia_request_configuration(link, &link->conf);
- if (last_ret)
- goto cs_failed;
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*
At this point, the dev_node_t structure(s) need to be
@@ -930,14 +821,13 @@ next_entry:
return;
-cs_failed:
- cs_error(link, last_fn, last_ret);
+failed:
das16cs_pcmcia_release(link);
} /* das16cs_pcmcia_config */
static void das16cs_pcmcia_release(struct pcmcia_device *link)
{
- DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "das16cs_pcmcia_release\n");
pcmcia_disable_device(link);
} /* das16cs_pcmcia_release */
@@ -983,14 +873,13 @@ struct pcmcia_driver das16cs_driver = {
static int __init init_das16cs_pcmcia_cs(void)
{
- DEBUG(0, "%s\n", version);
pcmcia_register_driver(&das16cs_driver);
return 0;
}
static void __exit exit_das16cs_pcmcia_cs(void)
{
- DEBUG(0, "das16cs_pcmcia_cs: unloading\n");
+ pr_debug("das16cs_pcmcia_cs: unloading\n");
pcmcia_unregister_driver(&das16cs_driver);
}
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index 9cab21eaaa18..9b945e5fdd32 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -110,25 +110,6 @@ static int das08_cs_attach(struct comedi_device *dev,
======================================================================*/
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static const char *version =
- "das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
static void das08_pcmcia_config(struct pcmcia_device *link);
static void das08_pcmcia_release(struct pcmcia_device *link);
static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
@@ -181,7 +162,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
{
struct local_info_t *local;
- DEBUG(0, "das08_pcmcia_attach()\n");
+ dev_dbg(&link->dev, "das08_pcmcia_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -192,7 +173,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
/*
@@ -224,7 +204,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
static void das08_pcmcia_detach(struct pcmcia_device *link)
{
- DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "das08_pcmcia_detach\n");
if (link->dev_node) {
((struct local_info_t *)link->priv)->stop = 1;
@@ -237,6 +217,44 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
} /* das08_pcmcia_detach */
+
+static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->index == 0)
+ return -ENODEV;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+ }
+ return 0;
+}
+
+
/*======================================================================
das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
@@ -248,128 +266,20 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
static void das08_pcmcia_config(struct pcmcia_device *link)
{
struct local_info_t *dev = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_fn, last_ret;
- u_char buf[64];
- cistpl_cftable_entry_t dflt = { 0 };
-
- DEBUG(0, "das08_pcmcia_config(0x%p)\n", link);
-
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- last_fn = GetFirstTuple;
-
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret)
- goto cs_failed;
-
- last_fn = GetTupleData;
-
- last_ret = pcmcia_get_tuple_data(link, &tuple);
- if (last_ret)
- goto cs_failed;
-
- last_fn = ParseTuple;
-
- last_ret = pcmcia_parse_tuple(&tuple, &parse);
- if (last_ret)
- goto cs_failed;
-
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
- /*
- In this loop, we scan the CIS for configuration table entries,
- each of which describes a valid card configuration, including
- voltage, IO window, memory window, and interrupt settings.
-
- We make no assumptions about the card to be configured: we use
- just the information available in the CIS. In an ideal world,
- this would work for any PCMCIA card, but it requires a complete
- and accurate CIS. In practice, a driver usually "knows" most of
- these things without consulting the CIS, and most client drivers
- will only use the CIS to fill in implementation-defined details.
- */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- last_fn = GetFirstTuple;
-
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret)
- goto cs_failed;
-
- while (1) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-
- last_ret = pcmcia_get_tuple_data(link, &tuple);
- if (last_ret)
- goto next_entry;
-
- last_ret = pcmcia_parse_tuple(&tuple, &parse);
- if (last_ret)
- goto next_entry;
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
- dflt = *cfg;
- if (cfg->index == 0)
- goto next_entry;
- link->conf.ConfigIndex = cfg->index;
-
- /* Does this card need audio output? */
-/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
-*/
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = link->io.NumPorts2 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- if (io->nwin > 1) {
- link->io.Attributes2 = link->io.Attributes1;
- link->io.BasePort2 = io->win[1].base;
- link->io.NumPorts2 = io->win[1].len;
- }
- /* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(link, &link->io) != 0)
- goto next_entry;
- }
-
- /* If we got this far, we're cool! */
- break;
+ int ret;
-next_entry:
- last_fn = GetNextTuple;
+ dev_dbg(&link->dev, "das08_pcmcia_config\n");
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- if (last_ret)
- goto cs_failed;
+ ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
+ if (ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto failed;
}
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
- last_fn = RequestIRQ;
- last_ret = pcmcia_request_irq(link, &link->irq);
- if (last_ret)
- goto cs_failed;
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
}
/*
@@ -377,10 +287,9 @@ next_entry:
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- last_fn = RequestConfiguration;
- last_ret = pcmcia_request_configuration(link, &link->conf);
- if (last_ret)
- goto cs_failed;
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*
At this point, the dev_node_t structure(s) need to be
@@ -405,8 +314,7 @@ next_entry:
return;
-cs_failed:
- cs_error(link, last_fn, last_ret);
+failed:
das08_pcmcia_release(link);
} /* das08_pcmcia_config */
@@ -421,7 +329,7 @@ cs_failed:
static void das08_pcmcia_release(struct pcmcia_device *link)
{
- DEBUG(0, "das08_pcmcia_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "das08_pcmcia_release\n");
pcmcia_disable_device(link);
} /* das08_pcmcia_release */
@@ -477,14 +385,13 @@ struct pcmcia_driver das08_cs_driver = {
static int __init init_das08_pcmcia_cs(void)
{
- DEBUG(0, "%s\n", version);
pcmcia_register_driver(&das08_cs_driver);
return 0;
}
static void __exit exit_das08_pcmcia_cs(void)
{
- DEBUG(0, "das08_pcmcia_cs: unloading\n");
+ pr_debug("das08_pcmcia_cs: unloading\n");
pcmcia_unregister_driver(&das08_cs_driver);
}
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index 2cda7ad1d32f..80e192d2e77e 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -51,6 +51,7 @@ from http://www.comedi.org
*/
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include "../comedidev.h"
#include "comedi_pci.h"
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index ec31a3970664..ef5e1183d47d 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -436,25 +436,7 @@ static int dio700_detach(struct comedi_device *dev)
return 0;
};
-/* PCMCIA crap */
-
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "ni_daq_700.c, based on dummy_cs.c";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
+/* PCMCIA crap -- watch your words, please! */
static void dio700_config(struct pcmcia_device *link);
static void dio700_release(struct pcmcia_device *link);
@@ -510,7 +492,7 @@ static int dio700_cs_attach(struct pcmcia_device *link)
printk(KERN_INFO "ni_daq_700: cs-attach\n");
- DEBUG(0, "dio700_cs_attach()\n");
+ dev_dbg(&link->dev, "dio700_cs_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -521,7 +503,6 @@ static int dio700_cs_attach(struct pcmcia_device *link)
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
/*
@@ -555,7 +536,7 @@ static void dio700_cs_detach(struct pcmcia_device *link)
printk(KERN_INFO "ni_daq_700: cs-detach!\n");
- DEBUG(0, "dio700_cs_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "dio700_cs_detach\n");
if (link->dev_node) {
((struct local_info_t *)link->priv)->stop = 1;
@@ -576,141 +557,85 @@ static void dio700_cs_detach(struct pcmcia_device *link)
======================================================================*/
-static void dio700_config(struct pcmcia_device *link)
+static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
{
- struct local_info_t *dev = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_ret;
- u_char buf[64];
- win_req_t req;
+ win_req_t *req = priv_data;
memreq_t map;
- cistpl_cftable_entry_t dflt = { 0 };
- printk(KERN_INFO "ni_daq_700: cs-config\n");
-
- DEBUG(0, "dio700_config(0x%p)\n", link);
+ if (cfg->index == 0)
+ return -ENODEV;
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetFirstTuple, last_ret);
- goto cs_failed;
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
+ p_dev->conf.Status = CCSR_AUDIO_ENA;
}
- last_ret = pcmcia_get_tuple_data(link, &tuple);
- if (last_ret) {
- cs_error(link, GetTupleData, last_ret);
- goto cs_failed;
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+ return -ENODEV;
}
- last_ret = pcmcia_parse_tuple(&tuple, &parse);
- if (last_ret) {
- cs_error(link, ParseTuple, last_ret);
- goto cs_failed;
+ if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+ req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req->Attributes |= WIN_ENABLE;
+ req->Base = mem->win[0].host_addr;
+ req->Size = mem->win[0].len;
+ if (req->Size < 0x1000)
+ req->Size = 0x1000;
+ req->AccessSpeed = 0;
+ if (pcmcia_request_window(p_dev, req, &p_dev->win))
+ return -ENODEV;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
+ return -ENODEV;
}
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
- /*
- In this loop, we scan the CIS for configuration table entries,
- each of which describes a valid card configuration, including
- voltage, IO window, memory window, and interrupt settings.
-
- We make no assumptions about the card to be configured: we use
- just the information available in the CIS. In an ideal world,
- this would work for any PCMCIA card, but it requires a complete
- and accurate CIS. In practice, a driver usually "knows" most of
- these things without consulting the CIS, and most client drivers
- will only use the CIS to fill in implementation-defined details.
- */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret != 0) {
- cs_error(link, GetFirstTuple, last_ret);
- goto cs_failed;
- }
- while (1) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
- if (pcmcia_get_tuple_data(link, &tuple) != 0)
- goto next_entry;
- if (pcmcia_parse_tuple(&tuple, &parse) != 0)
- goto next_entry;
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
- dflt = *cfg;
- if (cfg->index == 0)
- goto next_entry;
- link->conf.ConfigIndex = cfg->index;
-
- /* Does this card need audio output? */
- if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
+ /* If we got this far, we're cool! */
+ return 0;
+}
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = link->io.NumPorts2 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- if (io->nwin > 1) {
- link->io.Attributes2 = link->io.Attributes1;
- link->io.BasePort2 = io->win[1].base;
- link->io.NumPorts2 = io->win[1].len;
- }
- /* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(link, &link->io) != 0)
- goto next_entry;
- }
+static void dio700_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ win_req_t req;
+ int ret;
- if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
- cistpl_mem_t *mem =
- (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
- req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
- req.Attributes |= WIN_ENABLE;
- req.Base = mem->win[0].host_addr;
- req.Size = mem->win[0].len;
- if (req.Size < 0x1000)
- req.Size = 0x1000;
- req.AccessSpeed = 0;
- if (pcmcia_request_window(&link, &req, &link->win))
- goto next_entry;
- map.Page = 0;
- map.CardOffset = mem->win[0].card_addr;
- if (pcmcia_map_mem_page(link->win, &map))
- goto next_entry;
- }
- /* If we got this far, we're cool! */
- break;
+ printk(KERN_INFO "ni_daq_700: cs-config\n");
-next_entry:
+ dev_dbg(&link->dev, "dio700_config\n");
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetNextTuple, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, &req);
+ if (ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto failed;
}
/*
@@ -719,11 +644,9 @@ next_entry:
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
- last_ret = pcmcia_request_irq(link, &link->irq);
- if (last_ret) {
- cs_error(link, RequestIRQ, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
}
/*
@@ -731,11 +654,9 @@ next_entry:
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- last_ret = pcmcia_request_configuration(link, &link->conf);
- if (last_ret != 0) {
- cs_error(link, RequestConfiguration, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret != 0)
+ goto failed;
/*
At this point, the dev_node_t structure(s) need to be
@@ -763,7 +684,7 @@ next_entry:
return;
-cs_failed:
+failed:
printk(KERN_INFO "ni_daq_700 cs failed");
dio700_release(link);
@@ -771,7 +692,7 @@ cs_failed:
static void dio700_release(struct pcmcia_device *link)
{
- DEBUG(0, "dio700_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "dio700_release\n");
pcmcia_disable_device(link);
} /* dio700_release */
@@ -830,15 +751,13 @@ struct pcmcia_driver dio700_cs_driver = {
static int __init init_dio700_cs(void)
{
- printk("ni_daq_700: cs-init \n");
- DEBUG(0, "%s\n", version);
pcmcia_register_driver(&dio700_cs_driver);
return 0;
}
static void __exit exit_dio700_cs(void)
{
- DEBUG(0, "ni_daq_700: unloading\n");
+ pr_debug("ni_daq_700: unloading\n");
pcmcia_unregister_driver(&dio700_cs_driver);
}
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index 0700a8bddd1e..9017be3a92f1 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -187,25 +187,7 @@ static int dio24_detach(struct comedi_device *dev)
return 0;
};
-/* PCMCIA crap */
-
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "ni_daq_dio24.c, based on dummy_cs.c";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
+/* PCMCIA crap -- watch your words! */
static void dio24_config(struct pcmcia_device *link);
static void dio24_release(struct pcmcia_device *link);
@@ -261,7 +243,7 @@ static int dio24_cs_attach(struct pcmcia_device *link)
printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
- DEBUG(0, "dio24_cs_attach()\n");
+ dev_dbg(&link->dev, "dio24_cs_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -272,7 +254,6 @@ static int dio24_cs_attach(struct pcmcia_device *link)
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
/*
@@ -306,7 +287,7 @@ static void dio24_cs_detach(struct pcmcia_device *link)
printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
- DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "dio24_cs_detach\n");
if (link->dev_node) {
((struct local_info_t *)link->priv)->stop = 1;
@@ -327,142 +308,85 @@ static void dio24_cs_detach(struct pcmcia_device *link)
======================================================================*/
-static void dio24_config(struct pcmcia_device *link)
+static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
{
- struct local_info_t *dev = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_ret;
- u_char buf[64];
- win_req_t req;
+ win_req_t *req = priv_data;
memreq_t map;
- cistpl_cftable_entry_t dflt = { 0 };
- printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
-
- DEBUG(0, "dio24_config(0x%p)\n", link);
-
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetFirstTuple, last_ret);
- goto cs_failed;
- }
+ if (cfg->index == 0)
+ return -ENODEV;
- last_ret = pcmcia_get_tuple_data(link, &tuple);
- if (last_ret) {
- cs_error(link, GetTupleData, last_ret);
- goto cs_failed;
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
+ p_dev->conf.Status = CCSR_AUDIO_ENA;
}
- last_ret = pcmcia_parse_tuple(&tuple, &parse);
- if (last_ret) {
- cs_error(link, ParseTuple, last_ret);
- goto cs_failed;
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+ return -ENODEV;
}
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
- /*
- In this loop, we scan the CIS for configuration table entries,
- each of which describes a valid card configuration, including
- voltage, IO window, memory window, and interrupt settings.
-
- We make no assumptions about the card to be configured: we use
- just the information available in the CIS. In an ideal world,
- this would work for any PCMCIA card, but it requires a complete
- and accurate CIS. In practice, a driver usually "knows" most of
- these things without consulting the CIS, and most client drivers
- will only use the CIS to fill in implementation-defined details.
- */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetFirstTuple, last_ret);
- goto cs_failed;
+ if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+ req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req->Attributes |= WIN_ENABLE;
+ req->Base = mem->win[0].host_addr;
+ req->Size = mem->win[0].len;
+ if (req->Size < 0x1000)
+ req->Size = 0x1000;
+ req->AccessSpeed = 0;
+ if (pcmcia_request_window(p_dev, req, &p_dev->win))
+ return -ENODEV;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
+ return -ENODEV;
}
- while (1) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
- if (pcmcia_get_tuple_data(link, &tuple) != 0)
- goto next_entry;
- if (pcmcia_parse_tuple(&tuple, &parse) != 0)
- goto next_entry;
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
- dflt = *cfg;
- if (cfg->index == 0)
- goto next_entry;
- link->conf.ConfigIndex = cfg->index;
-
- /* Does this card need audio output? */
- if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
+ /* If we got this far, we're cool! */
+ return 0;
+}
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = link->io.NumPorts2 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- if (io->nwin > 1) {
- link->io.Attributes2 = link->io.Attributes1;
- link->io.BasePort2 = io->win[1].base;
- link->io.NumPorts2 = io->win[1].len;
- }
- /* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(link, &link->io) != 0)
- goto next_entry;
- }
+static void dio24_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ int ret;
+ win_req_t req;
- if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
- cistpl_mem_t *mem =
- (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
- req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
- req.Attributes |= WIN_ENABLE;
- req.Base = mem->win[0].host_addr;
- req.Size = mem->win[0].len;
- if (req.Size < 0x1000)
- req.Size = 0x1000;
- req.AccessSpeed = 0;
- if (pcmcia_request_window(&link, &req, &link->win))
- goto next_entry;
- map.Page = 0;
- map.CardOffset = mem->win[0].card_addr;
- if (pcmcia_map_mem_page(link->win, &map))
- goto next_entry;
- }
- /* If we got this far, we're cool! */
- break;
+ printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
-next_entry:
+ dev_dbg(&link->dev, "dio24_config\n");
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetNextTuple, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, &req);
+ if (ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto failed;
}
/*
@@ -471,11 +395,9 @@ next_entry:
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
- last_ret = pcmcia_request_irq(link, &link->irq);
- if (last_ret) {
- cs_error(link, RequestIRQ, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
}
/*
@@ -483,11 +405,9 @@ next_entry:
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- last_ret = pcmcia_request_configuration(link, &link->conf);
- if (last_ret) {
- cs_error(link, RequestConfiguration, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*
At this point, the dev_node_t structure(s) need to be
@@ -515,7 +435,7 @@ next_entry:
return;
-cs_failed:
+failed:
printk(KERN_INFO "Fallo");
dio24_release(link);
@@ -523,7 +443,7 @@ cs_failed:
static void dio24_release(struct pcmcia_device *link)
{
- DEBUG(0, "dio24_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "dio24_release\n");
pcmcia_disable_device(link);
} /* dio24_release */
@@ -582,14 +502,12 @@ struct pcmcia_driver dio24_cs_driver = {
static int __init init_dio24_cs(void)
{
printk("ni_daq_dio24: HOLA SOY YO!\n");
- DEBUG(0, "%s\n", version);
pcmcia_register_driver(&dio24_cs_driver);
return 0;
}
static void __exit exit_dio24_cs(void)
{
- DEBUG(0, "ni_dio24: unloading\n");
pcmcia_unregister_driver(&dio24_cs_driver);
}
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index a3053b8da1c6..7d514b3ee754 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -153,23 +153,6 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return labpc_common_attach(dev, iobase, irq, 0);
}
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static const char *version =
- "ni_labpc.c, based on dummy_cs.c 1.31 2001/08/24 12:13:13";
-#else
-#define DEBUG(n, args...)
-#endif
-
/*====================================================================*/
/*
@@ -236,7 +219,7 @@ static int labpc_cs_attach(struct pcmcia_device *link)
{
struct local_info_t *local;
- DEBUG(0, "labpc_cs_attach()\n");
+ dev_dbg(&link->dev, "labpc_cs_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -247,7 +230,6 @@ static int labpc_cs_attach(struct pcmcia_device *link)
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE;
- link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID;
link->irq.Handler = NULL;
/*
@@ -278,7 +260,7 @@ static int labpc_cs_attach(struct pcmcia_device *link)
static void labpc_cs_detach(struct pcmcia_device *link)
{
- DEBUG(0, "labpc_cs_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "labpc_cs_detach\n");
/*
If the device is currently configured and active, we won't
@@ -305,135 +287,84 @@ static void labpc_cs_detach(struct pcmcia_device *link)
======================================================================*/
-static void labpc_config(struct pcmcia_device *link)
+static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
{
- struct local_info_t *dev = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_ret;
- u_char buf[64];
- win_req_t req;
+ win_req_t *req = priv_data;
memreq_t map;
- cistpl_cftable_entry_t dflt = { 0 };
- DEBUG(0, "labpc_config(0x%p)\n", link);
+ if (cfg->index == 0)
+ return -ENODEV;
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetFirstTuple, last_ret);
- goto cs_failed;
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
+ p_dev->conf.Status = CCSR_AUDIO_ENA;
}
- last_ret = pcmcia_get_tuple_data(link, &tuple);
- if (last_ret) {
- cs_error(link, GetTupleData, last_ret);
- goto cs_failed;
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+ return -ENODEV;
}
- last_ret = pcmcia_parse_tuple(&tuple, &parse);
- if (last_ret) {
- cs_error(link, ParseTuple, last_ret);
- goto cs_failed;
+ if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+ req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req->Attributes |= WIN_ENABLE;
+ req->Base = mem->win[0].host_addr;
+ req->Size = mem->win[0].len;
+ if (req->Size < 0x1000)
+ req->Size = 0x1000;
+ req->AccessSpeed = 0;
+ if (pcmcia_request_window(p_dev, req, &p_dev->win))
+ return -ENODEV;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
+ return -ENODEV;
}
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+ /* If we got this far, we're cool! */
+ return 0;
+}
- /*
- In this loop, we scan the CIS for configuration table entries,
- each of which describes a valid card configuration, including
- voltage, IO window, memory window, and interrupt settings.
-
- We make no assumptions about the card to be configured: we use
- just the information available in the CIS. In an ideal world,
- this would work for any PCMCIA card, but it requires a complete
- and accurate CIS. In practice, a driver usually "knows" most of
- these things without consulting the CIS, and most client drivers
- will only use the CIS to fill in implementation-defined details.
- */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetFirstTuple, last_ret);
- goto cs_failed;
- }
- while (1) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
- if (pcmcia_get_tuple_data(link, &tuple))
- goto next_entry;
- if (pcmcia_parse_tuple(&tuple, &parse))
- goto next_entry;
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
- dflt = *cfg;
- if (cfg->index == 0)
- goto next_entry;
- link->conf.ConfigIndex = cfg->index;
-
- /* Does this card need audio output? */
- if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = link->io.NumPorts2 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- if (io->nwin > 1) {
- link->io.Attributes2 = link->io.Attributes1;
- link->io.BasePort2 = io->win[1].base;
- link->io.NumPorts2 = io->win[1].len;
- }
- /* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(link, &link->io))
- goto next_entry;
- }
+static void labpc_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ int ret;
+ win_req_t req;
- if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
- cistpl_mem_t *mem =
- (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
- req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
- req.Attributes |= WIN_ENABLE;
- req.Base = mem->win[0].host_addr;
- req.Size = mem->win[0].len;
- if (req.Size < 0x1000)
- req.Size = 0x1000;
- req.AccessSpeed = 0;
- link->win = (window_handle_t) link;
- if (pcmcia_request_window(&link, &req, &link->win))
- goto next_entry;
- map.Page = 0;
- map.CardOffset = mem->win[0].card_addr;
- if (pcmcia_map_mem_page(link->win, &map))
- goto next_entry;
- }
- /* If we got this far, we're cool! */
- break;
+ dev_dbg(&link->dev, "labpc_config\n");
-next_entry:
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetNextTuple, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, &req);
+ if (ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto failed;
}
/*
@@ -442,11 +373,9 @@ next_entry:
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
- last_ret = pcmcia_request_irq(link, &link->irq);
- if (last_ret) {
- cs_error(link, RequestIRQ, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
}
/*
@@ -454,11 +383,9 @@ next_entry:
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- last_ret = pcmcia_request_configuration(link, &link->conf);
- if (last_ret) {
- cs_error(link, RequestConfiguration, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*
At this point, the dev_node_t structure(s) need to be
@@ -486,14 +413,14 @@ next_entry:
return;
-cs_failed:
+failed:
labpc_release(link);
} /* labpc_config */
static void labpc_release(struct pcmcia_device *link)
{
- DEBUG(0, "labpc_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "labpc_release\n");
pcmcia_disable_device(link);
} /* labpc_release */
@@ -551,14 +478,12 @@ struct pcmcia_driver labpc_cs_driver = {
static int __init init_labpc_cs(void)
{
- DEBUG(0, "%s\n", version);
pcmcia_register_driver(&labpc_cs_driver);
return 0;
}
static void __exit exit_labpc_cs(void)
{
- DEBUG(0, "ni_labpc: unloading\n");
pcmcia_unregister_driver(&labpc_cs_driver);
}
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index e3ffb067ead1..753ee0512342 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -62,6 +62,7 @@
/* #define DEBUG_STATUS_B */
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include "8255.h"
#include "mite.h"
#include "comedi_fc.h"
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index 9aef87fc81dc..d692f4bb47ea 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -274,7 +274,6 @@ static int cs_attach(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
link->io.NumPorts1 = 16;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -312,96 +311,47 @@ static int mio_cs_resume(struct pcmcia_device *link)
return 0;
}
-static void mio_cs_config(struct pcmcia_device *link)
-{
- tuple_t tuple;
- u_short buf[128];
- cisparse_t parse;
- int manfid = 0, prodid = 0;
- int ret;
-
- DPRINTK("mio_cs_config(link=%p)\n", link);
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
+static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ int base, ret;
- tuple.DesiredTuple = CISTPL_CONFIG;
- ret = pcmcia_get_first_tuple(link, &tuple);
- ret = pcmcia_get_tuple_data(link, &tuple);
- ret = pcmcia_parse_tuple(&tuple, &parse);
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+ p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.NumPorts2 = 0;
-#if 0
- tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
- tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
- info->multi(first_tuple(link, &tuple, &parse) == 0);
-#endif
-
- tuple.DesiredTuple = CISTPL_MANFID;
- tuple.Attributes = TUPLE_RETURN_COMMON;
- if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
- (pcmcia_get_tuple_data(link, &tuple) == 0)) {
- manfid = le16_to_cpu(buf[0]);
- prodid = le16_to_cpu(buf[1]);
+ for (base = 0x000; base < 0x400; base += 0x20) {
+ p_dev->io.BasePort1 = base;
+ ret = pcmcia_request_io(p_dev, &p_dev->io);
+ if (!ret)
+ return 0;
}
- /* printk("manfid = 0x%04x, 0x%04x\n",manfid,prodid); */
+ return -ENODEV;
+}
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- tuple.Attributes = 0;
- ret = pcmcia_get_first_tuple(link, &tuple);
- ret = pcmcia_get_tuple_data(link, &tuple);
- ret = pcmcia_parse_tuple(&tuple, &parse);
-#if 0
- printk(" index: 0x%x\n", parse.cftable_entry.index);
- printk(" flags: 0x%x\n", parse.cftable_entry.flags);
- printk(" io flags: 0x%x\n", parse.cftable_entry.io.flags);
- printk(" io nwin: 0x%x\n", parse.cftable_entry.io.nwin);
- printk(" io base: 0x%x\n", parse.cftable_entry.io.win[0].base);
- printk(" io len: 0x%x\n", parse.cftable_entry.io.win[0].len);
- printk(" irq1: 0x%x\n", parse.cftable_entry.irq.IRQInfo1);
- printk(" irq2: 0x%x\n", parse.cftable_entry.irq.IRQInfo2);
- printk(" mem flags: 0x%x\n", parse.cftable_entry.mem.flags);
- printk(" mem nwin: 0x%x\n", parse.cftable_entry.mem.nwin);
- printk(" subtuples: 0x%x\n", parse.cftable_entry.subtuples);
-#endif
+static void mio_cs_config(struct pcmcia_device *link)
+{
+ int ret;
-#if 0
- link->io.NumPorts1 = 0x20;
- link->io.IOAddrLines = 5;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-#endif
- link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
- link->io.IOAddrLines =
- parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK;
- link->io.NumPorts2 = 0;
+ DPRINTK("mio_cs_config(link=%p)\n", link);
- {
- int base;
- for (base = 0x000; base < 0x400; base += 0x20) {
- link->io.BasePort1 = base;
- ret = pcmcia_request_io(link, &link->io);
- /* printk("RequestIO 0x%02x\n",ret); */
- if (!ret)
- break;
- }
+ ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL);
+ if (ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ return;
}
- link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
- link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2;
ret = pcmcia_request_irq(link, &link->irq);
if (ret) {
printk("pcmcia_request_irq() returned error: %i\n", ret);
}
- /* printk("RequestIRQ 0x%02x\n",ret); */
-
- link->conf.ConfigIndex = 1;
ret = pcmcia_request_configuration(link, &link->conf);
- /* printk("RequestConfiguration %d\n",ret); */
link->dev_node = &dev_node;
}
@@ -475,40 +425,17 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
-{
- tuple_t tuple;
- u_short buf[128];
- int prodid = 0;
-
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.DesiredTuple = CISTPL_MANFID;
- tuple.Attributes = TUPLE_RETURN_COMMON;
- if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
- (pcmcia_get_tuple_data(link, &tuple) == 0)) {
- prodid = le16_to_cpu(buf[1]);
- }
-
- return prodid;
-}
-
static int ni_getboardtype(struct comedi_device *dev,
struct pcmcia_device *link)
{
- int id;
int i;
- id = get_prodid(dev, link);
-
for (i = 0; i < n_ni_boards; i++) {
- if (ni_boards[i].device_id == id) {
+ if (ni_boards[i].device_id == link->card_id)
return i;
- }
}
- printk("unknown board 0x%04x -- pretend it is a ", id);
+ printk("unknown board 0x%04x -- pretend it is a ", link->card_id);
return 0;
}
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 52b2eca9e73d..d544698f2414 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -70,6 +70,7 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
/* #define DEBUG_FLAGS */
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include "../comedidev.h"
#include "mite.h"
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index 344b82353e08..5256fd933162 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -55,23 +55,6 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "quatech_daqp_cs.c 1.10 2003/04/21 (Brent Baccala)";
-#else
-#define DEBUG(n, args...)
-#endif
-
/* Maximum number of separate DAQP devices we'll allow */
#define MAX_DEV 4
@@ -863,8 +846,6 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int ret;
struct local_info_t *local = dev_table[it->options[0]];
- tuple_t tuple;
- int i;
struct comedi_subdevice *s;
if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) {
@@ -883,29 +864,10 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
strcpy(local->board_name, "DAQP");
dev->board_name = local->board_name;
-
- tuple.DesiredTuple = CISTPL_VERS_1;
- if (pcmcia_get_first_tuple(local->link, &tuple) == 0) {
- u_char buf[128];
-
- buf[0] = buf[sizeof(buf) - 1] = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 2;
- if (pcmcia_get_tuple_data(local->link, &tuple) == 0) {
-
- for (i = 0; i < tuple.TupleDataLen - 4; i++)
- if (buf[i] == 0)
- break;
- for (i++; i < tuple.TupleDataLen - 4; i++)
- if (buf[i] == 0)
- break;
- i++;
- if ((i < tuple.TupleDataLen - 4)
- && (strncmp(buf + i, "DAQP", 4) == 0)) {
- strncpy(local->board_name, buf + i,
- sizeof(local->board_name));
- }
+ if (local->link->prod_id[2]) {
+ if (strncmp(local->link->prod_id[2], "DAQP", 4) == 0) {
+ strncpy(local->board_name, local->link->prod_id[2],
+ sizeof(local->board_name));
}
}
@@ -1058,7 +1020,7 @@ static int daqp_cs_attach(struct pcmcia_device *link)
struct local_info_t *local;
int i;
- DEBUG(0, "daqp_cs_attach()\n");
+ dev_dbg(&link->dev, "daqp_cs_attach()\n");
for (i = 0; i < MAX_DEV; i++)
if (dev_table[i] == NULL)
@@ -1079,10 +1041,8 @@ static int daqp_cs_attach(struct pcmcia_device *link)
link->priv = local;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = daqp_interrupt;
- link->irq.Instance = local;
/*
General socket configuration defaults can go here. In this
@@ -1112,7 +1072,7 @@ static void daqp_cs_detach(struct pcmcia_device *link)
{
struct local_info_t *dev = link->priv;
- DEBUG(0, "daqp_cs_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "daqp_cs_detach\n");
if (link->dev_node) {
dev->stop = 1;
@@ -1134,115 +1094,54 @@ static void daqp_cs_detach(struct pcmcia_device *link)
======================================================================*/
-static void daqp_cs_config(struct pcmcia_device *link)
-{
- struct local_info_t *dev = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_ret;
- u_char buf[64];
-
- DEBUG(0, "daqp_cs_config(0x%p)\n", link);
-
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetFirstTuple, last_ret);
- goto cs_failed;
- }
- last_ret = pcmcia_get_tuple_data(link, &tuple);
- if (last_ret) {
- cs_error(link, GetTupleData, last_ret);
- goto cs_failed;
- }
-
- last_ret = pcmcia_parse_tuple(&tuple, &parse);
- if (last_ret) {
- cs_error(link, ParseTuple, last_ret);
- goto cs_failed;
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->index == 0)
+ return -ENODEV;
- /*
- In this loop, we scan the CIS for configuration table entries,
- each of which describes a valid card configuration, including
- voltage, IO window, memory window, and interrupt settings.
-
- We make no assumptions about the card to be configured: we use
- just the information available in the CIS. In an ideal world,
- this would work for any PCMCIA card, but it requires a complete
- and accurate CIS. In practice, a driver usually "knows" most of
- these things without consulting the CIS, and most client drivers
- will only use the CIS to fill in implementation-defined details.
- */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetFirstTuple, last_ret);
- goto cs_failed;
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
}
- while (1) {
- cistpl_cftable_entry_t dflt = { 0 };
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
- if (pcmcia_get_tuple_data(link, &tuple))
- goto next_entry;
- if (pcmcia_parse_tuple(&tuple, &parse))
- goto next_entry;
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
- dflt = *cfg;
- if (cfg->index == 0)
- goto next_entry;
- link->conf.ConfigIndex = cfg->index;
-
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = link->io.NumPorts2 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- if (io->nwin > 1) {
- link->io.Attributes2 = link->io.Attributes1;
- link->io.BasePort2 = io->win[1].base;
- link->io.NumPorts2 = io->win[1].len;
- }
- }
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+}
- /* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(link, &link->io))
- goto next_entry;
+static void daqp_cs_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ int ret;
- /* If we got this far, we're cool! */
- break;
+ dev_dbg(&link->dev, "daqp_cs_config\n");
-next_entry:
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- if (last_ret) {
- cs_error(link, GetNextTuple, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL);
+ if (ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto failed;
}
/*
@@ -1251,11 +1150,9 @@ next_entry:
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
- last_ret = pcmcia_request_irq(link, &link->irq);
- if (last_ret) {
- cs_error(link, RequestIRQ, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
}
/*
@@ -1263,11 +1160,9 @@ next_entry:
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- last_ret = pcmcia_request_configuration(link, &link->conf);
- if (last_ret) {
- cs_error(link, RequestConfiguration, last_ret);
- goto cs_failed;
- }
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*
At this point, the dev_node_t structure(s) need to be
@@ -1296,14 +1191,14 @@ next_entry:
return;
-cs_failed:
+failed:
daqp_cs_release(link);
} /* daqp_cs_config */
static void daqp_cs_release(struct pcmcia_device *link)
{
- DEBUG(0, "daqp_cs_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "daqp_cs_release\n");
pcmcia_disable_device(link);
} /* daqp_cs_release */
@@ -1363,7 +1258,6 @@ struct pcmcia_driver daqp_cs_driver = {
int __init init_module(void)
{
- DEBUG(0, "%s\n", version);
pcmcia_register_driver(&daqp_cs_driver);
comedi_driver_register(&driver_daqp);
return 0;
@@ -1371,7 +1265,6 @@ int __init init_module(void)
void __exit cleanup_module(void)
{
- DEBUG(0, "daqp_cs: unloading\n");
comedi_driver_unregister(&driver_daqp);
pcmcia_unregister_driver(&daqp_cs_driver);
}
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h
index 6294d3814e72..2c3d65a622a7 100644
--- a/drivers/staging/et131x/et1310_address_map.h
+++ b/drivers/staging/et131x/et1310_address_map.h
@@ -223,7 +223,7 @@ typedef union _TXDMA_PR_NUM_DES_t {
extern inline void add_10bit(u32 *v, int n)
{
- *v = INDEX10(*v + n);
+ *v = INDEX10(*v + n) | (*v & ET_DMA10_WRAP);
}
/*
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index 8f2e91fa0a86..10e21db57ac3 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -1177,12 +1177,20 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
static inline u32 bump_fbr(u32 *fbr, u32 limit)
{
- u32 v = *fbr;
- add_10bit(&v, 1);
- if (v > limit)
- v = (*fbr & ~ET_DMA10_MASK) ^ ET_DMA10_WRAP;
- *fbr = v;
- return v;
+ u32 v = *fbr;
+ v++;
+ /* This works for all cases where limit < 1024. The 1023 case
+ works because 1023++ is 1024 which means the if condition is not
+ taken but the carry of the bit into the wrap bit toggles the wrap
+ value correctly */
+ if ((v & ET_DMA10_MASK) > limit) {
+ v &= ~ET_DMA10_MASK;
+ v ^= ET_DMA10_WRAP;
+ }
+ /* For the 1023 case */
+ v &= (ET_DMA10_MASK|ET_DMA10_WRAP);
+ *fbr = v;
+ return v;
}
/**
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index 8c85a9c3665a..f4a6541c3e60 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -261,7 +261,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
memset(buf, 0xcd, 6);
usb = go->hpi_context;
- if (down_interruptible(&usb->i2c_lock) != 0) {
+ if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
printk(KERN_INFO "i2c lock failed\n");
kfree(buf);
return -EINTR;
@@ -270,7 +270,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
kfree(buf);
return -EFAULT;
}
- up(&usb->i2c_lock);
+ mutex_unlock(&usb->i2c_lock);
*val = (buf[0] << 8) | buf[1];
kfree(buf);
diff --git a/drivers/staging/go7007/s2250-loader.h b/drivers/staging/go7007/s2250-loader.h
new file mode 100644
index 000000000000..b7c301af16cc
--- /dev/null
+++ b/drivers/staging/go7007/s2250-loader.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef _S2250_LOADER_H_
+#define _S2250_LOADER_H_
+
+extern int s2250loader_init(void);
+extern void s2250loader_cleanup(void);
+
+#endif
diff --git a/drivers/staging/hv/BlkVsc.c b/drivers/staging/hv/BlkVsc.c
index 51aa861292fc..a48ee3a12646 100644
--- a/drivers/staging/hv/BlkVsc.c
+++ b/drivers/staging/hv/BlkVsc.c
@@ -16,6 +16,7 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*
*/
diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c
index d649ee169d95..746370e82115 100644
--- a/drivers/staging/hv/Channel.c
+++ b/drivers/staging/hv/Channel.c
@@ -611,7 +611,7 @@ void VmbusChannelClose(struct vmbus_channel *Channel)
/* Stop callback and cancel the timer asap */
Channel->OnChannelCallback = NULL;
- del_timer(&Channel->poll_timer);
+ del_timer_sync(&Channel->poll_timer);
/* Send a closing message */
info = kmalloc(sizeof(*info) +
@@ -978,14 +978,10 @@ void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel)
{
DumpVmbusChannel(Channel);
ASSERT(Channel->OnChannelCallback);
-#ifdef ENABLE_POLLING
- del_timer(&Channel->poll_timer);
- Channel->OnChannelCallback(Channel->ChannelCallbackContext);
- channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
- add_timer(&channel->poll_timer);
-#else
+
Channel->OnChannelCallback(Channel->ChannelCallbackContext);
-#endif
+
+ mod_timer(&Channel->poll_timer, jiffies + usecs_to_jiffies(100));
}
/**
@@ -997,10 +993,6 @@ void VmbusChannelOnTimer(unsigned long data)
if (channel->OnChannelCallback) {
channel->OnChannelCallback(channel->ChannelCallbackContext);
-#ifdef ENABLE_POLLING
- channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
- add_timer(&channel->poll_timer);
-#endif
}
}
diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c
index 3db62caedcff..ef38467ed4e2 100644
--- a/drivers/staging/hv/ChannelMgmt.c
+++ b/drivers/staging/hv/ChannelMgmt.c
@@ -119,7 +119,7 @@ static inline void ReleaseVmbusChannel(void *context)
*/
void FreeVmbusChannel(struct vmbus_channel *Channel)
{
- del_timer(&Channel->poll_timer);
+ del_timer_sync(&Channel->poll_timer);
/*
* We have to release the channel's workqueue/thread in the vmbus's
diff --git a/drivers/staging/hv/ChannelMgmt.h b/drivers/staging/hv/ChannelMgmt.h
index a839d8fe6cec..fa973d86b624 100644
--- a/drivers/staging/hv/ChannelMgmt.h
+++ b/drivers/staging/hv/ChannelMgmt.h
@@ -26,6 +26,7 @@
#define _CHANNEL_MGMT_H_
#include <linux/list.h>
+#include <linux/timer.h>
#include "RingBuffer.h"
#include "VmbusChannelInterface.h"
#include "VmbusPacketFormat.h"
@@ -54,7 +55,7 @@ enum vmbus_channel_message_type {
ChannelMessageViewRangeRemove = 18,
#endif
ChannelMessageCount
-} __attribute__((packed));
+};
struct vmbus_channel_message_header {
enum vmbus_channel_message_type MessageType;
diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c
index 1610b845198f..1c717f9a554e 100644
--- a/drivers/staging/hv/NetVsc.c
+++ b/drivers/staging/hv/NetVsc.c
@@ -15,6 +15,7 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*/
#include <linux/kernel.h>
@@ -1052,7 +1053,7 @@ static void NetVscOnReceive(struct hv_device *Device,
*/
spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
while (!list_empty(&netDevice->ReceivePacketList)) {
- list_move_tail(&netDevice->ReceivePacketList, &listHead);
+ list_move_tail(netDevice->ReceivePacketList.next, &listHead);
if (++count == vmxferpagePacket->RangeCount + 1)
break;
}
@@ -1071,7 +1072,7 @@ static void NetVscOnReceive(struct hv_device *Device,
/* Return it to the freelist */
spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
for (i = count; i != 0; i--) {
- list_move_tail(&listHead,
+ list_move_tail(listHead.next,
&netDevice->ReceivePacketList);
}
spin_unlock_irqrestore(&netDevice->receive_packet_list_lock,
@@ -1085,8 +1086,7 @@ static void NetVscOnReceive(struct hv_device *Device,
}
/* Remove the 1st packet to represent the xfer page packet itself */
- xferpagePacket = list_entry(&listHead, struct xferpage_packet,
- ListEntry);
+ xferpagePacket = (struct xferpage_packet*)listHead.next;
list_del(&xferpagePacket->ListEntry);
/* This is how much we can satisfy */
@@ -1102,8 +1102,7 @@ static void NetVscOnReceive(struct hv_device *Device,
/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
for (i = 0; i < (count - 1); i++) {
- netvscPacket = list_entry(&listHead, struct hv_netvsc_packet,
- ListEntry);
+ netvscPacket = (struct hv_netvsc_packet*)listHead.next;
list_del(&netvscPacket->ListEntry);
/* Initialize the netvsc packet */
diff --git a/drivers/staging/hv/NetVsc.h b/drivers/staging/hv/NetVsc.h
index 3e7112f7c755..6e0e03494126 100644
--- a/drivers/staging/hv/NetVsc.h
+++ b/drivers/staging/hv/NetVsc.h
@@ -16,6 +16,7 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*
*/
diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c
index 14015c927940..2f7c425896f7 100644
--- a/drivers/staging/hv/StorVsc.c
+++ b/drivers/staging/hv/StorVsc.c
@@ -196,7 +196,7 @@ static int StorVscChannelInit(struct hv_device *Device)
* Now, initiate the vsc/vsp initialization protocol on the open
* channel
*/
- memset(request, sizeof(struct storvsc_request_extension), 0);
+ memset(request, 0, sizeof(struct storvsc_request_extension));
request->WaitEvent = osd_WaitEventCreate();
vstorPacket->Operation = VStorOperationBeginInitialization;
@@ -233,7 +233,7 @@ static int StorVscChannelInit(struct hv_device *Device)
DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION...");
/* reuse the packet for version range supported */
- memset(vstorPacket, sizeof(struct vstor_packet), 0);
+ memset(vstorPacket, 0, sizeof(struct vstor_packet));
vstorPacket->Operation = VStorOperationQueryProtocolVersion;
vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
@@ -266,7 +266,7 @@ static int StorVscChannelInit(struct hv_device *Device)
/* Query channel properties */
DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION...");
- memset(vstorPacket, sizeof(struct vstor_packet), 0);
+ memset(vstorPacket, 0, sizeof(struct vstor_packet));
vstorPacket->Operation = VStorOperationQueryProperties;
vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
vstorPacket->StorageChannelProperties.PortNumber =
@@ -305,7 +305,7 @@ static int StorVscChannelInit(struct hv_device *Device)
DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION...");
- memset(vstorPacket, sizeof(struct vstor_packet), 0);
+ memset(vstorPacket, 0, sizeof(struct vstor_packet));
vstorPacket->Operation = VStorOperationEndInitialization;
vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
@@ -508,7 +508,7 @@ static int StorVscConnectToVsp(struct hv_device *Device)
int ret;
storDriver = (struct storvsc_driver_object *)Device->Driver;
- memset(&props, sizeof(struct vmstorage_channel_properties), 0);
+ memset(&props, 0, sizeof(struct vmstorage_channel_properties));
/* Open the channel */
ret = Device->Driver->VmbusChannelInterface.Open(Device,
diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO
index 4d390b237742..dbfbde937a66 100644
--- a/drivers/staging/hv/TODO
+++ b/drivers/staging/hv/TODO
@@ -1,11 +1,17 @@
TODO:
- fix remaining checkpatch warnings and errors
+ - use of /** when it is not a kerneldoc header
- remove RingBuffer.c to us in-kernel ringbuffer functions instead.
- audit the vmbus to verify it is working properly with the
driver model
+ - convert vmbus driver interface function pointer tables
+ to constant, a.k.a vmbus_ops
- see if the vmbus can be merged with the other virtual busses
in the kernel
- audit the network driver
+ - use existing net_device_stats struct in network device
+ - checking for carrier inside open is wrong, network device API
+ confusion??
- audit the block driver
- audit the scsi driver
diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c
index 99c49261a8b4..62b282844a53 100644
--- a/drivers/staging/hv/blkvsc_drv.c
+++ b/drivers/staging/hv/blkvsc_drv.c
@@ -15,6 +15,7 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*/
#include <linux/init.h>
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index 3192d50f7251..0d7459e2d036 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -15,6 +15,7 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*/
#include <linux/init.h>
diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c
index 8fe543bd9910..3a4793a0fd05 100644
--- a/drivers/staging/hv/osd.c
+++ b/drivers/staging/hv/osd.c
@@ -30,6 +30,7 @@
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
diff --git a/drivers/staging/hv/osd.h b/drivers/staging/hv/osd.h
index 9504604c72bd..ce064e8ea644 100644
--- a/drivers/staging/hv/osd.h
+++ b/drivers/staging/hv/osd.h
@@ -25,6 +25,7 @@
#ifndef _OSD_H_
#define _OSD_H_
+#include <linux/workqueue.h>
/* Defines */
#define ALIGN_UP(value, align) (((value) & (align-1)) ? \
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 582318f10222..894eecfc63ca 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -507,12 +507,12 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
child_device_obj = &child_device_ctx->device_obj;
child_device_obj->context = context;
- memcpy(&child_device_obj->deviceType, &type, sizeof(struct hv_guid));
- memcpy(&child_device_obj->deviceInstance, &instance,
+ memcpy(&child_device_obj->deviceType, type, sizeof(struct hv_guid));
+ memcpy(&child_device_obj->deviceInstance, instance,
sizeof(struct hv_guid));
- memcpy(&child_device_ctx->class_id, &type, sizeof(struct hv_guid));
- memcpy(&child_device_ctx->device_id, &instance, sizeof(struct hv_guid));
+ memcpy(&child_device_ctx->class_id, type, sizeof(struct hv_guid));
+ memcpy(&child_device_ctx->device_id, instance, sizeof(struct hv_guid));
DPRINT_EXIT(VMBUS_DRV);
@@ -537,18 +537,7 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
DPRINT_DBG(VMBUS_DRV, "child device (%p) registering",
child_device_ctx);
- /* Make sure we are not registered already */
- if (strlen(dev_name(&child_device_ctx->device)) != 0) {
- DPRINT_ERR(VMBUS_DRV,
- "child device (%p) already registered - busid %s",
- child_device_ctx,
- dev_name(&child_device_ctx->device));
-
- ret = -1;
- goto Cleanup;
- }
-
- /* Set the device bus id. Otherwise, device_register()will fail. */
+ /* Set the device name. Otherwise, device_register() will fail. */
dev_set_name(&child_device_ctx->device, "vmbus_0_%d",
atomic_inc_return(&device_num));
@@ -573,7 +562,6 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
DPRINT_INFO(VMBUS_DRV, "child device (%p) registered",
&child_device_ctx->device);
-Cleanup:
DPRINT_EXIT(VMBUS_DRV);
return ret;
@@ -623,8 +611,6 @@ static void vmbus_child_device_destroy(struct hv_device *device_obj)
static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
{
struct device_context *device_ctx = device_to_device_context(device);
- int i = 0;
- int len = 0;
int ret;
DPRINT_ENTER(VMBUS_DRV);
@@ -644,8 +630,6 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
device_ctx->class_id.data[14],
device_ctx->class_id.data[15]);
- env->envp_idx = i;
- env->buflen = len;
ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x%02x%02x%02x%02x%02x%02x}",
@@ -691,8 +675,6 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
if (ret)
return ret;
- env->envp[env->envp_idx] = NULL;
-
DPRINT_EXIT(VMBUS_DRV);
return 0;
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 1fa18f255814..768f44894d08 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -18,6 +18,8 @@
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
#include <linux/cdev.h>
#include "iio.h"
#include "trigger_consumer.h"
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 42230e62a222..31a58e508924 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -170,7 +170,7 @@ static u32 cvm_oct_get_link(struct net_device *dev)
return ret;
}
-struct const ethtool_ops cvm_oct_ethtool_ops = {
+const struct ethtool_ops cvm_oct_ethtool_ops = {
.get_drvinfo = cvm_oct_get_drvinfo,
.get_settings = cvm_oct_get_settings,
.set_settings = cvm_oct_set_settings,
diff --git a/drivers/staging/octeon/ethernet-spi.c b/drivers/staging/octeon/ethernet-spi.c
index 66190b0cb68f..00dc0f4bad19 100644
--- a/drivers/staging/octeon/ethernet-spi.c
+++ b/drivers/staging/octeon/ethernet-spi.c
@@ -317,6 +317,6 @@ void cvm_oct_spi_uninit(struct net_device *dev)
cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
}
- free_irq(8 + 46, &number_spi_ports);
+ free_irq(OCTEON_IRQ_RML, &number_spi_ports);
}
}
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index b8479517dce2..492c5029992d 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -111,6 +111,16 @@ MODULE_PARM_DESC(disable_core_queueing, "\n"
"\tallows packets to be sent without lock contention in the packet\n"
"\tscheduler resulting in some cases in improved throughput.\n");
+
+/*
+ * The offset from mac_addr_base that should be used for the next port
+ * that is configured. By convention, if any mgmt ports exist on the
+ * chip, they get the first mac addresses, The ports controlled by
+ * this driver are numbered sequencially following any mgmt addresses
+ * that may exist.
+ */
+static unsigned int cvm_oct_mac_addr_offset;
+
/**
* Periodic timer to check auto negotiation
*/
@@ -474,16 +484,30 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
*/
int cvm_oct_common_init(struct net_device *dev)
{
- static int count;
- char mac[8] = { 0x00, 0x00,
- octeon_bootinfo->mac_addr_base[0],
- octeon_bootinfo->mac_addr_base[1],
- octeon_bootinfo->mac_addr_base[2],
- octeon_bootinfo->mac_addr_base[3],
- octeon_bootinfo->mac_addr_base[4],
- octeon_bootinfo->mac_addr_base[5] + count
- };
struct octeon_ethernet *priv = netdev_priv(dev);
+ struct sockaddr sa;
+ u64 mac = ((u64)(octeon_bootinfo->mac_addr_base[0] & 0xff) << 40) |
+ ((u64)(octeon_bootinfo->mac_addr_base[1] & 0xff) << 32) |
+ ((u64)(octeon_bootinfo->mac_addr_base[2] & 0xff) << 24) |
+ ((u64)(octeon_bootinfo->mac_addr_base[3] & 0xff) << 16) |
+ ((u64)(octeon_bootinfo->mac_addr_base[4] & 0xff) << 8) |
+ (u64)(octeon_bootinfo->mac_addr_base[5] & 0xff);
+
+ mac += cvm_oct_mac_addr_offset;
+ sa.sa_data[0] = (mac >> 40) & 0xff;
+ sa.sa_data[1] = (mac >> 32) & 0xff;
+ sa.sa_data[2] = (mac >> 24) & 0xff;
+ sa.sa_data[3] = (mac >> 16) & 0xff;
+ sa.sa_data[4] = (mac >> 8) & 0xff;
+ sa.sa_data[5] = mac & 0xff;
+
+ if (cvm_oct_mac_addr_offset >= octeon_bootinfo->mac_addr_count)
+ printk(KERN_DEBUG "%s: Using MAC outside of the assigned range:"
+ " %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+ sa.sa_data[0] & 0xff, sa.sa_data[1] & 0xff,
+ sa.sa_data[2] & 0xff, sa.sa_data[3] & 0xff,
+ sa.sa_data[4] & 0xff, sa.sa_data[5] & 0xff);
+ cvm_oct_mac_addr_offset++;
/*
* Force the interface to use the POW send if always_use_pow
@@ -496,14 +520,12 @@ int cvm_oct_common_init(struct net_device *dev)
if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM)
dev->features |= NETIF_F_IP_CSUM;
- count++;
-
/* We do our own locking, Linux doesn't need to */
dev->features |= NETIF_F_LLTX;
SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
cvm_oct_mdio_setup_device(dev);
- dev->netdev_ops->ndo_set_mac_address(dev, mac);
+ dev->netdev_ops->ndo_set_mac_address(dev, &sa);
dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
/*
@@ -620,6 +642,13 @@ static int __init cvm_oct_init_module(void)
pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+ cvm_oct_mac_addr_offset = 2; /* First two are the mgmt ports. */
+ else if (OCTEON_IS_MODEL(OCTEON_CN56XX))
+ cvm_oct_mac_addr_offset = 1; /* First one is the mgmt port. */
+ else
+ cvm_oct_mac_addr_offset = 0;
+
cvm_oct_proc_initialize();
cvm_oct_rx_initialize();
cvm_oct_configure_common_hw();
diff --git a/drivers/staging/otus/Kconfig b/drivers/staging/otus/Kconfig
index d549d08fd495..f6cc2625e341 100644
--- a/drivers/staging/otus/Kconfig
+++ b/drivers/staging/otus/Kconfig
@@ -1,6 +1,6 @@
config OTUS
tristate "Atheros OTUS 802.11n USB wireless support"
- depends on USB && WLAN_80211 && MAC80211
+ depends on USB && WLAN && MAC80211
default N
---help---
Enable support for Atheros 802.11n USB hardware:
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index dd7d3fde9699..4ce399b6d237 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -2071,11 +2071,15 @@ static void panel_detach(struct parport *port)
return;
}
- if (keypad_enabled && keypad_initialized)
+ if (keypad_enabled && keypad_initialized) {
misc_deregister(&keypad_dev);
+ keypad_initialized = 0;
+ }
- if (lcd_enabled && lcd_initialized)
+ if (lcd_enabled && lcd_initialized) {
misc_deregister(&lcd_dev);
+ lcd_initialized = 0;
+ }
parport_release(pprt);
parport_unregister_device(pprt);
@@ -2211,13 +2215,16 @@ static void __exit panel_cleanup_module(void)
del_timer(&scan_timer);
if (pprt != NULL) {
- if (keypad_enabled)
+ if (keypad_enabled) {
misc_deregister(&keypad_dev);
+ keypad_initialized = 0;
+ }
if (lcd_enabled) {
panel_lcd_print("\x0cLCD driver " PANEL_VERSION
"\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
misc_deregister(&lcd_dev);
+ lcd_initialized = 0;
}
/* TODO: free all input signals */
diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c
index 0d111ddfabb2..2eb8e3d43c4d 100644
--- a/drivers/staging/poch/poch.c
+++ b/drivers/staging/poch/poch.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/ioctl.h>
#include <linux/io.h>
+#include <linux/sched.h>
#include "poch.h"
diff --git a/drivers/staging/rt2860/Kconfig b/drivers/staging/rt2860/Kconfig
index 7f44e5e72463..efe38e25c5ed 100644
--- a/drivers/staging/rt2860/Kconfig
+++ b/drivers/staging/rt2860/Kconfig
@@ -1,5 +1,5 @@
config RT2860
tristate "Ralink 2860 wireless support"
- depends on PCI && X86 && WLAN_80211
+ depends on PCI && X86 && WLAN
---help---
This is an experimental driver for the Ralink 2860 wireless chip.
diff --git a/drivers/staging/rt2860/common/cmm_data_2860.c b/drivers/staging/rt2860/common/cmm_data_2860.c
index fb1735533b74..857ff450b6c9 100644
--- a/drivers/staging/rt2860/common/cmm_data_2860.c
+++ b/drivers/staging/rt2860/common/cmm_data_2860.c
@@ -363,6 +363,8 @@ int RtmpPCIMgmtKickOut(
ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
+ if (!pTxD)
+ return 0;
pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
index 9d589c240ed0..019cc4474ce8 100644
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -25,6 +25,7 @@
*************************************************************************
*/
+#include <linux/sched.h>
#include "../rt_config.h"
INT Show_SSID_Proc(
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index b396a9b570e2..ed27b8545a1b 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -25,6 +25,7 @@
*************************************************************************
*/
+#include <linux/sched.h>
#include "rt_config.h"
ULONG RTDebugLevel = RT_DEBUG_ERROR;
diff --git a/drivers/staging/rt2870/Kconfig b/drivers/staging/rt2870/Kconfig
index 76841f6dea93..aea5c8221810 100644
--- a/drivers/staging/rt2870/Kconfig
+++ b/drivers/staging/rt2870/Kconfig
@@ -1,5 +1,5 @@
config RT2870
tristate "Ralink 2870/3070 wireless support"
- depends on USB && X86 && WLAN_80211
+ depends on USB && X86 && WLAN
---help---
This is an experimental driver for the Ralink xx70 wireless chips.
diff --git a/drivers/staging/rt3090/Kconfig b/drivers/staging/rt3090/Kconfig
index 255e8eaa4836..2b3f745d72b7 100644
--- a/drivers/staging/rt3090/Kconfig
+++ b/drivers/staging/rt3090/Kconfig
@@ -1,5 +1,5 @@
config RT3090
tristate "Ralink 3090 wireless support"
- depends on PCI && X86 && WLAN_80211
+ depends on PCI && X86 && WLAN
---help---
This is an experimental driver for the Ralink 3090 wireless chip.
diff --git a/drivers/staging/rt3090/common/cmm_info.c b/drivers/staging/rt3090/common/cmm_info.c
index 5be0714666cb..3e51e98b474c 100644
--- a/drivers/staging/rt3090/common/cmm_info.c
+++ b/drivers/staging/rt3090/common/cmm_info.c
@@ -34,6 +34,7 @@
--------- ---------- ----------------------------------------------
*/
+#include <linux/sched.h>
#include "../rt_config.h"
diff --git a/drivers/staging/rt3090/rt_linux.c b/drivers/staging/rt3090/rt_linux.c
index d2241ecdf583..9b94aa6eb904 100644
--- a/drivers/staging/rt3090/rt_linux.c
+++ b/drivers/staging/rt3090/rt_linux.c
@@ -25,6 +25,7 @@
*************************************************************************
*/
+#include <linux/sched.h>
#include "rt_config.h"
ULONG RTDebugLevel = RT_DEBUG_ERROR;
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig
index 236e42725447..203c79b8180f 100644
--- a/drivers/staging/rtl8187se/Kconfig
+++ b/drivers/staging/rtl8187se/Kconfig
@@ -1,6 +1,6 @@
config RTL8187SE
tristate "RealTek RTL8187SE Wireless LAN NIC driver"
- depends on PCI
+ depends on PCI && WLAN
depends on WIRELESS_EXT
default N
---help---
diff --git a/drivers/staging/rtl8187se/TODO b/drivers/staging/rtl8187se/TODO
index c09a9160739d..a762e79873e9 100644
--- a/drivers/staging/rtl8187se/TODO
+++ b/drivers/staging/rtl8187se/TODO
@@ -11,5 +11,4 @@ TODO:
- sparse fixes
- integrate with drivers/net/wireless/rtl818x
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
-Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
index 013c3e19ae25..4c5d63fd5833 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
@@ -53,10 +53,8 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
list_del(ptr);
- if (entry->ops) {
+ if (entry->ops)
entry->ops->deinit(entry->priv);
- module_put(entry->ops->owner);
- }
kfree(entry);
}
}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
index 6fbe4890cb66..18392fce487d 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
@@ -189,10 +189,8 @@ void free_ieee80211(struct net_device *dev)
for (i = 0; i < WEP_KEYS; i++) {
struct ieee80211_crypt_data *crypt = ieee->crypt[i];
if (crypt) {
- if (crypt->ops) {
+ if (crypt->ops)
crypt->ops->deinit(crypt->priv);
- module_put(crypt->ops->owner);
- }
kfree(crypt);
ieee->crypt[i] = NULL;
}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
index 59b2ab48cdcf..334e4c7ec61b 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -2839,16 +2839,12 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
goto skip_host_crypt;
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
- request_module("ieee80211_crypt_wep");
+ if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
- request_module("ieee80211_crypt_tkip");
+ else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
- request_module("ieee80211_crypt_ccmp");
+ else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- }
if (ops == NULL) {
printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
@@ -2869,7 +2865,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
}
memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ops;
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+ if (new_crypt->ops)
new_crypt->priv =
new_crypt->ops->init(param->u.crypt.idx);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
index 8d8bdd0a130e..a08b97a09512 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
@@ -331,12 +331,10 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
return -ENOMEM;
memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- if (!new_crypt->ops) {
- request_module("ieee80211_crypt_wep");
+ if (!new_crypt->ops)
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- }
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+ if (new_crypt->ops)
new_crypt->priv = new_crypt->ops->init(key);
if (!new_crypt->ops || !new_crypt->priv) {
@@ -483,7 +481,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int i, idx, ret = 0;
int group_key = 0;
- const char *alg, *module;
+ const char *alg;
struct ieee80211_crypto_ops *ops;
struct ieee80211_crypt_data **crypt;
@@ -539,15 +537,12 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
switch (ext->alg) {
case IW_ENCODE_ALG_WEP:
alg = "WEP";
- module = "ieee80211_crypt_wep";
break;
case IW_ENCODE_ALG_TKIP:
alg = "TKIP";
- module = "ieee80211_crypt_tkip";
break;
case IW_ENCODE_ALG_CCMP:
alg = "CCMP";
- module = "ieee80211_crypt_ccmp";
break;
default:
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -558,10 +553,8 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
// printk("8-09-08-9=====>%s, alg name:%s\n",__func__, alg);
ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL) {
- request_module(module);
+ if (ops == NULL)
ops = ieee80211_get_crypto_ops(alg);
- }
if (ops == NULL) {
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
dev->name, ext->alg);
@@ -581,7 +574,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
goto done;
}
new_crypt->ops = ops;
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+ if (new_crypt->ops)
new_crypt->priv = new_crypt->ops->init(idx);
if (new_crypt->priv == NULL) {
kfree(new_crypt);
diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig
index 3100aa58c940..37e4fde45073 100644
--- a/drivers/staging/rtl8192e/Kconfig
+++ b/drivers/staging/rtl8192e/Kconfig
@@ -1,6 +1,6 @@
config RTL8192E
tristate "RealTek RTL8192E Wireless LAN NIC driver"
- depends on PCI
+ depends on PCI && WLAN
depends on WIRELESS_EXT
default N
---help---
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
index 1a8ea8a40c3c..b1c54932da3e 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
@@ -53,14 +53,8 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
list_del(ptr);
- if (entry->ops) {
+ if (entry->ops)
entry->ops->deinit(entry->priv);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- module_put(entry->ops->owner);
-#else
- __MOD_DEC_USE_COUNT(entry->ops->owner);
-#endif
- }
kfree(entry);
}
}
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
index 16256a31f993..12c2a18e1fa2 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
@@ -242,14 +242,8 @@ void free_ieee80211(struct net_device *dev)
for (i = 0; i < WEP_KEYS; i++) {
struct ieee80211_crypt_data *crypt = ieee->crypt[i];
if (crypt) {
- if (crypt->ops) {
+ if (crypt->ops)
crypt->ops->deinit(crypt->priv);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- module_put(crypt->ops->owner);
-#else
- __MOD_DEC_USE_COUNT(crypt->ops->owner);
-#endif
- }
kfree(crypt);
ieee->crypt[i] = NULL;
}
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
index 2fc04df872ca..eae7c4579a68 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
@@ -3284,17 +3284,14 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
goto skip_host_crypt;
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
- request_module("ieee80211_crypt_wep");
+ if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
- } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
- request_module("ieee80211_crypt_tkip");
+ /* set WEP40 first, it will be modified according to WEP104 or
+ * WEP40 at other place */
+ else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
- request_module("ieee80211_crypt_ccmp");
+ else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- }
if (ops == NULL) {
printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
@@ -3315,11 +3312,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
}
memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ops;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
-#else
- if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
-#endif
+ if (new_crypt->ops)
new_crypt->priv =
new_crypt->ops->init(param->u.crypt.idx);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
index 223483126b0e..4e34a1f4c66b 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
@@ -482,15 +482,9 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
return -ENOMEM;
memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- if (!new_crypt->ops) {
- request_module("ieee80211_crypt_wep");
+ if (!new_crypt->ops)
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
-#else
- if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
-#endif
+ if (new_crypt->ops)
new_crypt->priv = new_crypt->ops->init(key);
if (!new_crypt->ops || !new_crypt->priv) {
@@ -644,7 +638,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int i, idx;
int group_key = 0;
- const char *alg, *module;
+ const char *alg;
struct ieee80211_crypto_ops *ops;
struct ieee80211_crypt_data **crypt;
@@ -711,15 +705,12 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
switch (ext->alg) {
case IW_ENCODE_ALG_WEP:
alg = "WEP";
- module = "ieee80211_crypt_wep";
break;
case IW_ENCODE_ALG_TKIP:
alg = "TKIP";
- module = "ieee80211_crypt_tkip";
break;
case IW_ENCODE_ALG_CCMP:
alg = "CCMP";
- module = "ieee80211_crypt_ccmp";
break;
default:
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -730,10 +721,8 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
printk("alg name:%s\n",alg);
ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL) {
- request_module(module);
+ if (ops == NULL)
ops = ieee80211_get_crypto_ops(alg);
- }
if (ops == NULL) {
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
dev->name, ext->alg);
@@ -758,7 +747,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
goto done;
}
new_crypt->ops = ops;
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+ if (new_crypt->ops)
new_crypt->priv = new_crypt->ops->init(idx);
if (new_crypt->priv == NULL) {
kfree(new_crypt);
diff --git a/drivers/staging/rtl8192su/Kconfig b/drivers/staging/rtl8192su/Kconfig
index 770f41280f21..b8c95f942069 100644
--- a/drivers/staging/rtl8192su/Kconfig
+++ b/drivers/staging/rtl8192su/Kconfig
@@ -1,6 +1,6 @@
config RTL8192SU
tristate "RealTek RTL8192SU Wireless LAN NIC driver"
- depends on PCI
+ depends on PCI && WLAN
depends on WIRELESS_EXT
default N
---help---
diff --git a/drivers/staging/rtl8192su/TODO b/drivers/staging/rtl8192su/TODO
index b13be9edb278..f11eec700030 100644
--- a/drivers/staging/rtl8192su/TODO
+++ b/drivers/staging/rtl8192su/TODO
@@ -14,5 +14,4 @@ TODO:
- sparse fixes
- integrate with drivers/net/wireless/rtl818x
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
-Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
index d76a54d59d2f..521e7b989934 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
@@ -53,10 +53,8 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
list_del(ptr);
- if (entry->ops) {
+ if (entry->ops)
entry->ops->deinit(entry->priv);
- module_put(entry->ops->owner);
- }
kfree(entry);
}
}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
index 68dc8fa094cc..c3383bb8b760 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
@@ -216,10 +216,8 @@ void free_ieee80211(struct net_device *dev)
for (i = 0; i < WEP_KEYS; i++) {
struct ieee80211_crypt_data *crypt = ieee->crypt[i];
if (crypt) {
- if (crypt->ops) {
+ if (crypt->ops)
crypt->ops->deinit(crypt->priv);
- module_put(crypt->ops->owner);
- }
kfree(crypt);
ieee->crypt[i] = NULL;
}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
index c64ae03f68a0..fd8e11252f1b 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
@@ -3026,17 +3026,14 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
goto skip_host_crypt;
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
- request_module("ieee80211_crypt_wep");
+ if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
- } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
- request_module("ieee80211_crypt_tkip");
+ /* set WEP40 first, it will be modified according to WEP104 or
+ * WEP40 at other place */
+ else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
- request_module("ieee80211_crypt_ccmp");
+ else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- }
if (ops == NULL) {
printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
@@ -3058,7 +3055,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ops;
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+ if (new_crypt->ops)
new_crypt->priv =
new_crypt->ops->init(param->u.crypt.idx);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
index 107759024335..6146c6435dde 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
@@ -358,11 +358,9 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
return -ENOMEM;
memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- if (!new_crypt->ops) {
- request_module("ieee80211_crypt_wep");
+ if (!new_crypt->ops)
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- }
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+ if (new_crypt->ops)
new_crypt->priv = new_crypt->ops->init(key);
if (!new_crypt->ops || !new_crypt->priv) {
@@ -507,7 +505,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int i, idx;
int group_key = 0;
- const char *alg, *module;
+ const char *alg;
struct ieee80211_crypto_ops *ops;
struct ieee80211_crypt_data **crypt;
@@ -570,15 +568,12 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
switch (ext->alg) {
case IW_ENCODE_ALG_WEP:
alg = "WEP";
- module = "ieee80211_crypt_wep";
break;
case IW_ENCODE_ALG_TKIP:
alg = "TKIP";
- module = "ieee80211_crypt_tkip";
break;
case IW_ENCODE_ALG_CCMP:
alg = "CCMP";
- module = "ieee80211_crypt_ccmp";
break;
default:
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -589,10 +584,8 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
printk("alg name:%s\n",alg);
ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL) {
- request_module("%s", module);
+ if (ops == NULL)
ops = ieee80211_get_crypto_ops(alg);
- }
if (ops == NULL) {
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
dev->name, ext->alg);
@@ -612,7 +605,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
goto done;
}
new_crypt->ops = ops;
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+ if (new_crypt->ops)
new_crypt->priv = new_crypt->ops->init(idx);
if (new_crypt->priv == NULL) {
kfree(new_crypt);
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
index 87f8a1192762..f890a16096c0 100644
--- a/drivers/staging/sep/sep_driver.c
+++ b/drivers/staging/sep/sep_driver.c
@@ -38,6 +38,7 @@
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/wait.h>
+#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/firmware.h>
#include <asm/ioctl.h>
diff --git a/drivers/staging/stlc45xx/Kconfig b/drivers/staging/stlc45xx/Kconfig
deleted file mode 100644
index 947fb75a9c68..000000000000
--- a/drivers/staging/stlc45xx/Kconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-config STLC45XX
- tristate "stlc4550/4560 support"
- depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS
- ---help---
- This is a driver for stlc4550 and stlc4560 chipsets.
-
- To compile this driver as a module, choose M here: the module will be
- called stlc45xx. If unsure, say N.
diff --git a/drivers/staging/stlc45xx/Makefile b/drivers/staging/stlc45xx/Makefile
deleted file mode 100644
index 7ee32903055a..000000000000
--- a/drivers/staging/stlc45xx/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_STLC45XX) += stlc45xx.o
diff --git a/drivers/staging/stlc45xx/stlc45xx.c b/drivers/staging/stlc45xx/stlc45xx.c
deleted file mode 100644
index be99eb33d817..000000000000
--- a/drivers/staging/stlc45xx/stlc45xx.c
+++ /dev/null
@@ -1,2594 +0,0 @@
-/*
- * This file is part of stlc45xx
- *
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Contact: Kalle Valo <kalle.valo@nokia.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.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "stlc45xx.h"
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/spi/spi.h>
-#include <linux/etherdevice.h>
-#include <linux/gpio.h>
-#include <linux/moduleparam.h>
-
-#include "stlc45xx_lmac.h"
-
-/*
- * gpios should be handled in board files and provided via platform data,
- * but because it's currently impossible for stlc45xx to have a header file
- * in include/linux, let's use module paramaters for now
- */
-static int stlc45xx_gpio_power = 97;
-module_param(stlc45xx_gpio_power, int, 0444);
-MODULE_PARM_DESC(stlc45xx_gpio_power, "stlc45xx gpio number for power line");
-
-static int stlc45xx_gpio_irq = 87;
-module_param(stlc45xx_gpio_irq, int, 0444);
-MODULE_PARM_DESC(stlc45xx_gpio_irq, "stlc45xx gpio number for irq line");
-
-static const u8 default_cal_channels[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x09,
- 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10,
- 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xe0, 0x00, 0xe0, 0x00,
- 0xe0, 0x00, 0xe0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
- 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
- 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
- 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9,
- 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00,
- 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
- 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
- 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
- 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d,
- 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa,
- 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
- 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17,
- 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
- 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00,
- 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00,
- 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
- 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x71, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8,
- 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
- 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0,
- 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6,
- 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00,
- 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
- 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
- 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
- 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca,
- 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4,
- 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
- 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21,
- 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
- 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00,
- 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00,
- 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
- 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0,
- 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
- 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
- 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01,
- 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0,
- 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
- 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
- 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
- 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37,
- 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc,
- 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
- 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b,
- 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
- 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00,
- 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00,
- 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
- 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0,
- 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
- 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a,
- 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
- 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
- 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x09, 0x00, 0x00, 0xc9, 0xff,
- 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
- 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
- 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab,
- 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb,
- 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
- 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33,
- 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
- 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00,
- 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00,
- 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
- 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0,
- 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
- 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7,
- 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
- 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
- 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d,
- 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00,
- 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00,
- 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00,
- 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
- 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42,
- 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
- 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01,
- 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00,
- 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
- 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0,
- 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
- 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0,
- 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
- 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
- 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17,
- 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00,
- 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
- 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
- 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
- 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x09, 0x00, 0x00, 0xc9,
- 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01,
- 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
- 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01,
- 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00,
- 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
- 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0,
- 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
- 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb,
- 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
- 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
- 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21,
- 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00,
- 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
- 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
- 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
- 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0,
- 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96,
- 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x8a, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00,
- 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0,
- 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
- 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0,
- 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
- 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22,
- 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
- 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
- 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b,
- 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00,
- 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
- 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
- 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
- 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0,
- 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0,
- 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
- 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
- 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
- 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x09, 0x00, 0x00,
- 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10,
- 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
- 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54,
- 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
- 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
- 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33,
- 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00,
- 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
- 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
- 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
- 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0,
- 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa,
- 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
- 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
- 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
- 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c,
- 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00,
- 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
- 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x94, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00,
- 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
- 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0,
- 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42,
- 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00,
- 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
- 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
- 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
- 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0,
- 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4,
- 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
- 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
- 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
- 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d,
- 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00,
- 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
- 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
- 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
- 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x09, 0x00,
- 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01,
- 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
- 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
- 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
- 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
- 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0,
- 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc,
- 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
- 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
- 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
- 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54,
- 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00,
- 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
- 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
- 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
- 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06,
- 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96,
- 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
- 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x9e, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff,
- 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
- 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00,
- 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0,
- 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb,
- 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
- 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
- 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
- 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79,
- 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00,
- 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
- 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
- 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
- 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9,
- 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0,
- 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
- 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d,
- 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
- 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00 };
-
-static const u8 default_cal_rssi[] = {
- 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72,
- 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00,
- 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a,
- 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe,
- 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00,
- 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01,
- 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a,
- 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-static void stlc45xx_tx_edcf(struct stlc45xx *stlc);
-static void stlc45xx_tx_setup(struct stlc45xx *stlc);
-static void stlc45xx_tx_scan(struct stlc45xx *stlc);
-static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable);
-static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave);
-static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave);
-
-static ssize_t stlc45xx_sysfs_show_cal_rssi(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct stlc45xx *stlc = dev_get_drvdata(dev);
- ssize_t len;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- len = PAGE_SIZE;
-
- mutex_lock(&stlc->mutex);
-
- if (stlc->cal_rssi)
- hex_dump_to_buffer(stlc->cal_rssi, RSSI_CAL_ARRAY_LEN, 16,
- 2, buf, len, 0);
- mutex_unlock(&stlc->mutex);
-
- len = strlen(buf);
-
- return len;
-}
-
-static ssize_t stlc45xx_sysfs_store_cal_rssi(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct stlc45xx *stlc = dev_get_drvdata(dev);
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- mutex_lock(&stlc->mutex);
-
- if (count != RSSI_CAL_ARRAY_LEN) {
- stlc45xx_error("invalid cal_rssi length: %zu", count);
- count = 0;
- goto out_unlock;
- }
-
- kfree(stlc->cal_rssi);
-
- stlc->cal_rssi = kmemdup(buf, RSSI_CAL_ARRAY_LEN, GFP_KERNEL);
-
- if (!stlc->cal_rssi) {
- stlc45xx_error("failed to allocate memory for cal_rssi");
- count = 0;
- goto out_unlock;
- }
-
- out_unlock:
- mutex_unlock(&stlc->mutex);
-
- return count;
-}
-
-static ssize_t stlc45xx_sysfs_show_cal_channels(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct stlc45xx *stlc = dev_get_drvdata(dev);
- ssize_t len;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- len = PAGE_SIZE;
-
- mutex_lock(&stlc->mutex);
-
- if (stlc->cal_channels)
- hex_dump_to_buffer(stlc->cal_channels, CHANNEL_CAL_ARRAY_LEN,
- 16, 2, buf, len, 0);
-
- mutex_unlock(&stlc->mutex);
-
- len = strlen(buf);
-
- return len;
-}
-
-static ssize_t stlc45xx_sysfs_store_cal_channels(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct stlc45xx *stlc = dev_get_drvdata(dev);
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- mutex_lock(&stlc->mutex);
-
- if (count != CHANNEL_CAL_ARRAY_LEN) {
- stlc45xx_error("invalid cal_channels size: %zu ", count);
- count = 0;
- goto out_unlock;
- }
-
- kfree(stlc->cal_channels);
-
- stlc->cal_channels = kmemdup(buf, count, GFP_KERNEL);
-
- if (!stlc->cal_channels) {
- stlc45xx_error("failed to allocate memory for cal_channels");
- count = 0;
- goto out_unlock;
- }
-
-out_unlock:
- mutex_unlock(&stlc->mutex);
-
- return count;
-}
-
-static ssize_t stlc45xx_sysfs_show_tx_buf(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct stlc45xx *stlc = dev_get_drvdata(dev);
- struct txbuffer *entry;
- ssize_t len = 0;
-
- stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
- mutex_lock(&stlc->mutex);
-
- list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
- len += sprintf(buf + len, "0x%x: 0x%x-0x%x\n",
- entry->handle, entry->start,
- entry->end);
- }
-
- mutex_unlock(&stlc->mutex);
-
- return len;
-}
-
-static DEVICE_ATTR(cal_rssi, S_IRUGO | S_IWUSR,
- stlc45xx_sysfs_show_cal_rssi,
- stlc45xx_sysfs_store_cal_rssi);
-static DEVICE_ATTR(cal_channels, S_IRUGO | S_IWUSR,
- stlc45xx_sysfs_show_cal_channels,
- stlc45xx_sysfs_store_cal_channels);
-static DEVICE_ATTR(tx_buf, S_IRUGO, stlc45xx_sysfs_show_tx_buf, NULL);
-
-static void stlc45xx_spi_read(struct stlc45xx *stlc, unsigned long addr,
- void *buf, size_t len)
-{
- struct spi_transfer t[2];
- struct spi_message m;
-
- /* We first push the address */
- addr = (addr << 8) | ADDR_READ_BIT_15;
-
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
-
- t[0].tx_buf = &addr;
- t[0].len = 2;
- spi_message_add_tail(&t[0], &m);
-
- t[1].rx_buf = buf;
- t[1].len = len;
- spi_message_add_tail(&t[1], &m);
-
- spi_sync(stlc->spi, &m);
-}
-
-
-static void stlc45xx_spi_write(struct stlc45xx *stlc, unsigned long addr,
- void *buf, size_t len)
-{
- struct spi_transfer t[3];
- struct spi_message m;
- u16 last_word;
-
- /* We first push the address */
- addr = addr << 8;
-
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
-
- t[0].tx_buf = &addr;
- t[0].len = 2;
- spi_message_add_tail(&t[0], &m);
-
- t[1].tx_buf = buf;
- t[1].len = len;
- spi_message_add_tail(&t[1], &m);
-
- if (len % 2) {
- last_word = ((u8 *)buf)[len - 1];
-
- t[2].tx_buf = &last_word;
- t[2].len = 2;
- spi_message_add_tail(&t[2], &m);
- }
-
- spi_sync(stlc->spi, &m);
-}
-
-static u16 stlc45xx_read16(struct stlc45xx *stlc, unsigned long addr)
-{
- u16 val;
-
- stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
-
- return val;
-}
-
-static u32 stlc45xx_read32(struct stlc45xx *stlc, unsigned long addr)
-{
- u32 val;
-
- stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
-
- return val;
-}
-
-static void stlc45xx_write16(struct stlc45xx *stlc, unsigned long addr, u16 val)
-{
- stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
-}
-
-static void stlc45xx_write32(struct stlc45xx *stlc, unsigned long addr, u32 val)
-{
- stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
-}
-
-struct stlc45xx_spi_reg {
- u16 address;
- u16 length;
- char *name;
-};
-
-/* caller must hold tx_lock */
-static void stlc45xx_txbuffer_dump(struct stlc45xx *stlc)
-{
- struct txbuffer *txbuffer;
- char *buf, *pos;
- int buf_len, l, count;
-
- if (!(DEBUG_LEVEL & DEBUG_TXBUFFER))
- return;
-
- stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
- buf_len = 500;
- buf = kmalloc(buf_len, GFP_ATOMIC);
- if (!buf)
- return;
-
- pos = buf;
- count = 0;
-
- list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
- l = snprintf(pos, buf_len, "0x%x-0x%x,",
- txbuffer->start, txbuffer->end);
- /* drop the null byte */
- pos += l;
- buf_len -= l;
- count++;
- }
-
- if (count == 0)
- *pos = '\0';
- else
- *--pos = '\0';
-
- stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: in buffer %d regions: %s",
- count, buf);
-
- kfree(buf);
-}
-
-/* caller must hold tx_lock */
-static int stlc45xx_txbuffer_find(struct stlc45xx *stlc, size_t len)
-{
- struct txbuffer *txbuffer;
- int pos;
-
- stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
- pos = FIRMWARE_TXBUFFER_START;
-
- if (list_empty(&stlc->txbuffer))
- goto out;
-
- /*
- * the entries in txbuffer must be in the same order as they are in
- * the real buffer
- */
- list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
- if (pos + len < txbuffer->start)
- break;
- pos = ALIGN(txbuffer->end + 1, 4);
- }
-
- if (pos + len > FIRMWARE_TXBUFFER_END)
- /* not enough room */
- pos = -1;
-
- stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: find %zu B: 0x%x", len, pos);
-
-out:
- return pos;
-}
-
-static int stlc45xx_txbuffer_add(struct stlc45xx *stlc,
- struct txbuffer *txbuffer)
-{
- struct txbuffer *r, *prev = NULL;
-
- if (list_empty(&stlc->txbuffer)) {
- list_add(&txbuffer->buffer_list, &stlc->txbuffer);
- return 0;
- }
-
- r = list_first_entry(&stlc->txbuffer, struct txbuffer, buffer_list);
-
- if (txbuffer->start < r->start) {
- /* add to the beginning of the list */
- list_add(&txbuffer->buffer_list, &stlc->txbuffer);
- return 0;
- }
-
- prev = NULL;
- list_for_each_entry(r, &stlc->txbuffer, buffer_list) {
- /* skip first entry, we checked for that above */
- if (!prev) {
- prev = r;
- continue;
- }
-
- /* double-check overlaps */
- WARN_ON_ONCE(txbuffer->start >= r->start &&
- txbuffer->start <= r->end);
- WARN_ON_ONCE(txbuffer->end >= r->start &&
- txbuffer->end <= r->end);
-
- if (prev->end < txbuffer->start &&
- txbuffer->end < r->start) {
- /* insert at this spot */
- list_add_tail(&txbuffer->buffer_list, &r->buffer_list);
- return 0;
- }
-
- prev = r;
- }
-
- /* not found */
- list_add_tail(&txbuffer->buffer_list, &stlc->txbuffer);
-
- return 0;
-
-}
-
-/* caller must hold tx_lock */
-static struct txbuffer *stlc45xx_txbuffer_alloc(struct stlc45xx *stlc,
- size_t frame_len)
-{
- struct txbuffer *entry = NULL;
- size_t len;
- int pos;
-
- stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
- len = FIRMWARE_TXBUFFER_HEADER + frame_len + FIRMWARE_TXBUFFER_TRAILER;
- pos = stlc45xx_txbuffer_find(stlc, len);
-
- if (pos < 0)
- return NULL;
-
- WARN_ON_ONCE(pos + len > FIRMWARE_TXBUFFER_END);
- WARN_ON_ONCE(pos < FIRMWARE_TXBUFFER_START);
-
- entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
- entry->start = pos;
- entry->frame_start = pos + FIRMWARE_TXBUFFER_HEADER;
- entry->end = entry->start + len - 1;
-
- stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: allocated 0x%x-0x%x",
- entry->start, entry->end);
-
- stlc45xx_txbuffer_add(stlc, entry);
-
- stlc45xx_txbuffer_dump(stlc);
-
- return entry;
-}
-
-/* caller must hold tx_lock */
-static void stlc45xx_txbuffer_free(struct stlc45xx *stlc,
- struct txbuffer *txbuffer)
-{
- stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
- stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: freed 0x%x-0x%x",
- txbuffer->start, txbuffer->end);
-
- list_del(&txbuffer->buffer_list);
- kfree(txbuffer);
-}
-
-
-static int stlc45xx_wait_bit(struct stlc45xx *stlc, u16 reg, u32 mask,
- u32 expected)
-{
- int i;
- char buffer[4];
-
- for (i = 0; i < 2000; i++) {
- stlc45xx_spi_read(stlc, reg, buffer, sizeof(buffer));
- if (((*(u32 *)buffer) & mask) == expected)
- return 1;
- msleep(1);
- }
-
- return 0;
-}
-
-static int stlc45xx_request_firmware(struct stlc45xx *stlc)
-{
- const struct firmware *fw;
- int ret;
-
- /* FIXME: should driver use it's own struct device? */
- ret = request_firmware(&fw, "3826.arm", &stlc->spi->dev);
-
- if (ret < 0) {
- stlc45xx_error("request_firmware() failed: %d", ret);
- return ret;
- }
-
- if (fw->size % 4) {
- stlc45xx_error("firmware size is not multiple of 32bit: %zu",
- fw->size);
- return -EILSEQ; /* Illegal byte sequence */;
- }
-
- if (fw->size < 1000) {
- stlc45xx_error("firmware is too small: %zu", fw->size);
- return -EILSEQ;
- }
-
- stlc->fw = kmemdup(fw->data, fw->size, GFP_KERNEL);
- if (!stlc->fw) {
- stlc45xx_error("could not allocate memory for firmware");
- return -ENOMEM;
- }
-
- stlc->fw_len = fw->size;
-
- release_firmware(fw);
-
- return 0;
-}
-
-static int stlc45xx_upload_firmware(struct stlc45xx *stlc)
-{
- struct s_dma_regs dma_regs;
- unsigned long fw_len, fw_addr;
- long _fw_len;
- int ret;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- if (!stlc->fw) {
- ret = stlc45xx_request_firmware(stlc);
- if (ret < 0)
- return ret;
- }
-
- /* stop the device */
- stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
- SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
- | SPI_CTRL_STAT_START_HALTED);
-
- msleep(TARGET_BOOT_SLEEP);
-
- stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
- SPI_CTRL_STAT_HOST_OVERRIDE
- | SPI_CTRL_STAT_START_HALTED);
-
- msleep(TARGET_BOOT_SLEEP);
-
- fw_addr = FIRMWARE_ADDRESS;
- fw_len = stlc->fw_len;
-
- while (fw_len > 0) {
- _fw_len = (fw_len > SPI_MAX_PACKET_SIZE)
- ? SPI_MAX_PACKET_SIZE : fw_len;
- dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
- dma_regs.len = cpu_to_le16(_fw_len);
- dma_regs.addr = cpu_to_le32(fw_addr);
-
- fw_len -= _fw_len;
- fw_addr += _fw_len;
-
- stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_CTRL, dma_regs.cmd);
-
- if (stlc45xx_wait_bit(stlc, SPI_ADRS_DMA_WRITE_CTRL,
- HOST_ALLOWED, HOST_ALLOWED) == 0) {
- stlc45xx_error("fw_upload not allowed to DMA write");
- return -EAGAIN;
- }
-
- stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_LEN, dma_regs.len);
- stlc45xx_write32(stlc, SPI_ADRS_DMA_WRITE_BASE, dma_regs.addr);
-
- stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, stlc->fw, _fw_len);
-
- /* FIXME: I think this doesn't work if firmware is large,
- * this loop goes to second round. fw->data is not
- * increased at all! */
- }
-
- BUG_ON(fw_len != 0);
-
- /* enable host interrupts */
- stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN, SPI_HOST_INTS_DEFAULT);
-
- /* boot the device */
- stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
- SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
- | SPI_CTRL_STAT_RAM_BOOT);
-
- msleep(TARGET_BOOT_SLEEP);
-
- stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
- SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT);
- msleep(TARGET_BOOT_SLEEP);
-
- return 0;
-}
-
-/* caller must hold tx_lock */
-static void stlc45xx_check_txsent(struct stlc45xx *stlc)
-{
- struct txbuffer *entry, *n;
-
- list_for_each_entry_safe(entry, n, &stlc->tx_sent, tx_list) {
- if (time_after(jiffies, entry->lifetime)) {
- if (net_ratelimit())
- stlc45xx_warning("frame 0x%x lifetime exceeded",
- entry->start);
- list_del(&entry->tx_list);
- skb_pull(entry->skb, entry->header_len);
- ieee80211_tx_status(stlc->hw, entry->skb);
- stlc45xx_txbuffer_free(stlc, entry);
- }
- }
-}
-
-static void stlc45xx_power_off(struct stlc45xx *stlc)
-{
- disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
- gpio_set_value(stlc45xx_gpio_power, 0);
-}
-
-static void stlc45xx_power_on(struct stlc45xx *stlc)
-{
- gpio_set_value(stlc45xx_gpio_power, 1);
- enable_irq(gpio_to_irq(stlc45xx_gpio_irq));
-
- /*
- * need to wait a while before device can be accessed, the length
- * is just a guess
- */
- msleep(10);
-}
-
-/* caller must hold tx_lock */
-static void stlc45xx_flush_queues(struct stlc45xx *stlc)
-{
- struct txbuffer *entry;
-
- while (!list_empty(&stlc->tx_sent)) {
- entry = list_first_entry(&stlc->tx_sent,
- struct txbuffer, tx_list);
- list_del(&entry->tx_list);
- dev_kfree_skb(entry->skb);
- stlc45xx_txbuffer_free(stlc, entry);
- }
-
- WARN_ON(!list_empty(&stlc->tx_sent));
-
- while (!list_empty(&stlc->tx_pending)) {
- entry = list_first_entry(&stlc->tx_pending,
- struct txbuffer, tx_list);
- list_del(&entry->tx_list);
- dev_kfree_skb(entry->skb);
- stlc45xx_txbuffer_free(stlc, entry);
- }
-
- WARN_ON(!list_empty(&stlc->tx_pending));
- WARN_ON(!list_empty(&stlc->txbuffer));
-}
-
-static void stlc45xx_work_reset(struct work_struct *work)
-{
- struct stlc45xx *stlc = container_of(work, struct stlc45xx,
- work_reset);
-
- mutex_lock(&stlc->mutex);
-
- if (stlc->fw_state != FW_STATE_RESET)
- goto out;
-
- stlc45xx_power_off(stlc);
-
- mutex_unlock(&stlc->mutex);
-
- /* wait that all work_structs have finished, we can't hold
- * stlc->mutex to avoid deadlock */
- cancel_work_sync(&stlc->work);
-
- /* FIXME: find out good value to wait for chip power down */
- msleep(100);
-
- mutex_lock(&stlc->mutex);
-
- /* FIXME: we should gracefully handle if the state has changed
- * after re-acquiring mutex */
- WARN_ON(stlc->fw_state != FW_STATE_RESET);
-
- spin_lock_bh(&stlc->tx_lock);
- stlc45xx_flush_queues(stlc);
- spin_unlock_bh(&stlc->tx_lock);
-
- stlc->fw_state = FW_STATE_RESETTING;
-
- stlc45xx_power_on(stlc);
- stlc45xx_upload_firmware(stlc);
-
-out:
- mutex_unlock(&stlc->mutex);
-}
-
-/* caller must hold mutex */
-static void stlc45xx_reset(struct stlc45xx *stlc)
-{
- stlc45xx_warning("resetting firmware");
- stlc->fw_state = FW_STATE_RESET;
- ieee80211_stop_queues(stlc->hw);
- queue_work(stlc->hw->workqueue, &stlc->work_reset);
-}
-
-static void stlc45xx_work_tx_timeout(struct work_struct *work)
-{
- struct stlc45xx *stlc = container_of(work, struct stlc45xx,
- work_tx_timeout.work);
-
- stlc45xx_warning("tx timeout");
-
- mutex_lock(&stlc->mutex);
-
- if (stlc->fw_state != FW_STATE_READY)
- goto out;
-
- stlc45xx_reset(stlc);
-
-out:
- mutex_unlock(&stlc->mutex);
-}
-
-static void stlc45xx_int_ack(struct stlc45xx *stlc, u32 val)
-{
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_ACK, val);
-}
-
-static void stlc45xx_wakeup(struct stlc45xx *stlc)
-{
- unsigned long timeout;
- u32 ints;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- /* wake the chip */
- stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_WAKEUP);
-
- /* And wait for the READY interrupt */
- timeout = jiffies + HZ;
-
- ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
- while (!(ints & SPI_HOST_INT_READY)) {
- if (time_after(jiffies, timeout))
- goto out;
- ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
- }
-
- stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
-
-out:
- return;
-}
-
-static void stlc45xx_sleep(struct stlc45xx *stlc)
-{
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_SLEEP);
-}
-
-static void stlc45xx_int_ready(struct stlc45xx *stlc)
-{
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN,
- SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE);
-
- switch (stlc->fw_state) {
- case FW_STATE_BOOTING:
- stlc->fw_state = FW_STATE_READY;
- complete(&stlc->fw_comp);
- break;
- case FW_STATE_RESETTING:
- stlc->fw_state = FW_STATE_READY;
-
- stlc45xx_tx_scan(stlc);
- stlc45xx_tx_setup(stlc);
- stlc45xx_tx_edcf(stlc);
-
- ieee80211_wake_queues(stlc->hw);
- break;
- default:
- break;
- }
-}
-
-static int stlc45xx_rx_txack(struct stlc45xx *stlc, struct sk_buff *skb)
-{
- struct ieee80211_tx_info *info;
- struct s_lm_control *control;
- struct s_lmo_tx *tx;
- struct txbuffer *entry;
- int found = 0;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- control = (struct s_lm_control *) skb->data;
- tx = (struct s_lmo_tx *) (control + 1);
-
- if (list_empty(&stlc->tx_sent)) {
- if (net_ratelimit())
- stlc45xx_warning("no frames waiting for "
- "acknowledgement");
- return -1;
- }
-
- list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
- if (control->handle == entry->handle) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- if (net_ratelimit())
- stlc45xx_warning("couldn't find frame for tx ack 0x%x",
- control->handle);
- return -1;
- }
-
- stlc45xx_debug(DEBUG_TX, "TX ACK 0x%x", entry->handle);
-
- if (entry->status_needed) {
- info = IEEE80211_SKB_CB(entry->skb);
-
- if (!(tx->flags & LM_TX_FAILED)) {
- /* frame was acked */
- info->flags |= IEEE80211_TX_STAT_ACK;
- info->status.ack_signal = tx->rcpi / 2 - 110;
- }
-
- skb_pull(entry->skb, entry->header_len);
-
- ieee80211_tx_status(stlc->hw, entry->skb);
- }
-
- list_del(&entry->tx_list);
-
- stlc45xx_check_txsent(stlc);
- if (list_empty(&stlc->tx_sent))
- /* there are no pending frames, we can stop the tx timeout
- * timer */
- cancel_delayed_work(&stlc->work_tx_timeout);
-
- spin_lock_bh(&stlc->tx_lock);
-
- stlc45xx_txbuffer_free(stlc, entry);
-
- if (stlc->tx_queue_stopped &&
- stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) != -1) {
- stlc45xx_debug(DEBUG_QUEUE, "room in tx buffer, waking queues");
- ieee80211_wake_queues(stlc->hw);
- stlc->tx_queue_stopped = 0;
- }
-
- spin_unlock_bh(&stlc->tx_lock);
-
- return 0;
-}
-
-static int stlc45xx_rx_control(struct stlc45xx *stlc, struct sk_buff *skb)
-{
- struct s_lm_control *control;
- int ret = 0;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- control = (struct s_lm_control *) skb->data;
-
- switch (control->oid) {
- case LM_OID_TX:
- ret = stlc45xx_rx_txack(stlc, skb);
- break;
- case LM_OID_SETUP:
- case LM_OID_SCAN:
- case LM_OID_TRAP:
- case LM_OID_EDCF:
- case LM_OID_KEYCACHE:
- case LM_OID_PSM:
- case LM_OID_STATS:
- case LM_OID_LED:
- default:
- stlc45xx_warning("unhandled rx control oid %d\n",
- control->oid);
- break;
- }
-
- dev_kfree_skb(skb);
-
- return ret;
-}
-
-/* copied from mac80211 */
-static void stlc45xx_parse_elems(u8 *start, size_t len,
- struct stlc45xx_ie_tim **tim,
- size_t *tim_len)
-{
- size_t left = len;
- u8 *pos = start;
-
- while (left >= 2) {
- u8 id, elen;
-
- id = *pos++;
- elen = *pos++;
- left -= 2;
-
- if (elen > left)
- return;
-
- switch (id) {
- case WLAN_EID_TIM:
- *tim = (struct stlc45xx_ie_tim *) pos;
- *tim_len = elen;
- break;
- default:
- break;
- }
-
- left -= elen;
- pos += elen;
- }
-}
-
-/*
- * mac80211 doesn't have support for asking frames with PS-Poll, so let's
- * implement in the driver for now. We have to add support to mac80211
- * later.
- */
-static int stlc45xx_check_more_data(struct stlc45xx *stlc, struct sk_buff *skb)
-{
- struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
- struct ieee80211_hdr *hdr;
- size_t len;
- u16 fc;
-
- hdr = (void *) skb->data + sizeof(*data);
- len = skb->len - sizeof(*data);
-
- /* minimum frame length is the null frame length 24 bytes */
- if (len < 24) {
- stlc45xx_warning("invalid frame length when checking for "
- "more data");
- return -EINVAL;
- }
-
- fc = le16_to_cpu(hdr->frame_control);
- if (!(fc & IEEE80211_FCTL_FROMDS))
- /* this is not from DS */
- return 0;
-
- if (compare_ether_addr(hdr->addr1, stlc->mac_addr) != 0)
- /* the frame was not for us */
- return 0;
-
- if (!(fc & IEEE80211_FCTL_MOREDATA)) {
- /* AP has no more frames buffered for us */
- stlc45xx_debug(DEBUG_PSM, "all buffered frames retrieved");
- stlc->pspolling = false;
- return 0;
- }
-
- /* MOREDATA bit is set, let's ask for a new frame from the AP */
- stlc45xx_tx_pspoll(stlc, stlc->psm);
-
- return 0;
-}
-
-/*
- * mac80211 cannot read TIM from beacons, so let's add a hack to the
- * driver. We have to add support to mac80211 later.
- */
-static int stlc45xx_rx_data_beacon(struct stlc45xx *stlc, struct sk_buff *skb)
-{
- struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
- size_t len = skb->len, tim_len = 0, baselen, pvbmap_len;
- struct ieee80211_mgmt *mgmt;
- struct stlc45xx_ie_tim *tim = NULL;
- int bmap_offset, index, aid_bit;
-
- mgmt = (void *) skb->data + sizeof(*data);
-
- baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
- if (baselen > len) {
- stlc45xx_warning("invalid baselen in beacon");
- return -EINVAL;
- }
-
- stlc45xx_parse_elems(mgmt->u.beacon.variable, len - baselen, &tim,
- &tim_len);
-
- if (!tim) {
- stlc45xx_warning("didn't find tim from a beacon");
- return -EINVAL;
- }
-
- bmap_offset = tim->bmap_control & 0xfe;
- index = stlc->aid / 8 - bmap_offset;
-
- pvbmap_len = tim_len - 3;
- if (index > pvbmap_len)
- return -EINVAL;
-
- aid_bit = !!(tim->pvbmap[index] & (1 << stlc->aid % 8));
-
- stlc45xx_debug(DEBUG_PSM, "fc 0x%x duration %d seq %d dtim %u "
- "bmap_control 0x%x aid_bit %d",
- mgmt->frame_control, mgmt->duration, mgmt->seq_ctrl >> 4,
- tim->dtim_count, tim->bmap_control, aid_bit);
-
- if (!aid_bit)
- return 0;
-
- stlc->pspolling = true;
- stlc45xx_tx_pspoll(stlc, stlc->psm);
-
- return 0;
-}
-
-static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb)
-{
- struct ieee80211_rx_status status;
- struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
- int align = 0;
- u8 *p, align_len;
- u16 len;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- if (stlc->psm) {
- if (data->flags & LM_IN_BEACON)
- stlc45xx_rx_data_beacon(stlc, skb);
- else if (stlc->pspolling && (data->flags & LM_IN_DATA))
- stlc45xx_check_more_data(stlc, skb);
- }
-
- memset(&status, 0, sizeof(status));
-
- status.freq = data->frequency;
- status.signal = data->rcpi / 2 - 110;
-
- /* let's assume that maximum rcpi value is 140 (= 35 dBm) */
- status.qual = data->rcpi * 100 / 140;
-
- status.band = IEEE80211_BAND_2GHZ;
-
- /*
- * FIXME: this gives warning from __ieee80211_rx()
- *
- * status.rate_idx = data->rate;
- */
-
- len = data->length;
-
- if (data->flags & LM_FLAG_ALIGN)
- align = 1;
-
- skb_pull(skb, sizeof(*data));
-
- if (align) {
- p = skb->data;
- align_len = *p;
- skb_pull(skb, align_len);
- }
-
- skb_trim(skb, len);
-
- stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len);
- stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
-
- memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
- ieee80211_rx(stlc->hw, skb);
-
- return 0;
-}
-
-
-
-static int stlc45xx_rx(struct stlc45xx *stlc)
-{
- struct s_lm_control *control;
- struct sk_buff *skb;
- int ret;
- u16 len;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- stlc45xx_wakeup(stlc);
-
- /* dummy read to flush SPI DMA controller bug */
- stlc45xx_read16(stlc, SPI_ADRS_GEN_PURP_1);
-
- len = stlc45xx_read16(stlc, SPI_ADRS_DMA_DATA);
-
- if (len == 0) {
- stlc45xx_warning("rx request of zero bytes");
- return 0;
- }
-
- skb = dev_alloc_skb(len);
- if (!skb) {
- stlc45xx_warning("could not alloc skb");
- return 0;
- }
-
- stlc45xx_spi_read(stlc, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
-
- stlc45xx_sleep(stlc);
-
- stlc45xx_debug(DEBUG_RX, "rx frame 0x%p %d B", skb->data, skb->len);
- stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
-
- control = (struct s_lm_control *) skb->data;
-
- if (control->flags & LM_FLAG_CONTROL)
- ret = stlc45xx_rx_control(stlc, skb);
- else
- ret = stlc45xx_rx_data(stlc, skb);
-
- return ret;
-}
-
-
-static irqreturn_t stlc45xx_interrupt(int irq, void *config)
-{
- struct spi_device *spi = config;
- struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
-
- stlc45xx_debug(DEBUG_IRQ, "IRQ");
-
- queue_work(stlc->hw->workqueue, &stlc->work);
-
- return IRQ_HANDLED;
-}
-
-static int stlc45xx_tx_frame(struct stlc45xx *stlc, u32 address,
- void *buf, size_t len)
-{
- struct s_dma_regs dma_regs;
- unsigned long timeout;
- int ret = 0;
- u32 ints;
-
- stlc->tx_frames++;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- stlc45xx_debug(DEBUG_TX, "tx frame 0x%p %zu B", buf, len);
- stlc45xx_dump(DEBUG_TX_CONTENT, buf, len);
-
- stlc45xx_wakeup(stlc);
-
- dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
- dma_regs.len = cpu_to_le16(len);
- dma_regs.addr = cpu_to_le32(address);
-
- stlc45xx_spi_write(stlc, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
- sizeof(dma_regs));
-
- stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, buf, len);
-
- timeout = jiffies + 2 * HZ;
- ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
- while (!(ints & SPI_HOST_INT_WR_READY)) {
- if (time_after(jiffies, timeout)) {
- stlc45xx_warning("WR_READY timeout");
- ret = -1;
- goto out;
- }
- ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
- }
-
- stlc45xx_int_ack(stlc, SPI_HOST_INT_WR_READY);
-
- stlc45xx_sleep(stlc);
-
-out:
- return ret;
-}
-
-static int stlc45xx_wq_tx(struct stlc45xx *stlc)
-{
- struct txbuffer *entry;
- int ret = 0;
-
- spin_lock_bh(&stlc->tx_lock);
-
- while (!list_empty(&stlc->tx_pending)) {
- entry = list_entry(stlc->tx_pending.next,
- struct txbuffer, tx_list);
-
- list_del_init(&entry->tx_list);
-
- spin_unlock_bh(&stlc->tx_lock);
-
- ret = stlc45xx_tx_frame(stlc, entry->frame_start,
- entry->skb->data, entry->skb->len);
-
- spin_lock_bh(&stlc->tx_lock);
-
- if (ret < 0) {
- /* frame transfer to firmware buffer failed */
- /* FIXME: report this to mac80211 */
- dev_kfree_skb(entry->skb);
- stlc45xx_txbuffer_free(stlc, entry);
- goto out;
- }
-
- list_add(&entry->tx_list, &stlc->tx_sent);
- queue_delayed_work(stlc->hw->workqueue,
- &stlc->work_tx_timeout,
- msecs_to_jiffies(TX_TIMEOUT));
- }
-
-out:
- spin_unlock_bh(&stlc->tx_lock);
- return ret;
-}
-
-static void stlc45xx_work(struct work_struct *work)
-{
- struct stlc45xx *stlc = container_of(work, struct stlc45xx, work);
- u32 ints;
- int ret;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- mutex_lock(&stlc->mutex);
-
- if (stlc->fw_state == FW_STATE_OFF &&
- stlc->fw_state == FW_STATE_RESET)
- goto out;
-
- ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
- stlc45xx_debug(DEBUG_BH, "begin host_ints 0x%08x", ints);
-
- if (ints & SPI_HOST_INT_READY) {
- stlc45xx_int_ready(stlc);
- stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
- }
-
- if (stlc->fw_state != FW_STATE_READY)
- goto out;
-
- if (ints & SPI_HOST_INT_UPDATE) {
- stlc45xx_int_ack(stlc, SPI_HOST_INT_UPDATE);
- ret = stlc45xx_rx(stlc);
- if (ret < 0) {
- stlc45xx_reset(stlc);
- goto out;
- }
- }
- if (ints & SPI_HOST_INT_SW_UPDATE) {
- stlc45xx_int_ack(stlc, SPI_HOST_INT_SW_UPDATE);
- ret = stlc45xx_rx(stlc);
- if (ret < 0) {
- stlc45xx_reset(stlc);
- goto out;
- }
- }
-
- ret = stlc45xx_wq_tx(stlc);
- if (ret < 0) {
- stlc45xx_reset(stlc);
- goto out;
- }
-
- ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
- stlc45xx_debug(DEBUG_BH, "end host_ints 0x%08x", ints);
-
-out:
- mutex_unlock(&stlc->mutex);
-}
-
-static void stlc45xx_tx_edcf(struct stlc45xx *stlc)
-{
- struct s_lm_control *control;
- struct s_lmo_edcf *edcf;
- size_t len, edcf_len;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- edcf_len = sizeof(*edcf);
- len = sizeof(*control) + edcf_len;
- control = kzalloc(len, GFP_KERNEL);
- edcf = (struct s_lmo_edcf *) (control + 1);
-
- control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
- control->length = edcf_len;
- control->oid = LM_OID_EDCF;
-
- edcf->slottime = 0x14;
- edcf->sifs = 10;
- edcf->eofpad = 6;
- edcf->maxburst = 1500;
-
- edcf->queues[0].aifs = 2;
- edcf->queues[0].pad0 = 1;
- edcf->queues[0].cwmin = 3;
- edcf->queues[0].cwmax = 7;
- edcf->queues[0].txop = 47;
- edcf->queues[1].aifs = 2;
- edcf->queues[1].pad0 = 0;
- edcf->queues[1].cwmin = 7;
- edcf->queues[1].cwmax = 15;
- edcf->queues[1].txop = 94;
- edcf->queues[2].aifs = 3;
- edcf->queues[2].pad0 = 0;
- edcf->queues[2].cwmin = 15;
- edcf->queues[2].cwmax = 1023;
- edcf->queues[2].txop = 0;
- edcf->queues[3].aifs = 7;
- edcf->queues[3].pad0 = 0;
- edcf->queues[3].cwmin = 15;
- edcf->queues[3].cwmax = 1023;
- edcf->queues[3].txop = 0;
- edcf->queues[4].aifs = 13;
- edcf->queues[4].pad0 = 99;
- edcf->queues[4].cwmin = 3437;
- edcf->queues[4].cwmax = 512;
- edcf->queues[4].txop = 12;
- edcf->queues[5].aifs = 142;
- edcf->queues[5].pad0 = 109;
- edcf->queues[5].cwmin = 8756;
- edcf->queues[5].cwmax = 6;
- edcf->queues[5].txop = 0;
- edcf->queues[6].aifs = 4;
- edcf->queues[6].pad0 = 0;
- edcf->queues[6].cwmin = 0;
- edcf->queues[6].cwmax = 58705;
- edcf->queues[6].txop = 25716;
- edcf->queues[7].aifs = 0;
- edcf->queues[7].pad0 = 0;
- edcf->queues[7].cwmin = 0;
- edcf->queues[7].cwmax = 0;
- edcf->queues[7].txop = 0;
-
- stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
-
- kfree(control);
-}
-
-static void stlc45xx_tx_setup(struct stlc45xx *stlc)
-{
- struct s_lm_control *control;
- struct s_lmo_setup *setup;
- size_t len, setup_len;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- setup_len = sizeof(*setup);
- len = sizeof(*control) + setup_len;
- control = kzalloc(len, GFP_KERNEL);
- setup = (struct s_lmo_setup *) (control + 1);
-
- control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
- control->length = setup_len;
- control->oid = LM_OID_SETUP;
-
- setup->flags = LM_SETUP_INFRA;
- setup->antenna = 2;
- setup->rx_align = 0;
- setup->rx_buffer = FIRMWARE_RXBUFFER_START;
- setup->rx_mtu = FIRMWARE_MTU;
- setup->frontend = 5;
- setup->timeout = 0;
- setup->truncate = 48896;
- setup->bratemask = 0xffffffff;
- setup->ref_clock = 644245094;
- setup->lpf_bandwidth = 65535;
- setup->osc_start_delay = 65535;
-
- memcpy(setup->macaddr, stlc->mac_addr, ETH_ALEN);
- memcpy(setup->bssid, stlc->bssid, ETH_ALEN);
-
- stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
-
- kfree(control);
-}
-
-static void stlc45xx_tx_scan(struct stlc45xx *stlc)
-{
- struct s_lm_control *control;
- struct s_lmo_scan *scan;
- size_t len, scan_len;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- scan_len = sizeof(*scan);
- len = sizeof(*control) + scan_len;
- control = kzalloc(len, GFP_KERNEL);
- scan = (struct s_lmo_scan *) (control + 1);
-
- control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
- control->length = scan_len;
- control->oid = LM_OID_SCAN;
-
- scan->flags = LM_SCAN_EXIT;
- scan->bratemask = 0x15f;
- scan->aloft[0] = 3;
- scan->aloft[1] = 3;
- scan->aloft[2] = 1;
- scan->aloft[3] = 0;
- scan->aloft[4] = 0;
- scan->aloft[5] = 0;
- scan->aloft[6] = 0;
- scan->aloft[7] = 0;
-
- memcpy(&scan->rssical, &stlc->cal_rssi[(stlc->channel - 1) *
- RSSI_CAL_LEN],
- RSSI_CAL_LEN);
- memcpy(&scan->channel, &stlc->cal_channels[(stlc->channel - 1) *
- CHANNEL_CAL_LEN],
- CHANNEL_CAL_LEN);
-
- stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
-
- kfree(control);
-}
-
-/*
- * caller must hold mutex
- */
-static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave)
-{
- struct ieee80211_hdr *pspoll;
- int payload_len, padding, i;
- struct s_lm_data_out *data;
- struct txbuffer *entry;
- struct sk_buff *skb;
- char *payload;
- u16 fc;
-
- skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 16);
- if (!skb) {
- stlc45xx_warning("failed to allocate pspoll frame");
- return -ENOMEM;
- }
- skb_reserve(skb, stlc->hw->extra_tx_headroom);
-
- pspoll = (struct ieee80211_hdr *) skb_put(skb, 16);
- memset(pspoll, 0, 16);
- fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL;
- if (powersave)
- fc |= IEEE80211_FCTL_PM;
- pspoll->frame_control = cpu_to_le16(fc);
- pspoll->duration_id = cpu_to_le16(stlc->aid);
-
- /* aid in PS-Poll has its two MSBs each set to 1 */
- pspoll->duration_id |= cpu_to_le16(1 << 15) | cpu_to_le16(1 << 14);
-
- memcpy(pspoll->addr1, stlc->bssid, ETH_ALEN);
- memcpy(pspoll->addr2, stlc->mac_addr, ETH_ALEN);
-
- stlc45xx_debug(DEBUG_PSM, "sending PS-Poll frame to %pM (powersave %d, "
- "fc 0x%x, aid %d)", pspoll->addr1,
- powersave, fc, stlc->aid);
-
- spin_lock_bh(&stlc->tx_lock);
-
- entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
-
- spin_unlock_bh(&stlc->tx_lock);
-
- if (!entry) {
- /*
- * The queue should be stopped before the firmware buffer
- * is full, so firmware buffer should always have enough
- * space.
- *
- * But I'm too lazy and omit it for now.
- */
- if (net_ratelimit())
- stlc45xx_warning("firmware tx buffer full is full "
- "for null frame");
- return -ENOSPC;
- }
-
- payload = skb->data;
- payload_len = skb->len;
- padding = (int) (skb->data - sizeof(*data)) & 3;
- entry->header_len = sizeof(*data) + padding;
-
- entry->skb = skb;
- entry->status_needed = false;
- entry->handle = (u32) skb;
- entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
-
- stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
- "padding %d header_len %d)",
- entry->handle, payload, payload_len, padding,
- entry->header_len);
- stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
-
- data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
-
- memset(data, 0, entry->header_len);
-
- if (padding)
- data->flags = LM_FLAG_ALIGN;
-
- data->flags = LM_OUT_BURST;
- data->length = payload_len;
- data->handle = entry->handle;
- data->aid = 1;
- data->rts_retries = 7;
- data->retries = 7;
- data->aloft_ctrl = 0;
- data->crypt_offset = 58;
- data->keytype = 0;
- data->keylen = 0;
- data->queue = LM_QUEUE_DATA3;
- data->backlog = 32;
- data->antenna = 2;
- data->cts = 3;
- data->power = 127;
-
- for (i = 0; i < 8; i++)
- data->aloft[i] = 0;
-
- /*
- * check if there's enough space in tx buffer
- *
- * FIXME: ignored for now
- */
-
- stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
-
- list_add(&entry->tx_list, &stlc->tx_sent);
-
- return 0;
-}
-
-/*
- * caller must hold mutex
- *
- * shamelessly stolen from mac80211/ieee80211_send_nullfunc
- */
-static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave)
-{
- struct ieee80211_hdr *nullfunc;
- int payload_len, padding, i;
- struct s_lm_data_out *data;
- struct txbuffer *entry;
- struct sk_buff *skb;
- char *payload;
- u16 fc;
-
- skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 24);
- if (!skb) {
- stlc45xx_warning("failed to allocate buffer for null frame\n");
- return -ENOMEM;
- }
- skb_reserve(skb, stlc->hw->extra_tx_headroom);
-
- nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
- memset(nullfunc, 0, 24);
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
- IEEE80211_FCTL_TODS;
-
- if (powersave)
- fc |= IEEE80211_FCTL_PM;
-
- nullfunc->frame_control = cpu_to_le16(fc);
- memcpy(nullfunc->addr1, stlc->bssid, ETH_ALEN);
- memcpy(nullfunc->addr2, stlc->mac_addr, ETH_ALEN);
- memcpy(nullfunc->addr3, stlc->bssid, ETH_ALEN);
-
- stlc45xx_debug(DEBUG_PSM, "sending Null frame to %pM (powersave %d, "
- "fc 0x%x)", nullfunc->addr1, powersave, fc);
-
- spin_lock_bh(&stlc->tx_lock);
-
- entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
-
- spin_unlock_bh(&stlc->tx_lock);
-
- if (!entry) {
- /*
- * The queue should be stopped before the firmware buffer
- * is full, so firmware buffer should always have enough
- * space.
- *
- * But I'm too lazy and omit it for now.
- */
- if (net_ratelimit())
- stlc45xx_warning("firmware tx buffer full is full "
- "for null frame");
- return -ENOSPC;
- }
-
- payload = skb->data;
- payload_len = skb->len;
- padding = (int) (skb->data - sizeof(*data)) & 3;
- entry->header_len = sizeof(*data) + padding;
-
- entry->skb = skb;
- entry->status_needed = false;
- entry->handle = (u32) skb;
- entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
-
- stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
- "padding %d header_len %d)",
- entry->handle, payload, payload_len, padding,
- entry->header_len);
- stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
-
- data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
-
- memset(data, 0, entry->header_len);
-
- if (padding)
- data->flags = LM_FLAG_ALIGN;
-
- data->flags = LM_OUT_BURST;
- data->length = payload_len;
- data->handle = entry->handle;
- data->aid = 1;
- data->rts_retries = 7;
- data->retries = 7;
- data->aloft_ctrl = 0;
- data->crypt_offset = 58;
- data->keytype = 0;
- data->keylen = 0;
- data->queue = LM_QUEUE_DATA3;
- data->backlog = 32;
- data->antenna = 2;
- data->cts = 3;
- data->power = 127;
-
- for (i = 0; i < 8; i++)
- data->aloft[i] = 0;
-
- /*
- * check if there's enough space in tx buffer
- *
- * FIXME: ignored for now
- */
-
- stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
-
- list_add(&entry->tx_list, &stlc->tx_sent);
-
- return 0;
-}
-
-/* caller must hold mutex */
-static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable)
-{
- struct s_lm_control *control;
- struct s_lmo_psm *psm;
- size_t len, psm_len;
-
- WARN_ON(!stlc->associated);
- WARN_ON(stlc->aid < 1);
- WARN_ON(stlc->aid > 2007);
-
- psm_len = sizeof(*psm);
- len = sizeof(*control) + psm_len;
- control = kzalloc(len, GFP_KERNEL);
- psm = (struct s_lmo_psm *) (control + 1);
-
- control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
- control->length = psm_len;
- control->oid = LM_OID_PSM;
-
- if (enable)
- psm->flags |= LM_PSM;
-
- psm->aid = stlc->aid;
-
- psm->beacon_rcpi_skip_max = 60;
-
- psm->intervals[0].interval = 1;
- psm->intervals[0].periods = 1;
- psm->intervals[1].interval = 1;
- psm->intervals[1].periods = 1;
- psm->intervals[2].interval = 1;
- psm->intervals[2].periods = 1;
- psm->intervals[3].interval = 1;
- psm->intervals[3].periods = 1;
-
- psm->nr = 0;
- psm->exclude[0] = 0;
-
- stlc45xx_debug(DEBUG_PSM, "sending LM_OID_PSM (aid %d, interval %d)",
- psm->aid, psm->intervals[0].interval);
-
- stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
-
- kfree(control);
-}
-
-static int stlc45xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct stlc45xx *stlc = hw->priv;
- struct ieee80211_tx_info *info;
- struct ieee80211_rate *rate;
- int payload_len, padding, i;
- struct s_lm_data_out *data;
- struct txbuffer *entry;
- char *payload;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- spin_lock_bh(&stlc->tx_lock);
-
- entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
- if (!entry) {
- /* the queue should be stopped before the firmware buffer
- * is full, so firmware buffer should always have enough
- * space */
- if (net_ratelimit())
- stlc45xx_warning("firmware buffer full");
- spin_unlock_bh(&stlc->tx_lock);
- return NETDEV_TX_BUSY;
- }
-
- info = IEEE80211_SKB_CB(skb);
-
- payload = skb->data;
- payload_len = skb->len;
- padding = (int) (skb->data - sizeof(*data)) & 3;
- entry->header_len = sizeof(*data) + padding;
-
- entry->skb = skb;
- entry->status_needed = true;
- entry->handle = (u32) skb;
- entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
-
- stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
- "padding %d header_len %d)",
- entry->handle, payload, payload_len, padding,
- entry->header_len);
- stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
-
- data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
-
- memset(data, 0, entry->header_len);
-
- if (padding)
- data->flags = LM_FLAG_ALIGN;
-
- data->flags = LM_OUT_BURST;
- data->length = payload_len;
- data->handle = entry->handle;
- data->aid = 1;
- data->rts_retries = 7;
- data->retries = 7;
- data->aloft_ctrl = 0;
- data->crypt_offset = 58;
- data->keytype = 0;
- data->keylen = 0;
- data->queue = 2;
- data->backlog = 32;
- data->antenna = 2;
- data->cts = 3;
- data->power = 127;
-
- for (i = 0; i < 8; i++) {
- rate = ieee80211_get_tx_rate(stlc->hw, info);
- data->aloft[i] = rate->hw_value;
- }
-
- list_add_tail(&entry->tx_list, &stlc->tx_pending);
-
- /* check if there's enough space in tx buffer */
- if (stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) == -1) {
- stlc45xx_debug(DEBUG_QUEUE, "tx buffer full, stopping queues");
- stlc->tx_queue_stopped = 1;
- ieee80211_stop_queues(stlc->hw);
- }
-
- queue_work(stlc->hw->workqueue, &stlc->work);
-
- spin_unlock_bh(&stlc->tx_lock);
-
- return NETDEV_TX_OK;
-}
-
-static int stlc45xx_op_start(struct ieee80211_hw *hw)
-{
- struct stlc45xx *stlc = hw->priv;
- unsigned long timeout;
- int ret = 0;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- mutex_lock(&stlc->mutex);
-
- stlc->fw_state = FW_STATE_BOOTING;
- stlc->channel = 1;
-
- stlc45xx_power_on(stlc);
-
- ret = stlc45xx_upload_firmware(stlc);
- if (ret < 0) {
- stlc45xx_power_off(stlc);
- goto out_unlock;
- }
-
- stlc->tx_queue_stopped = 0;
-
- mutex_unlock(&stlc->mutex);
-
- timeout = msecs_to_jiffies(2000);
- timeout = wait_for_completion_interruptible_timeout(&stlc->fw_comp,
- timeout);
- if (!timeout) {
- stlc45xx_error("firmware boot failed");
- stlc45xx_power_off(stlc);
- ret = -1;
- goto out;
- }
-
- stlc45xx_debug(DEBUG_BOOT, "firmware booted");
-
- /* FIXME: should we take mutex just after wait_for_completion()? */
- mutex_lock(&stlc->mutex);
-
- WARN_ON(stlc->fw_state != FW_STATE_READY);
-
-out_unlock:
- mutex_unlock(&stlc->mutex);
-
-out:
- return ret;
-}
-
-static void stlc45xx_op_stop(struct ieee80211_hw *hw)
-{
- struct stlc45xx *stlc = hw->priv;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- mutex_lock(&stlc->mutex);
-
- WARN_ON(stlc->fw_state != FW_STATE_READY);
-
- stlc45xx_power_off(stlc);
-
- /* FIXME: make sure that all work_structs have completed */
-
- spin_lock_bh(&stlc->tx_lock);
- stlc45xx_flush_queues(stlc);
- spin_unlock_bh(&stlc->tx_lock);
-
- stlc->fw_state = FW_STATE_OFF;
-
- mutex_unlock(&stlc->mutex);
-}
-
-static int stlc45xx_op_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct stlc45xx *stlc = hw->priv;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- switch (conf->type) {
- case NL80211_IFTYPE_STATION:
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- memcpy(stlc->mac_addr, conf->mac_addr, ETH_ALEN);
-
- return 0;
-}
-
-static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-}
-
-static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct stlc45xx *stlc = hw->priv;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- mutex_lock(&stlc->mutex);
-
- stlc->channel = hw->conf.channel->hw_value;
- stlc45xx_tx_scan(stlc);
- stlc45xx_tx_setup(stlc);
- stlc45xx_tx_edcf(stlc);
-
- if ((hw->conf.flags & IEEE80211_CONF_PS) != stlc->psm) {
- stlc->psm = hw->conf.flags & IEEE80211_CONF_PS;
- if (stlc->associated) {
- stlc45xx_tx_psm(stlc, stlc->psm);
- stlc45xx_tx_nullfunc(stlc, stlc->psm);
- }
- }
-
- mutex_unlock(&stlc->mutex);
-
- return 0;
-}
-
-static void stlc45xx_op_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- int mc_count,
- struct dev_addr_list *mc_list)
-{
- *total_flags = 0;
-}
-
-static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u32 changed)
-{
- struct stlc45xx *stlc = hw->priv;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
- mutex_lock(&stlc->mutex);
-
- memcpy(stlc->bssid, info->bssid, ETH_ALEN);
- stlc45xx_tx_setup(stlc);
-
- mutex_unlock(&stlc->mutex);
-
- if (changed & BSS_CHANGED_ASSOC) {
- stlc->associated = info->assoc;
- if (info->assoc)
- stlc->aid = info->aid;
- else
- stlc->aid = -1;
-
- if (stlc->psm) {
- stlc45xx_tx_psm(stlc, stlc->psm);
- stlc45xx_tx_nullfunc(stlc, stlc->psm);
- }
- }
-}
-
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_rate stlc45xx_rates[] = {
- { .bitrate = 10, .hw_value = 0, .hw_value_short = 0, },
- { .bitrate = 20, .hw_value = 1, .hw_value_short = 1, },
- { .bitrate = 55, .hw_value = 2, .hw_value_short = 2, },
- { .bitrate = 110, .hw_value = 3, .hw_value_short = 3, },
- { .bitrate = 60, .hw_value = 4, .hw_value_short = 4, },
- { .bitrate = 90, .hw_value = 5, .hw_value_short = 5, },
- { .bitrate = 120, .hw_value = 6, .hw_value_short = 6, },
- { .bitrate = 180, .hw_value = 7, .hw_value_short = 7, },
- { .bitrate = 240, .hw_value = 8, .hw_value_short = 8, },
- { .bitrate = 360, .hw_value = 9, .hw_value_short = 9, },
- { .bitrate = 480, .hw_value = 10, .hw_value_short = 10, },
- { .bitrate = 540, .hw_value = 11, .hw_value_short = 11, },
-};
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_channel stlc45xx_channels[] = {
- { .hw_value = 1, .center_freq = 2412},
- { .hw_value = 2, .center_freq = 2417},
- { .hw_value = 3, .center_freq = 2422},
- { .hw_value = 4, .center_freq = 2427},
- { .hw_value = 5, .center_freq = 2432},
- { .hw_value = 6, .center_freq = 2437},
- { .hw_value = 7, .center_freq = 2442},
- { .hw_value = 8, .center_freq = 2447},
- { .hw_value = 9, .center_freq = 2452},
- { .hw_value = 10, .center_freq = 2457},
- { .hw_value = 11, .center_freq = 2462},
- { .hw_value = 12, .center_freq = 2467},
- { .hw_value = 13, .center_freq = 2472},
-};
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_supported_band stlc45xx_band_2ghz = {
- .channels = stlc45xx_channels,
- .n_channels = ARRAY_SIZE(stlc45xx_channels),
- .bitrates = stlc45xx_rates,
- .n_bitrates = ARRAY_SIZE(stlc45xx_rates),
-};
-
-static const struct ieee80211_ops stlc45xx_ops = {
- .start = stlc45xx_op_start,
- .stop = stlc45xx_op_stop,
- .add_interface = stlc45xx_op_add_interface,
- .remove_interface = stlc45xx_op_remove_interface,
- .config = stlc45xx_op_config,
- .configure_filter = stlc45xx_op_configure_filter,
- .tx = stlc45xx_op_tx,
- .bss_info_changed = stlc45xx_op_bss_info_changed,
-};
-
-static int stlc45xx_register_mac80211(struct stlc45xx *stlc)
-{
- /* FIXME: SET_IEEE80211_PERM_ADDR() requires default_mac_addr
- to be non-const for some strange reason */
- static u8 default_mac_addr[ETH_ALEN] = {
- 0x00, 0x02, 0xee, 0xc0, 0xff, 0xee
- };
- int ret;
-
- SET_IEEE80211_PERM_ADDR(stlc->hw, default_mac_addr);
-
- ret = ieee80211_register_hw(stlc->hw);
- if (ret) {
- stlc45xx_error("unable to register mac80211 hw: %d", ret);
- return ret;
- }
-
- return 0;
-}
-
-static void stlc45xx_device_release(struct device *dev)
-{
-
-}
-
-static struct platform_device stlc45xx_device = {
- .name = "stlc45xx",
- .id = -1,
-
- /* device model insists to have a release function */
- .dev = {
- .release = stlc45xx_device_release,
- },
-};
-
-static int __devinit stlc45xx_probe(struct spi_device *spi)
-{
- struct stlc45xx *stlc;
- struct ieee80211_hw *hw;
- int ret;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- /* mac80211 alloc */
- hw = ieee80211_alloc_hw(sizeof(*stlc), &stlc45xx_ops);
- if (!hw) {
- stlc45xx_error("could not alloc ieee80211_hw");
- ret = -ENOMEM;
- goto out;
- }
-
- /* mac80211 clears hw->priv */
- stlc = hw->priv;
-
- stlc->hw = hw;
- dev_set_drvdata(&spi->dev, stlc);
- stlc->spi = spi;
-
- spi->bits_per_word = 16;
- spi->max_speed_hz = 24000000;
-
- ret = spi_setup(spi);
- if (ret < 0)
- stlc45xx_error("spi_setup failed");
-
- ret = gpio_request(stlc45xx_gpio_power, "stlc45xx power");
- if (ret < 0) {
- stlc45xx_error("power GPIO request failed: %d", ret);
- return ret;
- }
-
- ret = gpio_request(stlc45xx_gpio_irq, "stlc45xx irq");
- if (ret < 0) {
- stlc45xx_error("irq GPIO request failed: %d", ret);
- goto out;
- }
-
- gpio_direction_output(stlc45xx_gpio_power, 0);
- gpio_direction_input(stlc45xx_gpio_irq);
-
- ret = request_irq(gpio_to_irq(stlc45xx_gpio_irq),
- stlc45xx_interrupt, IRQF_DISABLED, "stlc45xx",
- stlc->spi);
- if (ret < 0)
- /* FIXME: handle the error */
- stlc45xx_error("request_irq() failed");
-
- set_irq_type(gpio_to_irq(stlc45xx_gpio_irq),
- IRQ_TYPE_EDGE_RISING);
-
- disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
-
- ret = platform_device_register(&stlc45xx_device);
- if (ret) {
- stlc45xx_error("Couldn't register wlan_omap device.");
- return ret;
- }
- dev_set_drvdata(&stlc45xx_device.dev, stlc);
-
- INIT_WORK(&stlc->work, stlc45xx_work);
- INIT_WORK(&stlc->work_reset, stlc45xx_work_reset);
- INIT_DELAYED_WORK(&stlc->work_tx_timeout, stlc45xx_work_tx_timeout);
- mutex_init(&stlc->mutex);
- init_completion(&stlc->fw_comp);
- spin_lock_init(&stlc->tx_lock);
- INIT_LIST_HEAD(&stlc->txbuffer);
- INIT_LIST_HEAD(&stlc->tx_pending);
- INIT_LIST_HEAD(&stlc->tx_sent);
-
- hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_SIGNAL_DBM |
- IEEE80211_HW_NOISE_DBM;
- /* four bytes for padding */
- hw->extra_tx_headroom = sizeof(struct s_lm_data_out) + 4;
-
- /* unit us */
- hw->channel_change_time = 1000;
-
- hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
- hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &stlc45xx_band_2ghz;
-
- SET_IEEE80211_DEV(hw, &spi->dev);
-
- BUILD_BUG_ON(sizeof(default_cal_rssi) != RSSI_CAL_ARRAY_LEN);
- BUILD_BUG_ON(sizeof(default_cal_channels) != CHANNEL_CAL_ARRAY_LEN);
-
- stlc->cal_rssi = kmemdup(default_cal_rssi, RSSI_CAL_ARRAY_LEN,
- GFP_KERNEL);
- stlc->cal_channels = kmemdup(default_cal_channels,
- CHANNEL_CAL_ARRAY_LEN,
- GFP_KERNEL);
-
- ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_rssi);
- if (ret < 0) {
- stlc45xx_error("failed to create sysfs file cal_rssi");
- goto out;
- }
-
- ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_channels);
- if (ret < 0) {
- stlc45xx_error("failed to create sysfs file cal_channels");
- goto out;
- }
-
- ret = device_create_file(&stlc45xx_device.dev, &dev_attr_tx_buf);
- if (ret < 0) {
- stlc45xx_error("failed to create sysfs file tx_buf");
- goto out;
- }
-
- ret = stlc45xx_register_mac80211(stlc);
- if (ret < 0)
- goto out;
-
- stlc45xx_info("v" DRIVER_VERSION " loaded");
-
- stlc45xx_info("config buffer 0x%x-0x%x",
- FIRMWARE_CONFIG_START, FIRMWARE_CONFIG_END);
- stlc45xx_info("tx 0x%x-0x%x, rx 0x%x-0x%x",
- FIRMWARE_TXBUFFER_START, FIRMWARE_TXBUFFER_END,
- FIRMWARE_RXBUFFER_START, FIRMWARE_RXBUFFER_END);
-
-out:
- return ret;
-}
-
-static int __devexit stlc45xx_remove(struct spi_device *spi)
-{
- struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- platform_device_unregister(&stlc45xx_device);
-
- ieee80211_unregister_hw(stlc->hw);
-
- free_irq(gpio_to_irq(stlc45xx_gpio_irq), spi);
-
- gpio_free(stlc45xx_gpio_power);
- gpio_free(stlc45xx_gpio_irq);
-
- /* FIXME: free cal_channels and cal_rssi? */
-
- kfree(stlc->fw);
-
- mutex_destroy(&stlc->mutex);
-
- /* frees also stlc */
- ieee80211_free_hw(stlc->hw);
- stlc = NULL;
-
- return 0;
-}
-
-
-static struct spi_driver stlc45xx_spi_driver = {
- .driver = {
- /* use cx3110x name because board-n800.c uses that for the
- * SPI port */
- .name = "cx3110x",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = stlc45xx_probe,
- .remove = __devexit_p(stlc45xx_remove),
-};
-
-static int __init stlc45xx_init(void)
-{
- int ret;
-
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- ret = spi_register_driver(&stlc45xx_spi_driver);
- if (ret < 0) {
- stlc45xx_error("failed to register SPI driver: %d", ret);
- goto out;
- }
-
-out:
- return ret;
-}
-
-static void __exit stlc45xx_exit(void)
-{
- stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
- spi_unregister_driver(&stlc45xx_spi_driver);
-
- stlc45xx_info("unloaded");
-}
-
-module_init(stlc45xx_init);
-module_exit(stlc45xx_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
-MODULE_ALIAS("spi:cx3110x");
diff --git a/drivers/staging/stlc45xx/stlc45xx.h b/drivers/staging/stlc45xx/stlc45xx.h
deleted file mode 100644
index ac96bbbde79f..000000000000
--- a/drivers/staging/stlc45xx/stlc45xx.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * This file is part of stlc45xx
- *
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Contact: Kalle Valo <kalle.valo@nokia.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.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/mutex.h>
-#include <linux/list.h>
-#include <net/mac80211.h>
-
-#include "stlc45xx_lmac.h"
-
-#define DRIVER_NAME "stlc45xx"
-#define DRIVER_VERSION "0.1.3"
-
-#define DRIVER_PREFIX DRIVER_NAME ": "
-
-enum {
- DEBUG_NONE = 0,
- DEBUG_FUNC = 1 << 0,
- DEBUG_IRQ = 1 << 1,
- DEBUG_BH = 1 << 2,
- DEBUG_RX = 1 << 3,
- DEBUG_RX_CONTENT = 1 << 5,
- DEBUG_TX = 1 << 6,
- DEBUG_TX_CONTENT = 1 << 8,
- DEBUG_TXBUFFER = 1 << 9,
- DEBUG_QUEUE = 1 << 10,
- DEBUG_BOOT = 1 << 11,
- DEBUG_PSM = 1 << 12,
- DEBUG_ALL = ~0,
-};
-
-#define DEBUG_LEVEL DEBUG_NONE
-/* #define DEBUG_LEVEL DEBUG_ALL */
-/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_RX | DEBUG_IRQ) */
-/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_MEMREGION | DEBUG_QUEUE) */
-/* #define DEBUG_LEVEL (DEBUG_MEMREGION | DEBUG_QUEUE) */
-
-#define stlc45xx_error(fmt, arg...) \
- printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
-
-#define stlc45xx_warning(fmt, arg...) \
- printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
-
-#define stlc45xx_info(fmt, arg...) \
- printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
-
-#define stlc45xx_debug(level, fmt, arg...) \
- do { \
- if (level & DEBUG_LEVEL) \
- printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
- } while (0)
-
-#define stlc45xx_dump(level, buf, len) \
- do { \
- if (level & DEBUG_LEVEL) \
- print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \
- 16, 1, buf, len, 1); \
- } while (0)
-
-#define MAC2STR(a) ((a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5])
-#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
-
-/* Bit 15 is read/write bit; ON = READ, OFF = WRITE */
-#define ADDR_READ_BIT_15 0x8000
-
-#define SPI_ADRS_ARM_INTERRUPTS 0x00
-#define SPI_ADRS_ARM_INT_EN 0x04
-
-#define SPI_ADRS_HOST_INTERRUPTS 0x08
-#define SPI_ADRS_HOST_INT_EN 0x0c
-#define SPI_ADRS_HOST_INT_ACK 0x10
-
-#define SPI_ADRS_GEN_PURP_1 0x14
-#define SPI_ADRS_GEN_PURP_2 0x18
-
-/* high word */
-#define SPI_ADRS_DEV_CTRL_STAT 0x26
-
-#define SPI_ADRS_DMA_DATA 0x28
-
-#define SPI_ADRS_DMA_WRITE_CTRL 0x2c
-#define SPI_ADRS_DMA_WRITE_LEN 0x2e
-#define SPI_ADRS_DMA_WRITE_BASE 0x30
-
-#define SPI_ADRS_DMA_READ_CTRL 0x34
-#define SPI_ADRS_DMA_READ_LEN 0x36
-#define SPI_ADRS_DMA_READ_BASE 0x38
-
-#define SPI_CTRL_STAT_HOST_OVERRIDE 0x8000
-#define SPI_CTRL_STAT_START_HALTED 0x4000
-#define SPI_CTRL_STAT_RAM_BOOT 0x2000
-#define SPI_CTRL_STAT_HOST_RESET 0x1000
-#define SPI_CTRL_STAT_HOST_CPU_EN 0x0800
-
-#define SPI_DMA_WRITE_CTRL_ENABLE 0x0001
-#define SPI_DMA_READ_CTRL_ENABLE 0x0001
-#define HOST_ALLOWED (1 << 7)
-
-#define FIRMWARE_ADDRESS 0x20000
-
-#define SPI_TIMEOUT 100 /* msec */
-
-#define SPI_MAX_TX_PACKETS 32
-
-#define SPI_MAX_PACKET_SIZE 32767
-
-#define SPI_TARGET_INT_WAKEUP 0x00000001
-#define SPI_TARGET_INT_SLEEP 0x00000002
-#define SPI_TARGET_INT_RDDONE 0x00000004
-
-#define SPI_TARGET_INT_CTS 0x00004000
-#define SPI_TARGET_INT_DR 0x00008000
-
-#define SPI_HOST_INT_READY 0x00000001
-#define SPI_HOST_INT_WR_READY 0x00000002
-#define SPI_HOST_INT_SW_UPDATE 0x00000004
-#define SPI_HOST_INT_UPDATE 0x10000000
-
-/* clear to send */
-#define SPI_HOST_INT_CTS 0x00004000
-
-/* data ready */
-#define SPI_HOST_INT_DR 0x00008000
-
-#define SPI_HOST_INTS_DEFAULT \
- (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE)
-
-#define TARGET_BOOT_SLEEP 50
-
-/* The firmware buffer is divided into three areas:
- *
- * o config area (for control commands)
- * o tx buffer
- * o rx buffer
- */
-#define FIRMWARE_BUFFER_START 0x20200
-#define FIRMWARE_BUFFER_END 0x27c60
-#define FIRMWARE_BUFFER_LEN (FIRMWARE_BUFFER_END - FIRMWARE_BUFFER_START)
-#define FIRMWARE_MTU 3240
-#define FIRMWARE_CONFIG_PAYLOAD_LEN 1024
-#define FIRMWARE_CONFIG_START FIRMWARE_BUFFER_START
-#define FIRMWARE_CONFIG_LEN (sizeof(struct s_lm_control) + \
- FIRMWARE_CONFIG_PAYLOAD_LEN)
-#define FIRMWARE_CONFIG_END (FIRMWARE_CONFIG_START + FIRMWARE_CONFIG_LEN - 1)
-#define FIRMWARE_RXBUFFER_LEN (5 * FIRMWARE_MTU + 1024)
-#define FIRMWARE_RXBUFFER_START (FIRMWARE_BUFFER_END - FIRMWARE_RXBUFFER_LEN)
-#define FIRMWARE_RXBUFFER_END (FIRMWARE_RXBUFFER_START + \
- FIRMWARE_RXBUFFER_LEN - 1)
-#define FIRMWARE_TXBUFFER_START (FIRMWARE_BUFFER_START + FIRMWARE_CONFIG_LEN)
-#define FIRMWARE_TXBUFFER_LEN (FIRMWARE_BUFFER_LEN - FIRMWARE_CONFIG_LEN - \
- FIRMWARE_RXBUFFER_LEN)
-#define FIRMWARE_TXBUFFER_END (FIRMWARE_TXBUFFER_START + \
- FIRMWARE_TXBUFFER_LEN - 1)
-
-#define FIRMWARE_TXBUFFER_HEADER 100
-#define FIRMWARE_TXBUFFER_TRAILER 4
-
-/* FIXME: come up with a proper value */
-#define MAX_FRAME_LEN 2500
-
-/* unit is ms */
-#define TX_FRAME_LIFETIME 2000
-#define TX_TIMEOUT 4000
-
-#define SUPPORTED_CHANNELS 13
-
-/* FIXME */
-/* #define CHANNEL_CAL_LEN offsetof(struct s_lmo_scan, bratemask) - \ */
-/* offsetof(struct s_lmo_scan, channel) */
-#define CHANNEL_CAL_LEN 292
-#define CHANNEL_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * CHANNEL_CAL_LEN)
-/* FIXME */
-/* #define RSSI_CAL_LEN sizeof(struct s_lmo_scan) - \ */
-/* offsetof(struct s_lmo_scan, rssical) */
-#define RSSI_CAL_LEN 8
-#define RSSI_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * RSSI_CAL_LEN)
-
-struct s_dma_regs {
- unsigned short cmd;
- unsigned short len;
- unsigned long addr;
-};
-
-struct stlc45xx_ie_tim {
- u8 dtim_count;
- u8 dtim_period;
- u8 bmap_control;
- u8 pvbmap[251];
-};
-
-struct txbuffer {
- /* can be removed when switched to skb queue */
- struct list_head tx_list;
-
- struct list_head buffer_list;
-
- int start;
- int frame_start;
- int end;
-
- struct sk_buff *skb;
- u32 handle;
-
- bool status_needed;
-
- int header_len;
-
- /* unit jiffies */
- unsigned long lifetime;
-};
-
-enum fw_state {
- FW_STATE_OFF,
- FW_STATE_BOOTING,
- FW_STATE_READY,
- FW_STATE_RESET,
- FW_STATE_RESETTING,
-};
-
-struct stlc45xx {
- struct ieee80211_hw *hw;
- struct spi_device *spi;
- struct work_struct work;
- struct work_struct work_reset;
- struct delayed_work work_tx_timeout;
- struct mutex mutex;
- struct completion fw_comp;
-
-
- u8 bssid[ETH_ALEN];
- u8 mac_addr[ETH_ALEN];
- int channel;
-
- u8 *cal_rssi;
- u8 *cal_channels;
-
- enum fw_state fw_state;
-
- spinlock_t tx_lock;
-
- /* protected by tx_lock */
- struct list_head txbuffer;
-
- /* protected by tx_lock */
- struct list_head tx_pending;
-
- /* protected by tx_lock */
- int tx_queue_stopped;
-
- /* protected by mutex */
- struct list_head tx_sent;
-
- int tx_frames;
-
- u8 *fw;
- int fw_len;
-
- bool psm;
- bool associated;
- int aid;
- bool pspolling;
-};
-
-
diff --git a/drivers/staging/stlc45xx/stlc45xx_lmac.h b/drivers/staging/stlc45xx/stlc45xx_lmac.h
deleted file mode 100644
index af5db801347f..000000000000
--- a/drivers/staging/stlc45xx/stlc45xx_lmac.h
+++ /dev/null
@@ -1,434 +0,0 @@
-/************************************************************************
-* This is the LMAC API interface header file for STLC4560. *
-* Copyright (C) 2007 Conexant Systems, 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. *
-* *
-* 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 <http://www.gnu.org/licenses/>.*
-*************************************************************************/
-
-#ifndef __lmac_h__
-#define __lmac_h__
-
-#define LM_TOP_VARIANT 0x0506
-#define LM_BOTTOM_VARIANT 0x0506
-
-/*
- * LMAC - UMAC interface definition:
- */
-
-#define LM_FLAG_CONTROL 0x8000
-#define LM_FLAG_ALIGN 0x4000
-
-#define LM_CTRL_OPSET 0x0001
-
-#define LM_OUT_PROMISC 0x0001
-#define LM_OUT_TIMESTAMP 0x0002
-#define LM_OUT_SEQNR 0x0004
-#define LM_OUT_BURST 0x0010
-#define LM_OUT_NOCANCEL 0x0020
-#define LM_OUT_CLEARTIM 0x0040
-#define LM_OUT_HITCHHIKE 0x0080
-#define LM_OUT_COMPRESS 0x0100
-#define LM_OUT_CONCAT 0x0200
-#define LM_OUT_PCS_ACCEPT 0x0400
-#define LM_OUT_WAITEOSP 0x0800
-
-
-#define LM_ALOFT_SP 0x10
-#define LM_ALOFT_CTS 0x20
-#define LM_ALOFT_RTS 0x40
-#define LM_ALOFT_MASK 0x1f
-#define LM_ALOFT_RATE 0x0f
-
-#define LM_IN_FCS_GOOD 0x0001
-#define LM_IN_MATCH_MAC 0x0002
-#define LM_IN_MCBC 0x0004
-#define LM_IN_BEACON 0x0008
-#define LM_IN_MATCH_BSS 0x0010
-#define LM_IN_BCAST_BSS 0x0020
-#define LM_IN_DATA 0x0040
-#define LM_IN_TRUNCATED 0x0080
-
-#define LM_IN_TRANSPARENT 0x0200
-
-#define LM_QUEUE_BEACON 0
-#define LM_QUEUE_SCAN 1
-#define LM_QUEUE_MGT 2
-#define LM_QUEUE_MCBC 3
-#define LM_QUEUE_DATA 4
-#define LM_QUEUE_DATA0 4
-#define LM_QUEUE_DATA1 5
-#define LM_QUEUE_DATA2 6
-#define LM_QUEUE_DATA3 7
-
-#define LM_SETUP_INFRA 0x0001
-#define LM_SETUP_IBSS 0x0002
-#define LM_SETUP_TRANSPARENT 0x0008
-#define LM_SETUP_PROMISCUOUS 0x0010
-#define LM_SETUP_HIBERNATE 0x0020
-#define LM_SETUP_NOACK 0x0040
-#define LM_SETUP_RX_DISABLED 0x0080
-
-#define LM_ANTENNA_0 0
-#define LM_ANTENNA_1 1
-#define LM_ANTENNA_DIVERSITY 2
-
-#define LM_TX_FAILED 0x0001
-#define LM_TX_PSM 0x0002
-#define LM_TX_PSM_CANCELLED 0x0004
-
-#define LM_SCAN_EXIT 0x0001
-#define LM_SCAN_TRAP 0x0002
-#define LM_SCAN_ACTIVE 0x0004
-#define LM_SCAN_FILTER 0x0008
-
-#define LM_PSM 0x0001
-#define LM_PSM_DTIM 0x0002
-#define LM_PSM_MCBC 0x0004
-#define LM_PSM_CHECKSUM 0x0008
-#define LM_PSM_SKIP_MORE_DATA 0x0010
-#define LM_PSM_BEACON_TIMEOUT 0x0020
-#define LM_PSM_HFOSLEEP 0x0040
-#define LM_PSM_AUTOSWITCH_SLEEP 0x0080
-#define LM_PSM_LPIT 0x0100
-#define LM_PSM_BF_UCAST_SKIP 0x0200
-#define LM_PSM_BF_MCAST_SKIP 0x0400
-
-/* hfosleep */
-#define LM_PSM_SLEEP_OPTION_MASK (LM_PSM_AUTOSWITCH_SLEEP | LM_PSM_HFOSLEEP)
-#define LM_PSM_SLEEP_OPTION_SHIFT 6
-/* hfosleepend */
-#define LM_PSM_BF_OPTION_MASK (LM_PSM_BF_MCAST_SKIP | LM_PSM_BF_UCAST_SKIP)
-#define LM_PSM_BF_OPTION_SHIFT 9
-
-
-#define LM_PRIVACC_WEP 0x01
-#define LM_PRIVACC_TKIP 0x02
-#define LM_PRIVACC_MICHAEL 0x04
-#define LM_PRIVACC_CCX_KP 0x08
-#define LM_PRIVACC_CCX_MIC 0x10
-#define LM_PRIVACC_AES_CCMP 0x20
-
-/* size of s_lm_descr in words */
-#define LM_DESCR_SIZE_WORDS 11
-
-#ifndef __ASSEMBLER__
-
-enum {
- LM_MODE_CLIENT = 0,
- LM_MODE_AP
-};
-
-struct s_lm_descr {
- uint16_t modes;
- uint16_t flags;
- uint32_t buffer_start;
- uint32_t buffer_end;
- uint8_t header;
- uint8_t trailer;
- uint8_t tx_queues;
- uint8_t tx_depth;
- uint8_t privacy;
- uint8_t rx_keycache;
- uint8_t tim_size;
- uint8_t pad1;
- uint8_t rates[16];
- uint32_t link;
- uint16_t mtu;
-};
-
-
-struct s_lm_control {
- uint16_t flags;
- uint16_t length;
- uint32_t handle;
- uint16_t oid;
- uint16_t pad;
- /* uint8_t data[]; */
-};
-
-enum {
- LM_PRIV_NONE = 0,
- LM_PRIV_WEP,
- LM_PRIV_TKIP,
- LM_PRIV_TKIPMICHAEL,
- LM_PRIV_CCX_WEPMIC,
- LM_PRIV_CCX_KPMIC,
- LM_PRIV_CCX_KP,
- LM_PRIV_AES_CCMP
-};
-
-enum {
- LM_DECRYPT_NONE,
- LM_DECRYPT_OK,
- LM_DECRYPT_NOKEY,
- LM_DECRYPT_NOMICHAEL,
- LM_DECRYPT_NOCKIPMIC,
- LM_DECRYPT_FAIL_WEP,
- LM_DECRYPT_FAIL_TKIP,
- LM_DECRYPT_FAIL_MICHAEL,
- LM_DECRYPT_FAIL_CKIPKP,
- LM_DECRYPT_FAIL_CKIPMIC,
- LM_DECRYPT_FAIL_AESCCMP
-};
-
-struct s_lm_data_out {
- uint16_t flags;
- uint16_t length;
- uint32_t handle;
- uint16_t aid;
- uint8_t rts_retries;
- uint8_t retries;
- uint8_t aloft[8];
- uint8_t aloft_ctrl;
- uint8_t crypt_offset;
- uint8_t keytype;
- uint8_t keylen;
- uint8_t key[16];
- uint8_t queue;
- uint8_t backlog;
- uint16_t durations[4];
- uint8_t antenna;
- uint8_t cts;
- int16_t power;
- uint8_t pad[2];
- /*uint8_t data[];*/
-};
-
-#define LM_RCPI_INVALID (0xff)
-
-struct s_lm_data_in {
- uint16_t flags;
- uint16_t length;
- uint16_t frequency;
- uint8_t antenna;
- uint8_t rate;
- uint8_t rcpi;
- uint8_t sq;
- uint8_t decrypt;
- uint8_t rssi_raw;
- uint32_t clock[2];
- /*uint8_t data[];*/
-};
-
-union u_lm_data {
- struct s_lm_data_out out;
- struct s_lm_data_in in;
-};
-
-enum {
- LM_OID_SETUP = 0,
- LM_OID_SCAN = 1,
- LM_OID_TRAP = 2,
- LM_OID_EDCF = 3,
- LM_OID_KEYCACHE = 4,
- LM_OID_PSM = 6,
- LM_OID_TXCANCEL = 7,
- LM_OID_TX = 8,
- LM_OID_BURST = 9,
- LM_OID_STATS = 10,
- LM_OID_LED = 13,
- LM_OID_TIMER = 15,
- LM_OID_NAV = 20,
- LM_OID_PCS = 22,
- LM_OID_BT_BALANCER = 28,
- LM_OID_GROUP_ADDRESS_TABLE = 30,
- LM_OID_ARPTABLE = 31,
- LM_OID_BT_OPTIONS = 35
-};
-
-enum {
- LM_FRONTEND_UNKNOWN = 0,
- LM_FRONTEND_DUETTE3,
- LM_FRONTEND_DUETTE2,
- LM_FRONTEND_FRISBEE,
- LM_FRONTEND_CROSSBOW,
- LM_FRONTEND_LONGBOW
-};
-
-
-#define INVALID_LPF_BANDWIDTH 0xffff
-#define INVALID_OSC_START_DELAY 0xffff
-
-struct s_lmo_setup {
- uint16_t flags;
- uint8_t macaddr[6];
- uint8_t bssid[6];
- uint8_t antenna;
- uint8_t rx_align;
- uint32_t rx_buffer;
- uint16_t rx_mtu;
- uint16_t frontend;
- uint16_t timeout;
- uint16_t truncate;
- uint32_t bratemask;
- uint8_t sbss_offset;
- uint8_t mcast_window;
- uint8_t rx_rssi_threshold;
- uint8_t rx_ed_threshold;
- uint32_t ref_clock;
- uint16_t lpf_bandwidth;
- uint16_t osc_start_delay;
-};
-
-
-struct s_lmo_scan {
- uint16_t flags;
- uint16_t dwell;
- uint8_t channel[292];
- uint32_t bratemask;
- uint8_t aloft[8];
- uint8_t rssical[8];
-};
-
-
-enum {
- LM_TRAP_SCAN = 0,
- LM_TRAP_TIMER,
- LM_TRAP_BEACON_TX,
- LM_TRAP_FAA_RADIO_ON,
- LM_TRAP_FAA_RADIO_OFF,
- LM_TRAP_RADAR,
- LM_TRAP_NO_BEACON,
- LM_TRAP_TBTT,
- LM_TRAP_SCO_ENTER,
- LM_TRAP_SCO_EXIT
-};
-
-struct s_lmo_trap {
- uint16_t event;
- uint16_t frequency;
-};
-
-struct s_lmo_timer {
- uint32_t interval;
-};
-
-struct s_lmo_nav {
- uint32_t period;
-};
-
-
-struct s_lmo_edcf_queue;
-
-struct s_lmo_edcf {
- uint8_t flags;
- uint8_t slottime;
- uint8_t sifs;
- uint8_t eofpad;
- struct s_lmo_edcf_queue {
- uint8_t aifs;
- uint8_t pad0;
- uint16_t cwmin;
- uint16_t cwmax;
- uint16_t txop;
- } queues[8];
- uint8_t mapping[4];
- uint16_t maxburst;
- uint16_t round_trip_delay;
-};
-
-struct s_lmo_keycache {
- uint8_t entry;
- uint8_t keyid;
- uint8_t address[6];
- uint8_t pad[2];
- uint8_t keytype;
- uint8_t keylen;
- uint8_t key[24];
-};
-
-
-struct s_lm_interval;
-
-struct s_lmo_psm {
- uint16_t flags;
- uint16_t aid;
- struct s_lm_interval {
- uint16_t interval;
- uint16_t periods;
- } intervals[4];
- /* uint16_t pad; */
- uint8_t beacon_rcpi_skip_max;
- uint8_t rcpi_delta_threshold;
- uint8_t nr;
- uint8_t exclude[1];
-};
-
-#define MC_FILTER_ADDRESS_NUM 4
-
-struct s_lmo_group_address_table {
- uint16_t filter_enable;
- uint16_t num_address;
- uint8_t macaddr_list[MC_FILTER_ADDRESS_NUM][6];
-};
-
-struct s_lmo_txcancel {
- uint32_t address[1];
-};
-
-
-struct s_lmo_tx {
- uint8_t flags;
- uint8_t retries;
- uint8_t rcpi;
- uint8_t sq;
- uint16_t seqctrl;
- uint8_t antenna;
- uint8_t pad;
-};
-
-struct s_lmo_burst {
- uint8_t flags;
- uint8_t queue;
- uint8_t backlog;
- uint8_t pad;
- uint16_t durations[32];
-};
-
-struct s_lmo_stats {
- uint32_t valid;
- uint32_t fcs;
- uint32_t abort;
- uint32_t phyabort;
- uint32_t rts_success;
- uint32_t rts_fail;
- uint32_t timestamp;
- uint32_t time_tx;
- uint32_t noisefloor;
- uint32_t sample_noise[8];
- uint32_t sample_cca;
- uint32_t sample_tx;
-};
-
-
-struct s_lmo_led {
- uint16_t flags;
- uint16_t mask[2];
- uint16_t delay/*[2]*/;
-};
-
-
-struct s_lmo_bt_balancer {
- uint16_t prio_thresh;
- uint16_t acl_thresh;
-};
-
-
-struct s_lmo_arp_table {
- uint16_t filter_enable;
- uint32_t ipaddr;
-};
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* __lmac_h__ */
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c
index 3d2a84c45829..e139eaeaa174 100644
--- a/drivers/staging/vme/bridges/vme_ca91cx42.c
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.c
@@ -25,6 +25,7 @@
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/sched.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index 8960fa9ee7aa..00fe0803c21c 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -25,6 +25,7 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/sched.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/staging/vt6655/TODO b/drivers/staging/vt6655/TODO
index 8462cd17eb61..cb04aaafc46f 100644
--- a/drivers/staging/vt6655/TODO
+++ b/drivers/staging/vt6655/TODO
@@ -16,6 +16,5 @@ TODO:
- sparse fixes
- integrate with drivers/net/wireless
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>,
-Forest Bond <forest@alittletooquiet.net> and Bartlomiej Zolnierkiewicz
-<bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
+and Forest Bond <forest@alittletooquiet.net>.
diff --git a/drivers/staging/vt6656/TODO b/drivers/staging/vt6656/TODO
index 17cf50c6735e..a318995ba07f 100644
--- a/drivers/staging/vt6656/TODO
+++ b/drivers/staging/vt6656/TODO
@@ -15,6 +15,5 @@ TODO:
- sparse fixes
- integrate with drivers/net/wireless
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>,
-Forest Bond <forest@alittletooquiet.net> and Bartlomiej Zolnierkiewicz
-<bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
+and Forest Bond <forest@alittletooquiet.net>.
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 7f96bcaf1c60..05186110c029 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -1332,7 +1332,6 @@ device_release_WPADEV(pDevice);
free_netdev(pDevice->dev);
}
- kfree(pDevice);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect3.. \n");
}
diff --git a/drivers/staging/winbond/Kconfig b/drivers/staging/winbond/Kconfig
index 940460c39f36..132671d96d0d 100644
--- a/drivers/staging/winbond/Kconfig
+++ b/drivers/staging/winbond/Kconfig
@@ -1,6 +1,6 @@
config W35UND
tristate "IS89C35 WLAN USB driver"
- depends on MAC80211 && WLAN_80211 && USB && EXPERIMENTAL
+ depends on MAC80211 && WLAN && USB && EXPERIMENTAL
default n
---help---
This is highly experimental driver for Winbond WIFI card.
diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig
index 9959b658c8cf..f44294b0d8dc 100644
--- a/drivers/staging/wlan-ng/Kconfig
+++ b/drivers/staging/wlan-ng/Kconfig
@@ -1,6 +1,6 @@
config PRISM2_USB
tristate "Prism2.5/3 USB driver"
- depends on WLAN_80211 && USB && WIRELESS_EXT
+ depends on WLAN && USB && WIRELESS_EXT
default n
---help---
This is the wlan-ng prism 2.5/3 USB driver for a wide range of
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index 347c3ed1d9f1..d442fd35620a 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -19,13 +19,6 @@
* PCMCIA service support for Quicknet cards
*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
typedef struct ixj_info_t {
int ndev;
@@ -39,7 +32,7 @@ static void ixj_cs_release(struct pcmcia_device * link);
static int ixj_probe(struct pcmcia_device *p_dev)
{
- DEBUG(0, "ixj_attach()\n");
+ dev_dbg(&p_dev->dev, "ixj_attach()\n");
/* Create new ixj device */
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
@@ -55,33 +48,30 @@ static int ixj_probe(struct pcmcia_device *p_dev)
static void ixj_detach(struct pcmcia_device *link)
{
- DEBUG(0, "ixj_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "ixj_detach\n");
ixj_cs_release(link);
kfree(link->priv);
}
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
{
char *str;
int i, place;
- DEBUG(0, "ixj_get_serial(0x%p)\n", link);
+ dev_dbg(&link->dev, "ixj_get_serial\n");
str = link->prod_id[0];
if (!str)
- goto cs_failed;
+ goto failed;
printk("%s", str);
str = link->prod_id[1];
if (!str)
- goto cs_failed;
+ goto failed;
printk(" %s", str);
str = link->prod_id[2];
if (!str)
- goto cs_failed;
+ goto failed;
place = 1;
for (i = strlen(str) - 1; i >= 0; i--) {
switch (str[i]) {
@@ -118,9 +108,9 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
}
str = link->prod_id[3];
if (!str)
- goto cs_failed;
+ goto failed;
printk(" version %s\n", str);
- cs_failed:
+failed:
return;
}
@@ -151,13 +141,13 @@ static int ixj_config(struct pcmcia_device * link)
cistpl_cftable_entry_t dflt = { 0 };
info = link->priv;
- DEBUG(0, "ixj_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "ixj_config\n");
if (pcmcia_loop_config(link, ixj_config_check, &dflt))
- goto cs_failed;
+ goto failed;
if (pcmcia_request_configuration(link, &link->conf))
- goto cs_failed;
+ goto failed;
/*
* Register the card with the core.
@@ -170,7 +160,7 @@ static int ixj_config(struct pcmcia_device * link)
ixj_get_serial(link, j);
return 0;
- cs_failed:
+failed:
ixj_cs_release(link);
return -ENODEV;
}
@@ -178,7 +168,7 @@ static int ixj_config(struct pcmcia_device * link)
static void ixj_cs_release(struct pcmcia_device *link)
{
ixj_info_t *info = link->priv;
- DEBUG(0, "ixj_cs_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "ixj_cs_release\n");
info->ndev = 0;
pcmcia_disable_device(link);
}
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 4e83c297ec9e..6f8d8f971212 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -180,15 +180,15 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
switch (type) {
case THERMAL_TRIP_CRITICAL:
- return sprintf(buf, "critical");
+ return sprintf(buf, "critical\n");
case THERMAL_TRIP_HOT:
- return sprintf(buf, "hot");
+ return sprintf(buf, "hot\n");
case THERMAL_TRIP_PASSIVE:
- return sprintf(buf, "passive");
+ return sprintf(buf, "passive\n");
case THERMAL_TRIP_ACTIVE:
- return sprintf(buf, "active");
+ return sprintf(buf, "active\n");
default:
- return sprintf(buf, "unknown");
+ return sprintf(buf, "unknown\n");
}
}
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index 02347c57357d..aa53db9f2e88 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -178,6 +178,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
return 0;
bad1:
kfree(priv);
+ pm_runtime_disable(&pdev->dev);
bad0:
return ret;
}
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index e3861b21e776..e4eca7810bcf 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -609,9 +609,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
acm->throttle = 0;
- tasklet_schedule(&acm->urb_task);
set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
rv = tty_port_block_til_ready(&acm->port, tty, filp);
+ tasklet_schedule(&acm->urb_task);
done:
mutex_unlock(&acm->mutex);
err_out:
@@ -686,15 +686,21 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
/* Perform the closing process and see if we need to do the hardware
shutdown */
- if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0)
+ if (!acm)
+ return;
+ if (tty_port_close_start(&acm->port, tty, filp) == 0) {
+ mutex_lock(&open_mutex);
+ if (!acm->dev) {
+ tty_port_tty_set(&acm->port, NULL);
+ acm_tty_unregister(acm);
+ tty->driver_data = NULL;
+ }
+ mutex_unlock(&open_mutex);
return;
+ }
acm_port_down(acm, 0);
tty_port_close_end(&acm->port, tty);
- mutex_lock(&open_mutex);
tty_port_tty_set(&acm->port, NULL);
- if (!acm->dev)
- acm_tty_unregister(acm);
- mutex_unlock(&open_mutex);
}
static int acm_tty_write(struct tty_struct *tty,
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5ce839137ad6..0f857e645058 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -444,7 +444,7 @@ resubmit:
static inline int
hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
{
- return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
+ return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo,
tt, NULL, 0, 1000);
}
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 33351312327f..a18e3c5dd82e 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -223,6 +223,7 @@ config USB_OTG
config USB_GADGET_PXA25X
boolean "PXA 25x or IXP 4xx"
depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX
+ select USB_OTG_UTILS
help
Intel's PXA 25x series XScale ARM-5TE processors include
an integrated full speed USB 1.1 device controller. The
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index d5b65962dd36..731150d4b1d9 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -1213,7 +1213,12 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp)
tmp &= AMD_UNMASK_BIT(ep->num);
writel(tmp, &dev->regs->ep_irqmsk);
}
- }
+ } else if (ep->in) {
+ /* enable ep irq */
+ tmp = readl(&dev->regs->ep_irqmsk);
+ tmp &= AMD_UNMASK_BIT(ep->num);
+ writel(tmp, &dev->regs->ep_irqmsk);
+ }
} else if (ep->dma) {
@@ -2005,18 +2010,17 @@ __acquires(dev->lock)
{
int tmp;
- /* empty queues and init hardware */
- udc_basic_init(dev);
- for (tmp = 0; tmp < UDC_EP_NUM; tmp++) {
- empty_req_queue(&dev->ep[tmp]);
- }
-
if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
spin_unlock(&dev->lock);
driver->disconnect(&dev->gadget);
spin_lock(&dev->lock);
}
- /* init */
+
+ /* empty queues and init hardware */
+ udc_basic_init(dev);
+ for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
+ empty_req_queue(&dev->ep[tmp]);
+
udc_setup_endpoints(dev);
}
@@ -2472,6 +2476,13 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix)
}
}
+ } else if (!use_dma && ep->in) {
+ /* disable interrupt */
+ tmp = readl(
+ &dev->regs->ep_irqmsk);
+ tmp |= AMD_BIT(ep->num);
+ writel(tmp,
+ &dev->regs->ep_irqmsk);
}
}
/* clear status bits */
@@ -3279,6 +3290,17 @@ static int udc_pci_probe(
goto finished;
}
+ spin_lock_init(&dev->lock);
+ /* udc csr registers base */
+ dev->csr = dev->virt_addr + UDC_CSR_ADDR;
+ /* dev registers base */
+ dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
+ /* ep registers base */
+ dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
+ /* fifo's base */
+ dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
+ dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
+
if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
kfree(dev);
@@ -3331,7 +3353,6 @@ static int udc_probe(struct udc *dev)
udc_pollstall_timer.data = 0;
/* device struct setup */
- spin_lock_init(&dev->lock);
dev->gadget.ops = &udc_ops;
dev_set_name(&dev->gadget.dev, "gadget");
@@ -3340,16 +3361,6 @@ static int udc_probe(struct udc *dev)
dev->gadget.name = name;
dev->gadget.is_dualspeed = 1;
- /* udc csr registers base */
- dev->csr = dev->virt_addr + UDC_CSR_ADDR;
- /* dev registers base */
- dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
- /* ep registers base */
- dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
- /* fifo's base */
- dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
- dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
-
/* init registers, interrupts, ... */
startup_registers(dev);
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index f37de283d0ab..167cb2a8ecef 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -61,11 +61,6 @@
* simpler, Microsoft pushes their own approach: RNDIS. The published
* RNDIS specs are ambiguous and appear to be incomplete, and are also
* needlessly complex. They borrow more from CDC ACM than CDC ECM.
- *
- * While CDC ECM, CDC Subset, and RNDIS are designed to extend the ethernet
- * interface to the target, CDC EEM was designed to use ethernet over the USB
- * link between the host and target. CDC EEM is implemented as an alternative
- * to those other protocols when that communication model is more appropriate
*/
#define DRIVER_DESC "Ethernet Gadget"
@@ -157,8 +152,8 @@ static inline bool has_rndis(void)
#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */
/* For EEM gadgets */
-#define EEM_VENDOR_NUM 0x0525 /* INVALID - NEEDS TO BE ALLOCATED */
-#define EEM_PRODUCT_NUM 0xa4a1 /* INVALID - NEEDS TO BE ALLOCATED */
+#define EEM_VENDOR_NUM 0x1d6b /* Linux Foundation */
+#define EEM_PRODUCT_NUM 0x0102 /* EEM Gadget */
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 42a74b8a0bb8..fa3d142ba64d 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -2139,7 +2139,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
static void fsl_udc_release(struct device *dev)
{
complete(udc_controller->done);
- dma_free_coherent(dev, udc_controller->ep_qh_size,
+ dma_free_coherent(dev->parent, udc_controller->ep_qh_size,
udc_controller->ep_qh, udc_controller->ep_qh_dma);
kfree(udc_controller);
}
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 9835e0713943..f5f5601701c9 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -28,6 +28,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
+#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
@@ -676,6 +677,7 @@ static int ehci_run (struct usb_hcd *hcd)
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
msleep(5);
up_write(&ehci_cf_port_reset_rwsem);
+ ehci->last_periodic_enable = ktime_get_real();
temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
ehci_info (ehci,
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 378861b9d79a..ead5f4f2aa5a 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -111,6 +111,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
switch (pdev->vendor) {
case PCI_VENDOR_ID_INTEL:
ehci->need_io_watchdog = 0;
+ if (pdev->device == 0x27cc) {
+ ehci->broken_periodic = 1;
+ ehci_info(ehci, "using broken periodic workaround\n");
+ }
break;
case PCI_VENDOR_ID_TDI:
if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 00ad9ce392ed..139a2cc3f641 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -487,8 +487,20 @@ halt:
* we must clear the TT buffer (11.17.5).
*/
if (unlikely(last_status != -EINPROGRESS &&
- last_status != -EREMOTEIO))
- ehci_clear_tt_buffer(ehci, qh, urb, token);
+ last_status != -EREMOTEIO)) {
+ /* The TT's in some hubs malfunction when they
+ * receive this request following a STALL (they
+ * stop sending isochronous packets). Since a
+ * STALL can't leave the TT buffer in a busy
+ * state (if you believe Figures 11-48 - 11-51
+ * in the USB 2.0 spec), we won't clear the TT
+ * buffer in this case. Strictly speaking this
+ * is a violation of the spec.
+ */
+ if (last_status != -EPIPE)
+ ehci_clear_tt_buffer(ehci, qh, urb,
+ token);
+ }
}
/* if we're removing something not at the queue head,
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 3efa59b18044..a5535b5e3fe2 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -475,6 +475,8 @@ static int enable_periodic (struct ehci_hcd *ehci)
/* make sure ehci_work scans these */
ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index)
% (ehci->periodic_size << 3);
+ if (unlikely(ehci->broken_periodic))
+ ehci->last_periodic_enable = ktime_get_real();
return 0;
}
@@ -486,6 +488,16 @@ static int disable_periodic (struct ehci_hcd *ehci)
if (--ehci->periodic_sched)
return 0;
+ if (unlikely(ehci->broken_periodic)) {
+ /* delay experimentally determined */
+ ktime_t safe = ktime_add_us(ehci->last_periodic_enable, 1000);
+ ktime_t now = ktime_get_real();
+ s64 delay = ktime_us_delta(safe, now);
+
+ if (unlikely(delay > 0))
+ udelay(delay);
+ }
+
/* did setting PSE not take effect yet?
* takes effect only at frame boundaries...
*/
@@ -1400,6 +1412,10 @@ iso_stream_schedule (
goto fail;
}
+ period = urb->interval;
+ if (!stream->highspeed)
+ period <<= 3;
+
now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
/* when's the last uframe this urb could start? */
@@ -1417,8 +1433,8 @@ iso_stream_schedule (
/* Fell behind (by up to twice the slop amount)? */
if (start >= max - 2 * 8 * SCHEDULE_SLOP)
- start += stream->interval * DIV_ROUND_UP(
- max - start, stream->interval) - mod;
+ start += period * DIV_ROUND_UP(
+ max - start, period) - mod;
/* Tried to schedule too far into the future? */
if (unlikely((start + sched->span) >= max)) {
@@ -1441,10 +1457,6 @@ iso_stream_schedule (
/* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
- period = urb->interval;
- if (!stream->highspeed)
- period <<= 3;
-
/* find a uframe slot with enough bandwidth */
for (; start < (stream->next_uframe + period); start++) {
int enough_space;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 064e76821ff5..2d85e21ff282 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -118,6 +118,7 @@ struct ehci_hcd { /* one per controller */
unsigned stamp;
unsigned random_frame;
unsigned long next_statechange;
+ ktime_t last_periodic_enable;
u32 command;
/* SILICON QUIRKS */
@@ -127,6 +128,7 @@ struct ehci_hcd { /* one per controller */
unsigned big_endian_desc:1;
unsigned has_amcc_usb23:1;
unsigned need_io_watchdog:1;
+ unsigned broken_periodic:1;
/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 78bb7710f36d..24eb74781919 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -87,6 +87,7 @@ static int ohci_restart (struct ohci_hcd *ohci);
#ifdef CONFIG_PCI
static void quirk_amd_pll(int state);
static void amd_iso_dev_put(void);
+static void sb800_prefetch(struct ohci_hcd *ohci, int on);
#else
static inline void quirk_amd_pll(int state)
{
@@ -96,6 +97,10 @@ static inline void amd_iso_dev_put(void)
{
return;
}
+static inline void sb800_prefetch(struct ohci_hcd *ohci, int on)
+{
+ return;
+}
#endif
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index d2ba04dd785e..b8a1148f248e 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -177,6 +177,13 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
return 0;
pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
+
+ /* SB800 needs pre-fetch fix */
+ if ((rev >= 0x40) && (rev <= 0x4f)) {
+ ohci->flags |= OHCI_QUIRK_AMD_PREFETCH;
+ ohci_dbg(ohci, "enabled AMD prefetch quirk\n");
+ }
+
if ((rev > 0x3b) || (rev < 0x30)) {
pci_dev_put(amd_smbus_dev);
amd_smbus_dev = NULL;
@@ -262,6 +269,19 @@ static void amd_iso_dev_put(void)
}
+static void sb800_prefetch(struct ohci_hcd *ohci, int on)
+{
+ struct pci_dev *pdev;
+ u16 misc;
+
+ pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller);
+ pci_read_config_word(pdev, 0x50, &misc);
+ if (on == 0)
+ pci_write_config_word(pdev, 0x50, misc & 0xfcff);
+ else
+ pci_write_config_word(pdev, 0x50, misc | 0x0300);
+}
+
/* List of quirks for OHCI */
static const struct pci_device_id ohci_pci_quirks[] = {
{
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 16fecb8ecc39..35288bcae0db 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -49,9 +49,12 @@ __acquires(ohci->lock)
switch (usb_pipetype (urb->pipe)) {
case PIPE_ISOCHRONOUS:
ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
- if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
- && quirk_amdiso(ohci))
- quirk_amd_pll(1);
+ if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
+ if (quirk_amdiso(ohci))
+ quirk_amd_pll(1);
+ if (quirk_amdprefetch(ohci))
+ sb800_prefetch(ohci, 0);
+ }
break;
case PIPE_INTERRUPT:
ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
@@ -680,9 +683,12 @@ static void td_submit_urb (
data + urb->iso_frame_desc [cnt].offset,
urb->iso_frame_desc [cnt].length, urb, cnt);
}
- if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
- && quirk_amdiso(ohci))
- quirk_amd_pll(0);
+ if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
+ if (quirk_amdiso(ohci))
+ quirk_amd_pll(0);
+ if (quirk_amdprefetch(ohci))
+ sb800_prefetch(ohci, 1);
+ }
periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0
&& ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0;
break;
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 222011f6172c..5bf15fed0d9f 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -402,6 +402,7 @@ struct ohci_hcd {
#define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */
#define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */
#define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/
+#define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */
// there are also chip quirks/bugs in init logic
struct work_struct nec_work; /* Worker for NEC quirk */
@@ -433,6 +434,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci)
{
return ohci->flags & OHCI_QUIRK_AMD_ISO;
}
+static inline int quirk_amdprefetch(struct ohci_hcd *ohci)
+{
+ return ohci->flags & OHCI_QUIRK_AMD_PREFETCH;
+}
#else
static inline int quirk_nec(struct ohci_hcd *ohci)
{
@@ -446,6 +451,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci)
{
return 0;
}
+static inline int quirk_amdprefetch(struct ohci_hcd *ohci)
+{
+ return 0;
+}
#endif
/* convert between an hcd pointer and the corresponding ohci_hcd */
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 749b53742828..e33d36256350 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -1003,19 +1003,20 @@ static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port,
if (syssts == SE0) {
r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port));
r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
- return;
- }
+ } else {
+ if (syssts == FS_JSTS)
+ r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
+ else if (syssts == LS_JSTS)
+ r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
- if (syssts == FS_JSTS)
- r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
- else if (syssts == LS_JSTS)
- r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
+ r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
+ r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
- r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
- r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
+ if (r8a66597->bus_suspended)
+ usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
+ }
- if (r8a66597->bus_suspended)
- usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
+ usb_hcd_poll_rh_status(r8a66597_to_hcd(r8a66597));
}
/* this function must be called with interrupt disabled */
@@ -1024,6 +1025,8 @@ static void r8a66597_usb_connect(struct r8a66597 *r8a66597, int port)
u16 speed = get_rh_usb_speed(r8a66597, port);
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+ rh->port &= ~((1 << USB_PORT_FEAT_HIGHSPEED) |
+ (1 << USB_PORT_FEAT_LOWSPEED));
if (speed == HSMODE)
rh->port |= (1 << USB_PORT_FEAT_HIGHSPEED);
else if (speed == LSMODE)
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 516848dd9b48..39d253e841f6 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -37,28 +37,8 @@ MODULE_LICENSE("GPL");
/* MACROS */
/*====================================================================*/
-#if defined(DEBUG) || defined(PCMCIA_DEBUG)
-
-static int pc_debug = 0;
-module_param(pc_debug, int, 0644);
-
-#define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args)
-
-#else
-#define DBG(n, args...) do{}while(0)
-#endif /* no debugging */
-
#define INFO(args...) printk(KERN_INFO "sl811_cs: " args)
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
-
-#define CS_CHECK(fn, ret) \
- do { \
- last_fn = (fn); \
- if ((last_ret = (ret)) != 0) \
- goto cs_failed; \
- } while (0)
-
/*====================================================================*/
/* VARIABLES */
/*====================================================================*/
@@ -76,7 +56,7 @@ static void sl811_cs_release(struct pcmcia_device * link);
static void release_platform_dev(struct device * dev)
{
- DBG(0, "sl811_cs platform_dev release\n");
+ dev_dbg(dev, "sl811_cs platform_dev release\n");
dev->parent = NULL;
}
@@ -140,7 +120,7 @@ static int sl811_hc_init(struct device *parent, resource_size_t base_addr,
static void sl811_cs_detach(struct pcmcia_device *link)
{
- DBG(0, "sl811_cs_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "sl811_cs_detach\n");
sl811_cs_release(link);
@@ -150,7 +130,7 @@ static void sl811_cs_detach(struct pcmcia_device *link)
static void sl811_cs_release(struct pcmcia_device * link)
{
- DBG(0, "sl811_cs_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "sl811_cs_release\n");
pcmcia_disable_device(link);
platform_device_unregister(&platform_dev);
@@ -205,11 +185,11 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev,
static int sl811_cs_config(struct pcmcia_device *link)
{
- struct device *parent = &handle_to_dev(link);
+ struct device *parent = &link->dev;
local_info_t *dev = link->priv;
- int last_fn, last_ret;
+ int ret;
- DBG(0, "sl811_cs_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "sl811_cs_config\n");
if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
goto failed;
@@ -217,14 +197,16 @@ static int sl811_cs_config(struct pcmcia_device *link)
/* require an IRQ and two registers */
if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
goto failed;
- if (link->conf.Attributes & CONF_ENABLE_IRQ)
- CS_CHECK(RequestIRQ,
- pcmcia_request_irq(link, &link->irq));
- else
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+ } else
goto failed;
- CS_CHECK(RequestConfiguration,
- pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
sprintf(dev->node.dev_name, driver_name);
dev->node.major = dev->node.minor = 0;
@@ -241,8 +223,6 @@ static int sl811_cs_config(struct pcmcia_device *link)
if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
< 0) {
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
printk(KERN_WARNING "sl811_cs_config failed\n");
sl811_cs_release(link);
@@ -263,7 +243,6 @@ static int sl811_cs_probe(struct pcmcia_device *link)
/* Initialize */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
link->irq.Handler = NULL;
link->conf.Attributes = 0;
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index c632437c7649..562eba108816 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -115,6 +115,10 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
if (status & QTD_STS_HALTED) {
/* Ug, an error. */
process_halted_qtd(whc, qset, td);
+ /* A halted qTD always triggers an update
+ because the qset was either removed or
+ reactivated. */
+ update |= WHC_UPDATE_UPDATED;
goto done;
}
@@ -305,6 +309,7 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
struct whc_urb *wurb = urb->hcpriv;
struct whc_qset *qset = wurb->qset;
struct whc_std *std, *t;
+ bool has_qtd = false;
int ret;
unsigned long flags;
@@ -315,17 +320,21 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
goto out;
list_for_each_entry_safe(std, t, &qset->stds, list_node) {
- if (std->urb == urb)
+ if (std->urb == urb) {
+ if (std->qtd)
+ has_qtd = true;
qset_free_std(whc, std);
- else
+ } else
std->qtd = NULL; /* so this std is re-added when the qset is */
}
- asl_qset_remove(whc, qset);
- wurb->status = status;
- wurb->is_async = true;
- queue_work(whc->workqueue, &wurb->dequeue_work);
-
+ if (has_qtd) {
+ asl_qset_remove(whc, qset);
+ wurb->status = status;
+ wurb->is_async = true;
+ queue_work(whc->workqueue, &wurb->dequeue_work);
+ } else
+ qset_remove_urb(whc, qset, urb, status);
out:
spin_unlock_irqrestore(&whc->lock, flags);
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index a9e05bac6646..0db3fb2dc03a 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -121,6 +121,10 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
if (status & QTD_STS_HALTED) {
/* Ug, an error. */
process_halted_qtd(whc, qset, td);
+ /* A halted qTD always triggers an update
+ because the qset was either removed or
+ reactivated. */
+ update |= WHC_UPDATE_UPDATED;
goto done;
}
@@ -333,6 +337,7 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
struct whc_urb *wurb = urb->hcpriv;
struct whc_qset *qset = wurb->qset;
struct whc_std *std, *t;
+ bool has_qtd = false;
int ret;
unsigned long flags;
@@ -343,17 +348,22 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
goto out;
list_for_each_entry_safe(std, t, &qset->stds, list_node) {
- if (std->urb == urb)
+ if (std->urb == urb) {
+ if (std->qtd)
+ has_qtd = true;
qset_free_std(whc, std);
- else
+ } else
std->qtd = NULL; /* so this std is re-added when the qset is */
}
- pzl_qset_remove(whc, qset);
- wurb->status = status;
- wurb->is_async = false;
- queue_work(whc->workqueue, &wurb->dequeue_work);
-
+ if (has_qtd) {
+ pzl_qset_remove(whc, qset);
+ update_pzl_hw_view(whc);
+ wurb->status = status;
+ wurb->is_async = false;
+ queue_work(whc->workqueue, &wurb->dequeue_work);
+ } else
+ qset_remove_urb(whc, qset, urb, status);
out:
spin_unlock_irqrestore(&whc->lock, flags);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1db4fea8c170..b8fd270a8b0d 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -802,9 +802,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
int i;
/* Free the Event Ring Segment Table and the actual Event Ring */
- xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
- xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
- xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
+ if (xhci->ir_set) {
+ xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
+ xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
+ xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
+ }
size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
if (xhci->erst.entries)
pci_free_consistent(pdev, size,
@@ -841,9 +843,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->dcbaa, xhci->dcbaa->dma);
xhci->dcbaa = NULL;
+ scratchpad_free(xhci);
xhci->page_size = 0;
xhci->page_shift = 0;
- scratchpad_free(xhci);
}
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 173c39c76489..821b7b4709de 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -864,9 +864,11 @@ static struct xhci_segment *trb_in_td(
cur_seg = start_seg;
do {
+ if (start_dma == 0)
+ return 0;
/* We may get an event for a Link TRB in the middle of a TD */
end_seg_dma = xhci_trb_virt_to_dma(cur_seg,
- &start_seg->trbs[TRBS_PER_SEGMENT - 1]);
+ &cur_seg->trbs[TRBS_PER_SEGMENT - 1]);
/* If the end TRB isn't in this segment, this is set to 0 */
end_trb_dma = xhci_trb_virt_to_dma(cur_seg, end_trb);
@@ -893,8 +895,9 @@ static struct xhci_segment *trb_in_td(
}
cur_seg = cur_seg->next;
start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]);
- } while (1);
+ } while (cur_seg != start_seg);
+ return 0;
}
/*
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 9ed3e741bee1..10f3205798e8 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -348,12 +348,12 @@ static unsigned int mon_buff_area_alloc_contiguous(struct mon_reader_bin *rp,
/*
* Return a few (kilo-)bytes to the head of the buffer.
- * This is used if a DMA fetch fails.
+ * This is used if a data fetch fails.
*/
static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size)
{
- size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
+ /* size &= ~(PKT_ALIGN-1); -- we're called with aligned size */
rp->b_cnt -= size;
if (rp->b_in < size)
rp->b_in += rp->b_size;
@@ -433,6 +433,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
unsigned int urb_length;
unsigned int offset;
unsigned int length;
+ unsigned int delta;
unsigned int ndesc, lendesc;
unsigned char dir;
struct mon_bin_hdr *ep;
@@ -537,8 +538,10 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
if (length != 0) {
ep->flag_data = mon_bin_get_data(rp, offset, urb, length);
if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */
- ep->len_cap = 0;
- mon_buff_area_shrink(rp, length);
+ delta = (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
+ ep->len_cap -= length;
+ delta -= (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
+ mon_buff_area_shrink(rp, delta);
}
} else {
ep->flag_data = data_tag;
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index c3577bbbae6c..ef2332a9941d 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -1442,11 +1442,6 @@ static int cppi_channel_abort(struct dma_channel *channel)
musb_writew(regs, MUSB_TXCSR, value);
musb_writew(regs, MUSB_TXCSR, value);
- /* re-enable interrupt */
- if (enabled)
- musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
- (1 << cppi_ch->index));
-
/* While we scrub the TX state RAM, ensure that we clean
* up any interrupt that's currently asserted:
* 1. Write to completion Ptr value 0x1(bit 0 set)
@@ -1459,6 +1454,11 @@ static int cppi_channel_abort(struct dma_channel *channel)
cppi_reset_tx(tx_ram, 1);
musb_writel(&tx_ram->tx_complete, 0, 0);
+ /* re-enable interrupt */
+ if (enabled)
+ musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
+ (1 << cppi_ch->index));
+
cppi_dump_tx(5, cppi_ch, " (done teardown)");
/* REVISIT tx side _should_ clean up the same way
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 3a61ddb62bd2..547e0e390726 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1450,7 +1450,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
#endif
if (hw_ep->max_packet_sz_tx) {
- printk(KERN_DEBUG
+ DBG(1,
"%s: hw_ep %d%s, %smax %d\n",
musb_driver_name, i,
hw_ep->is_shared_fifo ? "shared" : "tx",
@@ -1459,7 +1459,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
hw_ep->max_packet_sz_tx);
}
if (hw_ep->max_packet_sz_rx && !hw_ep->is_shared_fifo) {
- printk(KERN_DEBUG
+ DBG(1,
"%s: hw_ep %d%s, %smax %d\n",
musb_driver_name, i,
"rx",
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 8b3c4e2ed7b8..74073f9a43f0 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -4,6 +4,7 @@
* Copyright 2005 Mentor Graphics Corporation
* Copyright (C) 2005-2006 by Texas Instruments
* Copyright (C) 2006-2007 Nokia Corporation
+ * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -436,14 +437,6 @@ void musb_g_tx(struct musb *musb, u8 epnum)
csr |= MUSB_TXCSR_P_WZC_BITS;
csr &= ~MUSB_TXCSR_P_SENTSTALL;
musb_writew(epio, MUSB_TXCSR, csr);
- if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
- dma->status = MUSB_DMA_STATUS_CORE_ABORT;
- musb->dma_controller->channel_abort(dma);
- }
-
- if (request)
- musb_g_giveback(musb_ep, request, -EPIPE);
-
break;
}
@@ -582,15 +575,25 @@ void musb_g_tx(struct musb *musb, u8 epnum)
*/
static void rxstate(struct musb *musb, struct musb_request *req)
{
- u16 csr = 0;
const u8 epnum = req->epnum;
struct usb_request *request = &req->request;
struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
void __iomem *epio = musb->endpoints[epnum].regs;
unsigned fifo_count = 0;
u16 len = musb_ep->packet_sz;
+ u16 csr = musb_readw(epio, MUSB_RXCSR);
- csr = musb_readw(epio, MUSB_RXCSR);
+ /* We shouldn't get here while DMA is active, but we do... */
+ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
+ DBG(4, "DMA pending...\n");
+ return;
+ }
+
+ if (csr & MUSB_RXCSR_P_SENDSTALL) {
+ DBG(5, "%s stalling, RXCSR %04x\n",
+ musb_ep->end_point.name, csr);
+ return;
+ }
if (is_cppi_enabled() && musb_ep->dma) {
struct dma_controller *c = musb->dma_controller;
@@ -761,19 +764,10 @@ void musb_g_rx(struct musb *musb, u8 epnum)
csr, dma ? " (dma)" : "", request);
if (csr & MUSB_RXCSR_P_SENTSTALL) {
- if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
- dma->status = MUSB_DMA_STATUS_CORE_ABORT;
- (void) musb->dma_controller->channel_abort(dma);
- request->actual += musb_ep->dma->actual_len;
- }
-
csr |= MUSB_RXCSR_P_WZC_BITS;
csr &= ~MUSB_RXCSR_P_SENTSTALL;
musb_writew(epio, MUSB_RXCSR, csr);
-
- if (request)
- musb_g_giveback(musb_ep, request, -EPIPE);
- goto done;
+ return;
}
if (csr & MUSB_RXCSR_P_OVERRUN) {
@@ -795,7 +789,7 @@ void musb_g_rx(struct musb *musb, u8 epnum)
DBG((csr & MUSB_RXCSR_DMAENAB) ? 4 : 1,
"%s busy, csr %04x\n",
musb_ep->end_point.name, csr);
- goto done;
+ return;
}
if (dma && (csr & MUSB_RXCSR_DMAENAB)) {
@@ -826,22 +820,15 @@ void musb_g_rx(struct musb *musb, u8 epnum)
if ((request->actual < request->length)
&& (musb_ep->dma->actual_len
== musb_ep->packet_sz))
- goto done;
+ return;
#endif
musb_g_giveback(musb_ep, request, 0);
request = next_request(musb_ep);
if (!request)
- goto done;
-
- /* don't start more i/o till the stall clears */
- musb_ep_select(mbase, epnum);
- csr = musb_readw(epio, MUSB_RXCSR);
- if (csr & MUSB_RXCSR_P_SENDSTALL)
- goto done;
+ return;
}
-
/* analyze request if the ep is hot */
if (request)
rxstate(musb, to_musb_request(request));
@@ -849,8 +836,6 @@ void musb_g_rx(struct musb *musb, u8 epnum)
DBG(3, "packet waiting for %s%s request\n",
musb_ep->desc ? "" : "inactive ",
musb_ep->end_point.name);
-
-done:
return;
}
@@ -1244,7 +1229,7 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value)
void __iomem *mbase;
unsigned long flags;
u16 csr;
- struct musb_request *request = NULL;
+ struct musb_request *request;
int status = 0;
if (!ep)
@@ -1260,24 +1245,29 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value)
musb_ep_select(mbase, epnum);
- /* cannot portably stall with non-empty FIFO */
request = to_musb_request(next_request(musb_ep));
- if (value && musb_ep->is_in) {
- csr = musb_readw(epio, MUSB_TXCSR);
- if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
- DBG(3, "%s fifo busy, cannot halt\n", ep->name);
- spin_unlock_irqrestore(&musb->lock, flags);
- return -EAGAIN;
+ if (value) {
+ if (request) {
+ DBG(3, "request in progress, cannot halt %s\n",
+ ep->name);
+ status = -EAGAIN;
+ goto done;
+ }
+ /* Cannot portably stall with non-empty FIFO */
+ if (musb_ep->is_in) {
+ csr = musb_readw(epio, MUSB_TXCSR);
+ if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
+ DBG(3, "FIFO busy, cannot halt %s\n", ep->name);
+ status = -EAGAIN;
+ goto done;
+ }
}
-
}
/* set/clear the stall and toggle bits */
DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear");
if (musb_ep->is_in) {
csr = musb_readw(epio, MUSB_TXCSR);
- if (csr & MUSB_TXCSR_FIFONOTEMPTY)
- csr |= MUSB_TXCSR_FLUSHFIFO;
csr |= MUSB_TXCSR_P_WZC_BITS
| MUSB_TXCSR_CLRDATATOG;
if (value)
@@ -1300,14 +1290,13 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value)
musb_writew(epio, MUSB_RXCSR, csr);
}
-done:
-
/* maybe start the first request in the queue */
if (!musb_ep->busy && !value && request) {
DBG(3, "restarting the request\n");
musb_ep_restart(musb, request);
}
+done:
spin_unlock_irqrestore(&musb->lock, flags);
return status;
}
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
index 7a6778675ad3..522efb31b56b 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -511,7 +511,8 @@ static void ep0_txstate(struct musb *musb)
/* update the flags */
if (fifo_count < MUSB_MAX_END0_PACKET
- || request->actual == request->length) {
+ || (request->actual == request->length
+ && !request->zero)) {
musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT;
csr |= MUSB_CSR0_P_DATAEND;
} else
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index cf94511485f2..e3ab40a966eb 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1301,8 +1301,11 @@ void musb_host_tx(struct musb *musb, u8 epnum)
return;
} else if (usb_pipeisoc(pipe) && dma) {
if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb,
- offset, length))
+ offset, length)) {
+ if (is_cppi_enabled() || tusb_dma_omap())
+ musb_h_tx_dma_start(hw_ep);
return;
+ }
} else if (tx_csr & MUSB_TXCSR_DMAENAB) {
DBG(1, "not complete, but DMA enabled?\n");
return;
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 698252a4dc5d..bd254ec97d14 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -50,6 +50,8 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *,
static void cp210x_break_ctl(struct tty_struct *, int);
static int cp210x_startup(struct usb_serial *);
static void cp210x_disconnect(struct usb_serial *);
+static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
+static int cp210x_carrier_raised(struct usb_serial_port *p);
static int debug;
@@ -143,6 +145,8 @@ static struct usb_serial_driver cp210x_device = {
.tiocmset = cp210x_tiocmset,
.attach = cp210x_startup,
.disconnect = cp210x_disconnect,
+ .dtr_rts = cp210x_dtr_rts,
+ .carrier_raised = cp210x_carrier_raised
};
/* Config request types */
@@ -746,6 +750,14 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *file,
return cp210x_set_config(port, CP210X_SET_MHS, &control, 2);
}
+static void cp210x_dtr_rts(struct usb_serial_port *p, int on)
+{
+ if (on)
+ cp210x_tiocmset_port(p, NULL, TIOCM_DTR|TIOCM_RTS, 0);
+ else
+ cp210x_tiocmset_port(p, NULL, 0, TIOCM_DTR|TIOCM_RTS);
+}
+
static int cp210x_tiocmget (struct tty_struct *tty, struct file *file)
{
struct usb_serial_port *port = tty->driver_data;
@@ -768,6 +780,15 @@ static int cp210x_tiocmget (struct tty_struct *tty, struct file *file)
return result;
}
+static int cp210x_carrier_raised(struct usb_serial_port *p)
+{
+ unsigned int control;
+ cp210x_get_config(p, CP210X_GET_MDMSTS, &control, 1);
+ if (control & CONTROL_DCD)
+ return 1;
+ return 0;
+}
+
static void cp210x_break_ctl (struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 9c60d6d4908a..ebcc6d0e2e91 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1937,7 +1937,7 @@ static void ftdi_write_bulk_callback(struct urb *urb)
return;
}
/* account for transferred data */
- countback = urb->actual_length;
+ countback = urb->transfer_buffer_length;
data_offset = priv->write_offset;
if (data_offset > 0) {
/* Subtract the control bytes */
@@ -1950,7 +1950,6 @@ static void ftdi_write_bulk_callback(struct urb *urb)
if (status) {
dbg("nonzero write bulk status received: %d", status);
- return;
}
usb_serial_port_softint(port);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 43c227027560..0577e4b61114 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -308,6 +308,7 @@ static int option_resume(struct usb_serial *serial);
#define DLINK_VENDOR_ID 0x1186
#define DLINK_PRODUCT_DWM_652 0x3e04
+#define DLINK_PRODUCT_DWM_652_U5 0xce16
#define QISDA_VENDOR_ID 0x1da5
#define QISDA_PRODUCT_H21_4512 0x4512
@@ -315,6 +316,9 @@ static int option_resume(struct usb_serial *serial);
#define QISDA_PRODUCT_H20_4515 0x4515
#define QISDA_PRODUCT_H20_4519 0x4519
+/* TLAYTECH PRODUCTS */
+#define TLAYTECH_VENDOR_ID 0x20B9
+#define TLAYTECH_PRODUCT_TEU800 0x1682
/* TOSHIBA PRODUCTS */
#define TOSHIBA_VENDOR_ID 0x0930
@@ -328,6 +332,13 @@ static int option_resume(struct usb_serial *serial);
#define ALCATEL_VENDOR_ID 0x1bbb
#define ALCATEL_PRODUCT_X060S 0x0000
+/* Airplus products */
+#define AIRPLUS_VENDOR_ID 0x1011
+#define AIRPLUS_PRODUCT_MCD650 0x3198
+
+/* 4G Systems products */
+#define FOUR_G_SYSTEMS_VENDOR_ID 0x1c9e
+#define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -580,6 +591,7 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
+ { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
@@ -589,6 +601,9 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
+ { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
+ { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
+ { USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 45883988a005..5019325ba25d 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -296,7 +296,6 @@ struct sierra_port_private {
int dsr_state;
int dcd_state;
int ri_state;
-
unsigned int opened:1;
};
@@ -306,6 +305,8 @@ static int sierra_send_setup(struct usb_serial_port *port)
struct sierra_port_private *portdata;
__u16 interface = 0;
int val = 0;
+ int do_send = 0;
+ int retval;
dev_dbg(&port->dev, "%s\n", __func__);
@@ -324,10 +325,7 @@ static int sierra_send_setup(struct usb_serial_port *port)
*/
if (port->interrupt_in_urb) {
/* send control message */
- return usb_control_msg(serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
- 0x22, 0x21, val, interface,
- NULL, 0, USB_CTRL_SET_TIMEOUT);
+ do_send = 1;
}
}
@@ -339,12 +337,18 @@ static int sierra_send_setup(struct usb_serial_port *port)
interface = 1;
else if (port->bulk_out_endpointAddress == 5)
interface = 2;
- return usb_control_msg(serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
- 0x22, 0x21, val, interface,
- NULL, 0, USB_CTRL_SET_TIMEOUT);
+
+ do_send = 1;
}
- return 0;
+ if (!do_send)
+ return 0;
+
+ usb_autopm_get_interface(serial->interface);
+ retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT);
+ usb_autopm_put_interface(serial->interface);
+
+ return retval;
}
static void sierra_set_termios(struct tty_struct *tty,
@@ -773,8 +777,11 @@ static void sierra_close(struct usb_serial_port *port)
if (serial->dev) {
mutex_lock(&serial->disc_mutex);
- if (!serial->disconnected)
+ if (!serial->disconnected) {
+ serial->interface->needs_remote_wakeup = 0;
+ usb_autopm_get_interface(serial->interface);
sierra_send_setup(port);
+ }
mutex_unlock(&serial->disc_mutex);
spin_lock_irq(&intfdata->susp_lock);
portdata->opened = 0;
@@ -788,8 +795,6 @@ static void sierra_close(struct usb_serial_port *port)
sierra_release_urb(portdata->in_urbs[i]);
portdata->in_urbs[i] = NULL;
}
- usb_autopm_get_interface(serial->interface);
- serial->interface->needs_remote_wakeup = 0;
}
}
@@ -827,6 +832,8 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
if (err) {
/* get rid of everything as in close */
sierra_close(port);
+ /* restore balance for autopm */
+ usb_autopm_put_interface(serial->interface);
return err;
}
sierra_send_setup(port);
@@ -915,7 +922,7 @@ static void sierra_release(struct usb_serial *serial)
#ifdef CONFIG_PM
static void stop_read_write_urbs(struct usb_serial *serial)
{
- int i, j;
+ int i;
struct usb_serial_port *port;
struct sierra_port_private *portdata;
@@ -923,8 +930,7 @@ static void stop_read_write_urbs(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
portdata = usb_get_serial_port_data(port);
- for (j = 0; j < N_IN_URB; j++)
- usb_kill_urb(portdata->in_urbs[j]);
+ sierra_stop_rx_urbs(port);
usb_kill_anchored_urbs(&portdata->active);
}
}
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 3a4fb023af72..589f6b4404f0 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -696,7 +696,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
/* device supports and needs bigger sense buffer */
if (us->fflags & US_FL_SANE_SENSE)
sense_size = ~0;
-
+Retry_Sense:
US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sense_size);
@@ -720,6 +720,21 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
srb->result = DID_ABORT << 16;
goto Handle_Errors;
}
+
+ /* Some devices claim to support larger sense but fail when
+ * trying to request it. When a transport failure happens
+ * using US_FS_SANE_SENSE, we always retry with a standard
+ * (small) sense request. This fixes some USB GSM modems
+ */
+ if (temp_result == USB_STOR_TRANSPORT_FAILED &&
+ (us->fflags & US_FL_SANE_SENSE) &&
+ sense_size != US_SENSE_SIZE) {
+ US_DEBUGP("-- auto-sense failure, retry small sense\n");
+ sense_size = US_SENSE_SIZE;
+ goto Retry_Sense;
+ }
+
+ /* Other failures */
if (temp_result != USB_STOR_TRANSPORT_GOOD) {
US_DEBUGP("-- auto-sense failure\n");
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index b2f149fedcc5..4516c36436e6 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -200,35 +200,40 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
{
int result, bytes, secd_size;
struct device *dev = &usb_dev->dev;
- struct usb_security_descriptor secd;
+ struct usb_security_descriptor *secd;
const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL;
- void *secd_buf;
const void *itr, *top;
char buf[64];
+ secd = kmalloc(sizeof(struct usb_security_descriptor), GFP_KERNEL);
+ if (secd == NULL) {
+ result = -ENOMEM;
+ goto out;
+ }
+
result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
- 0, &secd, sizeof(secd));
+ 0, secd, sizeof(struct usb_security_descriptor));
if (result < sizeof(secd)) {
dev_err(dev, "Can't read security descriptor or "
"not enough data: %d\n", result);
- goto error_secd;
+ goto out;
}
- secd_size = le16_to_cpu(secd.wTotalLength);
- secd_buf = kmalloc(secd_size, GFP_KERNEL);
- if (secd_buf == NULL) {
+ secd_size = le16_to_cpu(secd->wTotalLength);
+ secd = krealloc(secd, secd_size, GFP_KERNEL);
+ if (secd == NULL) {
dev_err(dev, "Can't allocate space for security descriptors\n");
- goto error_secd_alloc;
+ goto out;
}
result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
- 0, secd_buf, secd_size);
+ 0, secd, secd_size);
if (result < secd_size) {
dev_err(dev, "Can't read security descriptor or "
"not enough data: %d\n", result);
- goto error_secd_all;
+ goto out;
}
bytes = 0;
- itr = secd_buf + sizeof(secd);
- top = secd_buf + result;
+ itr = &secd[1];
+ top = (void *)secd + result;
while (itr < top) {
etd = itr;
if (top - itr < sizeof(*etd)) {
@@ -259,24 +264,16 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
dev_err(dev, "WUSB device doesn't support CCM1 encryption, "
"can't use!\n");
result = -EINVAL;
- goto error_no_ccm1;
+ goto out;
}
wusb_dev->ccm1_etd = *ccm1_etd;
dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n",
buf, wusb_et_name(ccm1_etd->bEncryptionType),
ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex);
result = 0;
- kfree(secd_buf);
out:
+ kfree(secd);
return result;
-
-
-error_no_ccm1:
-error_secd_all:
- kfree(secd_buf);
-error_secd_alloc:
-error_secd:
- goto out;
}
void wusb_dev_sec_rm(struct wusb_dev *wusb_dev)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 9bbb2855ea91..188e1ba3b69f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2121,7 +2121,7 @@ config FB_EP93XX
config FB_PRE_INIT_FB
bool "Don't reinitialize, use bootloader's GDC/Display configuration"
- depends on FB_MB862XX_LIME
+ depends on FB && FB_MB862XX_LIME
---help---
Select this option if display contents should be inherited as set by
the bootloader.
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 8cd279be74e5..37624f74e88b 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -329,12 +329,6 @@ extern unsigned char fontdata_8x16[];
*
* * perform fb specific mmap *
* int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
- *
- * * save current hardware state *
- * void (*fb_save_state)(struct fb_info *info);
- *
- * * restore saved state *
- * void (*fb_restore_state)(struct fb_info *info);
* } ;
*/
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 2830ffd72976..d5e801076d33 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -484,6 +484,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
unsigned long value;
unsigned long clk_value_khz;
unsigned long bits_per_line;
+ unsigned long pix_factor = 2;
might_sleep();
@@ -516,20 +517,24 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
/* Now, the LCDC core... */
/* Set pixel clock */
+ if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es())
+ pix_factor = 1;
+
clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock));
- if (value < 2) {
+ if (value < pix_factor) {
dev_notice(info->device, "Bypassing pixel clock divider\n");
lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
} else {
- value = (value / 2) - 1;
+ value = (value / pix_factor) - 1;
dev_dbg(info->device, " * programming CLKVAL = 0x%08lx\n",
value);
lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1,
value << ATMEL_LCDC_CLKVAL_OFFSET);
- info->var.pixclock = KHZ2PICOS(clk_value_khz / (2 * (value + 1)));
+ info->var.pixclock =
+ KHZ2PICOS(clk_value_khz / (pix_factor * (value + 1)));
dev_dbg(info->device, " updated pixclk: %lu KHz\n",
PICOS2KHZ(info->var.pixclock));
}
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index 2211a852af9c..96774949cd30 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -433,8 +433,9 @@ static int corgi_bl_update_status(struct backlight_device *bd)
if (corgibl_flags & CORGIBL_SUSPENDED)
intensity = 0;
- if (corgibl_flags & CORGIBL_BATTLOW)
- intensity &= lcd->limit_mask;
+
+ if ((corgibl_flags & CORGIBL_BATTLOW) && intensity > lcd->limit_mask)
+ intensity = lcd->limit_mask;
return corgi_bl_set_intensity(lcd, intensity);
}
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index b6449470106c..a482dd7b0311 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -56,7 +56,7 @@ static int fb_notifier_callback(struct notifier_block *self,
static int lcd_register_fb(struct lcd_device *ld)
{
- memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif));
+ memset(&ld->fb_notif, 0, sizeof(ld->fb_notif));
ld->fb_notif.notifier_call = fb_notifier_callback;
return fb_register_client(&ld->fb_notif);
}
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 5a686cea23f4..3681c6a88212 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2311,14 +2311,11 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
ops->graphics = 1;
if (!blank) {
- if (info->fbops->fb_save_state)
- info->fbops->fb_save_state(info);
var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
fb_set_var(info, &var);
ops->graphics = 0;
ops->var = info->var;
- } else if (info->fbops->fb_restore_state)
- info->fbops->fb_restore_state(info);
+ }
}
if (!fbcon_is_inactive(vc, info)) {
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index d065894ce38f..ea1fd3f47511 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -554,11 +554,11 @@ static int fb_check_var(struct fb_var_screeninfo *var,
var->transp.length = 0;
break;
case 16: /* RGB 565 */
- var->red.offset = 0;
+ var->red.offset = 11;
var->red.length = 5;
var->green.offset = 5;
var->green.length = 6;
- var->blue.offset = 11;
+ var->blue.offset = 0;
var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
@@ -591,7 +591,7 @@ static int __devexit fb_remove(struct platform_device *dev)
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
- info->screen_base,
+ info->screen_base - PAGE_SIZE,
info->fix.smem_start);
free_irq(par->irq, par);
clk_disable(par->lcdc_clk);
@@ -704,7 +704,7 @@ static int __init fb_probe(struct platform_device *device)
if (i == ARRAY_SIZE(known_lcd_panels)) {
dev_err(&device->dev, "GLCD: No valid panel found\n");
- ret = ENODEV;
+ ret = -ENODEV;
goto err_clk_disable;
} else
dev_info(&device->dev, "GLCD: Found %s panel\n",
@@ -749,6 +749,7 @@ static int __init fb_probe(struct platform_device *device)
(PAGE_SIZE - par->palette_sz);
/* the rest of the frame buffer is pixel data */
+ da8xx_fb_info->screen_base = par->v_palette_base + par->palette_sz;
da8xx_fb_fix.smem_start = par->p_palette_base + par->palette_sz;
da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz;
da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8;
@@ -787,6 +788,8 @@ static int __init fb_probe(struct platform_device *device)
da8xx_fb_info->var = da8xx_fb_var;
da8xx_fb_info->fbops = &da8xx_fb_ops;
da8xx_fb_info->pseudo_palette = par->pseudo_palette;
+ da8xx_fb_info->fix.visual = (da8xx_fb_info->var.bits_per_pixel <= 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
if (ret)
@@ -825,7 +828,7 @@ err_free_irq:
err_release_fb_mem:
dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
- da8xx_fb_info->screen_base,
+ da8xx_fb_info->screen_base - PAGE_SIZE,
da8xx_fb_info->fix.smem_start);
err_release_fb:
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 1a83709f9611..f67db4268374 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -1147,7 +1147,7 @@ static int __init gbefb_probe(struct platform_device *p_dev)
gbefb_setup(options);
#endif
- if (!request_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
+ if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
ret = -EBUSY;
goto out_release_framebuffer;
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index 5c5a1ad1d397..474421fe79a6 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -24,6 +24,7 @@
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/sched.h>
#include <mach/msm_iomap.h>
#include <mach/irqs.h>
#include <mach/board.h>
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
index 9c78050ac799..c9e9349451cb 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <linux/gpio.h>
#include <mach/msm_fb.h>
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c
index 80d0f5fdf0b1..71048e78f7f0 100644
--- a/drivers/video/msm/mddi_client_toshiba.c
+++ b/drivers/video/msm/mddi_client_toshiba.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
+#include <linux/sched.h>
#include <mach/msm_fb.h>
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 99636a2b20f2..6c519e2fa2b7 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -22,9 +22,6 @@
#include <linux/wait.h>
#include <linux/clk.h>
#include <linux/file.h>
-#ifdef CONFIG_ANDROID_PMEM
-#include <linux/android_pmem.h>
-#endif
#include <linux/major.h>
#include <mach/msm_iomap.h>
@@ -262,11 +259,6 @@ int get_img(struct mdp_img *img, struct fb_info *info,
struct file *file;
unsigned long vstart;
-#ifdef CONFIG_ANDROID_PMEM
- if (!get_pmem_file(img->memory_id, start, &vstart, len, filep))
- return 0;
-#endif
-
file = fget_light(img->memory_id, &put_needed);
if (file == NULL)
return -1;
@@ -283,12 +275,6 @@ int get_img(struct mdp_img *img, struct fb_info *info,
void put_img(struct file *src_file, struct file *dst_file)
{
-#ifdef CONFIG_ANDROID_PMEM
- if (src_file)
- put_pmem_file(src_file);
- if (dst_file)
- put_pmem_file(dst_file);
-#endif
}
int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
@@ -320,9 +306,6 @@ int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) {
printk(KERN_ERR "mpd_ppp: could not retrieve dst image from "
"memory\n");
-#ifdef CONFIG_ANDROID_PMEM
- put_pmem_file(src_file);
-#endif
return -EINVAL;
}
mutex_lock(&mdp_mutex);
@@ -499,7 +482,6 @@ int mdp_probe(struct platform_device *pdev)
/* register mdp device */
mdp->mdp_dev.dev.parent = &pdev->dev;
mdp->mdp_dev.dev.class = mdp_class;
- snprintf(mdp->mdp_dev.dev.bus_id, BUS_ID_SIZE, "mdp%d", pdev->id);
/* if you can remove the platform device you'd have to implement
* this:
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index ba2c4673b648..4ff001f4cbbd 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -16,7 +16,6 @@
#include <linux/file.h>
#include <linux/delay.h>
#include <linux/msm_mdp.h>
-#include <linux/android_pmem.h>
#include <mach/msm_fb.h>
#include "mdp_hw.h"
@@ -579,25 +578,6 @@ static int valid_src_dst(unsigned long src_start, unsigned long src_len,
static void flush_imgs(struct mdp_blit_req *req, struct mdp_regs *regs,
struct file *src_file, struct file *dst_file)
{
-#ifdef CONFIG_ANDROID_PMEM
- uint32_t src0_len, src1_len, dst0_len, dst1_len;
-
- /* flush src images to memory before dma to mdp */
- get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len,
- &src1_len);
- flush_pmem_file(src_file, req->src.offset, src0_len);
- if (IS_PSEUDOPLNR(req->src.format))
- flush_pmem_file(src_file, req->src.offset + src0_len,
- src1_len);
-
- /* flush dst images */
- get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len,
- &dst1_len);
- flush_pmem_file(dst_file, req->dst.offset, dst0_len);
- if (IS_PSEUDOPLNR(req->dst.format))
- flush_pmem_file(dst_file, req->dst.offset + dst0_len,
- dst1_len);
-#endif
}
static void get_chroma_addr(struct mdp_img *img, struct mdp_rect *rect,
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 37b135d5d12e..842d157e1025 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1565,7 +1565,7 @@ static int savagefb_blank(int blank, struct fb_info *info)
vga_out8(0x3c5, sr8, par);
vga_out8(0x3c4, 0x0d, par);
srd = vga_in8(0x3c5, par);
- srd &= 0x03;
+ srd &= 0x50;
switch (blank) {
case FB_BLANK_UNBLANK:
@@ -1606,22 +1606,6 @@ static int savagefb_blank(int blank, struct fb_info *info)
return (blank == FB_BLANK_NORMAL) ? 1 : 0;
}
-static void savagefb_save_state(struct fb_info *info)
-{
- struct savagefb_par *par = info->par;
-
- savage_get_default_par(par, &par->save);
-}
-
-static void savagefb_restore_state(struct fb_info *info)
-{
- struct savagefb_par *par = info->par;
-
- savagefb_blank(FB_BLANK_POWERDOWN, info);
- savage_set_default_par(par, &par->save);
- savagefb_blank(FB_BLANK_UNBLANK, info);
-}
-
static int savagefb_open(struct fb_info *info, int user)
{
struct savagefb_par *par = info->par;
@@ -1667,8 +1651,6 @@ static struct fb_ops savagefb_ops = {
.fb_setcolreg = savagefb_setcolreg,
.fb_pan_display = savagefb_pan_display,
.fb_blank = savagefb_blank,
- .fb_save_state = savagefb_save_state,
- .fb_restore_state = savagefb_restore_state,
#if defined(CONFIG_FB_SAVAGE_ACCEL)
.fb_fillrect = savagefb_fillrect,
.fb_copyarea = savagefb_copyarea,
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index e35232a18571..54fbb2995a5f 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -1411,23 +1411,6 @@ static int uvesafb_check_var(struct fb_var_screeninfo *var,
return 0;
}
-static void uvesafb_save_state(struct fb_info *info)
-{
- struct uvesafb_par *par = info->par;
-
- if (par->vbe_state_saved)
- kfree(par->vbe_state_saved);
-
- par->vbe_state_saved = uvesafb_vbe_state_save(par);
-}
-
-static void uvesafb_restore_state(struct fb_info *info)
-{
- struct uvesafb_par *par = info->par;
-
- uvesafb_vbe_state_restore(par, par->vbe_state_saved);
-}
-
static struct fb_ops uvesafb_ops = {
.owner = THIS_MODULE,
.fb_open = uvesafb_open,
@@ -1441,8 +1424,6 @@ static struct fb_ops uvesafb_ops = {
.fb_imageblit = cfb_imageblit,
.fb_check_var = uvesafb_check_var,
.fb_set_par = uvesafb_set_par,
- .fb_save_state = uvesafb_save_state,
- .fb_restore_state = uvesafb_restore_state,
};
static void __devinit uvesafb_init_info(struct fb_info *info,
@@ -1459,15 +1440,6 @@ static void __devinit uvesafb_init_info(struct fb_info *info,
info->fix.ypanstep = par->ypan ? 1 : 0;
info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0;
- /*
- * If we were unable to get the state buffer size, disable
- * functions for saving and restoring the hardware state.
- */
- if (par->vbe_state_size == 0) {
- info->fbops->fb_save_state = NULL;
- info->fbops->fb_restore_state = NULL;
- }
-
/* Disable blanking if the user requested so. */
if (!blank)
info->fbops->fb_blank = NULL;
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 200c22f55130..9dd588042880 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -19,7 +19,6 @@
*/
//#define DEBUG
#include <linux/virtio.h>
-#include <linux/virtio_ids.h>
#include <linux/virtio_balloon.h>
#include <linux/swap.h>
#include <linux/kthread.h>
@@ -248,7 +247,7 @@ out:
return err;
}
-static void virtballoon_remove(struct virtio_device *vdev)
+static void __devexit virtballoon_remove(struct virtio_device *vdev)
{
struct virtio_balloon *vb = vdev->priv;
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 4a1f1ebff7bf..28d9cf7cf72f 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -530,19 +530,22 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
err = PTR_ERR(vqs[i]);
goto error_find;
}
+
+ if (!vp_dev->per_vq_vectors || msix_vec == VIRTIO_MSI_NO_VECTOR)
+ continue;
+
/* allocate per-vq irq if available and necessary */
- if (vp_dev->per_vq_vectors) {
- snprintf(vp_dev->msix_names[msix_vec],
- sizeof *vp_dev->msix_names,
- "%s-%s",
- dev_name(&vp_dev->vdev.dev), names[i]);
- err = request_irq(msix_vec, vring_interrupt, 0,
- vp_dev->msix_names[msix_vec],
- vqs[i]);
- if (err) {
- vp_del_vq(vqs[i]);
- goto error_find;
- }
+ snprintf(vp_dev->msix_names[msix_vec],
+ sizeof *vp_dev->msix_names,
+ "%s-%s",
+ dev_name(&vp_dev->vdev.dev), names[i]);
+ err = request_irq(vp_dev->msix_entries[msix_vec].vector,
+ vring_interrupt, 0,
+ vp_dev->msix_names[msix_vec],
+ vqs[i]);
+ if (err) {
+ vp_del_vq(vqs[i]);
+ goto error_find;
}
}
return 0;
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index f53600580726..fbd2ecde93e4 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -285,6 +285,9 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len)
return NULL;
}
+ /* Only get used array entries after they have been exposed by host. */
+ rmb();
+
i = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].id;
*len = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].len;
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index f24d04132eda..4d227b152001 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -317,7 +317,7 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
static struct platform_driver platform_wdt_driver = {
.driver = {
- .name = "watchdog",
+ .name = "pnx4008-watchdog",
.owner = THIS_MODULE,
},
.probe = pnx4008_wdt_probe,
@@ -352,4 +352,4 @@ MODULE_PARM_DESC(nowayout,
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-MODULE_ALIAS("platform:watchdog");
+MODULE_ALIAS("platform:pnx4008-watchdog");
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index f6cccc9df022..bf12d06b5877 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -62,7 +62,7 @@ extern unsigned int idt_cpu_freq;
static int timeout = WATCHDOG_TIMEOUT;
module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout, "Watchdog timeout value, in seconds (default="
- WATCHDOG_TIMEOUT ")");
+ __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
@@ -276,7 +276,7 @@ static int __devinit rc32434_wdt_probe(struct platform_device *pdev)
return -ENODEV;
}
- wdt_reg = ioremap_nocache(r->start, r->end - r->start);
+ wdt_reg = ioremap_nocache(r->start, resource_size(r));
if (!wdt_reg) {
printk(KERN_ERR PFX "failed to remap I/O resources\n");
return -ENXIO;
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c
index 1e8f02f440e6..d3c824dc2358 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -206,7 +206,7 @@ static int __devinit riowd_probe(struct of_device *op,
dev_set_drvdata(&op->dev, p);
riowd_device = p;
- err = 0;
+ return 0;
out_iounmap:
of_iounmap(&op->resource[0], p->regs, 2);
diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c
index 852ca1977917..91430a89107c 100644
--- a/drivers/watchdog/sbc_fitpc2_wdt.c
+++ b/drivers/watchdog/sbc_fitpc2_wdt.c
@@ -227,7 +227,7 @@ static int __init fitpc2_wdt_init(void)
}
err = misc_register(&fitpc2_wdt_miscdev);
- if (!err) {
+ if (err) {
pr_err("cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, err);
goto err_margin;
diff --git a/firmware/Makefile b/firmware/Makefile
index a6c7c3e47e42..f4ca0c7eb51c 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -69,11 +69,13 @@ fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \
cis/DP83903.cis cis/NE2K.cis \
- cis/tamarack.cis
+ cis/tamarack.cis cis/PE-200.cis
fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \
- cis/COMpad2.cis cis/COMpad4.cis
+ cis/COMpad2.cis cis/COMpad4.cis \
+ cis/SW_555_SER.cis cis/SW_7xx_SER.cis \
+ cis/SW_8xx_SER.cis
fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
advansys/3550.bin advansys/38C0800.bin
diff --git a/firmware/WHENCE b/firmware/WHENCE
index c437e14f0b11..7a8adc06eb34 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -600,6 +600,7 @@ File: cis/LA-PCM.cis
cis/DP83903.cis
cis/NE2K.cis
cis/tamarack.cis
+ cis/PE-200.cis
Licence: GPL
@@ -633,6 +634,9 @@ File: cis/MT5634ZLX.cis
cis/RS-COM-2P.cis
cis/COMpad2.cis
cis/COMpad4.cis
+ cis/SW_555_SER.cis
+ cis/SW_7xx_SER.cis
+ cis/SW_8xx_SER.cis
Licence: GPL
diff --git a/firmware/cis/PE-200.cis.ihex b/firmware/cis/PE-200.cis.ihex
new file mode 100644
index 000000000000..e6dbdab6eb79
--- /dev/null
+++ b/firmware/cis/PE-200.cis.ihex
@@ -0,0 +1,9 @@
+:1000000001030000FF151E0401504D582020200060
+:1000100050452D3230300045544845524E4554002D
+:1000200052303100FF210206031A050101000101CF
+:100030001B0EC181190155E051000F100F30FFFF59
+:040040001400FF00A9
+:00000001FF
+#
+# Replacement CIS for PE-200 ethernet card
+#
diff --git a/firmware/cis/SW_555_SER.cis.ihex b/firmware/cis/SW_555_SER.cis.ihex
new file mode 100644
index 000000000000..9b9348acee7b
--- /dev/null
+++ b/firmware/cis/SW_555_SER.cis.ihex
@@ -0,0 +1,12 @@
+:100000000101FF17034100FF20043F0110072102F7
+:100010000200152A070053696572726120576972E0
+:10002000656C657373004169724361726420353594
+:1000300035004135353500526576203100FF1A050F
+:1000400001030007731B0BE00118A360F8030730DE
+:10005000BC3F1B08A10108A360F802071B08A2010E
+:1000600008A360E803071B08A30108A360E80207D0
+:0A0070001B04A40108231400FF0084
+:00000001FF
+#
+# Replacement CIS for AC555 provided by Sierra Wireless
+#
diff --git a/firmware/cis/SW_7xx_SER.cis.ihex b/firmware/cis/SW_7xx_SER.cis.ihex
new file mode 100644
index 000000000000..11e44ad86437
--- /dev/null
+++ b/firmware/cis/SW_7xx_SER.cis.ihex
@@ -0,0 +1,13 @@
+:100000000101FF17034100FF2004920110072102A4
+:1000100002001537070053696572726120576972D3
+:10002000656C6573730041433731302F4143373579
+:10003000300047505253204E6574776F726B2041E9
+:1000400064617074657200523100FF1A050103008B
+:1000500007731B10E00119784D555D25A360F80367
+:100060000730BC861B08A10108A360F802071B0823
+:10007000A20108A360E803071B08A30108A360E826
+:0C00800002071B04A40108231400FF0069
+:00000001FF
+#
+# Replacement CIS for AC7xx provided by Sierra Wireless
+#
diff --git a/firmware/cis/SW_8xx_SER.cis.ihex b/firmware/cis/SW_8xx_SER.cis.ihex
new file mode 100644
index 000000000000..bbcfe6348328
--- /dev/null
+++ b/firmware/cis/SW_8xx_SER.cis.ihex
@@ -0,0 +1,13 @@
+:100000000101FF17034100FF2004920110072102A4
+:100010000200152F070053696572726120576972DB
+:10002000656C657373004143383530003347204EAB
+:100030006574776F726B20416461707465720052F1
+:100040003100FF1A0501030007731B10E001197846
+:100050004D555D25A360F8480730BC861B08A101FB
+:1000600008A360F847071B08A20108A360E8480737
+:100070001B08A30108A360E847071B04A401082389
+:040080001400FF0069
+:00000001FF
+#
+# Replacement CIS for AC8xx provided by Sierra Wireless
+#
diff --git a/fs/9p/cache.c b/fs/9p/cache.c
index 51c94e26a346..e777961939f3 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
@@ -343,18 +343,7 @@ int __v9fs_fscache_release_page(struct page *page, gfp_t gfp)
BUG_ON(!vcookie->fscache);
- if (PageFsCache(page)) {
- if (fscache_check_page_write(vcookie->fscache, page)) {
- if (!(gfp & __GFP_WAIT))
- return 0;
- fscache_wait_on_page_write(vcookie->fscache, page);
- }
-
- fscache_uncache_page(vcookie->fscache, page);
- ClearPageFsCache(page);
- }
-
- return 1;
+ return fscache_maybe_release_page(vcookie->fscache, page, gfp);
}
void __v9fs_fscache_invalidate_page(struct page *page)
@@ -368,7 +357,6 @@ void __v9fs_fscache_invalidate_page(struct page *page)
fscache_wait_on_page_write(vcookie->fscache, page);
BUG_ON(!PageLocked(page));
fscache_uncache_page(vcookie->fscache, page);
- ClearPageFsCache(page);
}
}
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 873cd31baa47..15cce53bf61e 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -40,6 +40,24 @@
#include "fid.h"
/**
+ * struct p9_rdir - readdir accounting
+ * @mutex: mutex protecting readdir
+ * @head: start offset of current dirread buffer
+ * @tail: end offset of current dirread buffer
+ * @buf: dirread buffer
+ *
+ * private structure for keeping track of readdir
+ * allocated on demand
+ */
+
+struct p9_rdir {
+ struct mutex mutex;
+ int head;
+ int tail;
+ uint8_t *buf;
+};
+
+/**
* dt_type - return file type
* @mistat: mistat structure
*
@@ -70,56 +88,79 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
int over;
struct p9_wstat st;
- int err;
+ int err = 0;
struct p9_fid *fid;
int buflen;
- char *statbuf;
- int n, i = 0;
+ int reclen = 0;
+ struct p9_rdir *rdir;
P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
fid = filp->private_data;
buflen = fid->clnt->msize - P9_IOHDRSZ;
- statbuf = kmalloc(buflen, GFP_KERNEL);
- if (!statbuf)
- return -ENOMEM;
-
- while (1) {
- err = v9fs_file_readn(filp, statbuf, NULL, buflen,
- fid->rdir_fpos);
- if (err <= 0)
- break;
-
- n = err;
- while (i < n) {
- err = p9stat_read(statbuf + i, buflen-i, &st,
- fid->clnt->dotu);
+
+ /* allocate rdir on demand */
+ if (!fid->rdir) {
+ rdir = kmalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL);
+
+ if (rdir == NULL) {
+ err = -ENOMEM;
+ goto exit;
+ }
+ spin_lock(&filp->f_dentry->d_lock);
+ if (!fid->rdir) {
+ rdir->buf = (uint8_t *)rdir + sizeof(struct p9_rdir);
+ mutex_init(&rdir->mutex);
+ rdir->head = rdir->tail = 0;
+ fid->rdir = (void *) rdir;
+ rdir = NULL;
+ }
+ spin_unlock(&filp->f_dentry->d_lock);
+ kfree(rdir);
+ }
+ rdir = (struct p9_rdir *) fid->rdir;
+
+ err = mutex_lock_interruptible(&rdir->mutex);
+ while (err == 0) {
+ if (rdir->tail == rdir->head) {
+ err = v9fs_file_readn(filp, rdir->buf, NULL,
+ buflen, filp->f_pos);
+ if (err <= 0)
+ goto unlock_and_exit;
+
+ rdir->head = 0;
+ rdir->tail = err;
+ }
+
+ while (rdir->head < rdir->tail) {
+ err = p9stat_read(rdir->buf + rdir->head,
+ buflen - rdir->head, &st,
+ fid->clnt->dotu);
if (err) {
P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err);
err = -EIO;
p9stat_free(&st);
- goto free_and_exit;
+ goto unlock_and_exit;
}
-
- i += st.size+2;
- fid->rdir_fpos += st.size+2;
+ reclen = st.size+2;
over = filldir(dirent, st.name, strlen(st.name),
filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st));
- filp->f_pos += st.size+2;
-
p9stat_free(&st);
if (over) {
err = 0;
- goto free_and_exit;
+ goto unlock_and_exit;
}
+ rdir->head += reclen;
+ filp->f_pos += reclen;
}
}
-free_and_exit:
- kfree(statbuf);
+unlock_and_exit:
+ mutex_unlock(&rdir->mutex);
+exit:
return err;
}
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 5947628aefef..18f74ec4dce9 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -994,8 +994,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
P9_DPRINTK(P9_DEBUG_VFS,
"%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer);
- retval = buflen;
-
+ retval = strnlen(buffer, buflen);
done:
kfree(st);
return retval;
@@ -1062,7 +1061,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
__putname(link);
link = ERR_PTR(len);
} else
- link[len] = 0;
+ link[min(len, PATH_MAX-1)] = 0;
}
nd_set_link(nd, link);
diff --git a/fs/Kconfig b/fs/Kconfig
index d4bf8caad8d0..64d44efad7a5 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -135,8 +135,8 @@ config TMPFS_POSIX_ACL
config HUGETLBFS
bool "HugeTLB file system support"
- depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \
- (S390 && 64BIT) || SYS_SUPPORTS_HUGETLBFS || BROKEN
+ depends on X86 || IA64 || SPARC64 || (S390 && 64BIT) || \
+ SYS_SUPPORTS_HUGETLBFS || BROKEN
help
hugetlbfs is a filesystem backing for HugeTLB pages, based on
ramfs. For architectures that support it, say Y here and read
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 681c2a7b013f..39b301662f22 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -315,7 +315,6 @@ static void afs_invalidatepage(struct page *page, unsigned long offset)
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
fscache_wait_on_page_write(vnode->cache, page);
fscache_uncache_page(vnode->cache, page);
- ClearPageFsCache(page);
}
#endif
@@ -349,17 +348,9 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags)
/* deny if page is being written to the cache and the caller hasn't
* elected to wait */
#ifdef CONFIG_AFS_FSCACHE
- if (PageFsCache(page)) {
- if (fscache_check_page_write(vnode->cache, page)) {
- if (!(gfp_flags & __GFP_WAIT)) {
- _leave(" = F [cache busy]");
- return 0;
- }
- fscache_wait_on_page_write(vnode->cache, page);
- }
-
- fscache_uncache_page(vnode->cache, page);
- ClearPageFsCache(page);
+ if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) {
+ _leave(" = F [cache busy]");
+ return 0;
}
#endif
diff --git a/fs/bio.c b/fs/bio.c
index 402cb84a92a1..12da5db8682c 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -325,8 +325,16 @@ static void bio_fs_destructor(struct bio *bio)
* @gfp_mask: allocation mask to use
* @nr_iovecs: number of iovecs
*
- * Allocate a new bio with @nr_iovecs bvecs. If @gfp_mask
- * contains __GFP_WAIT, the allocation is guaranteed to succeed.
+ * bio_alloc will allocate a bio and associated bio_vec array that can hold
+ * at least @nr_iovecs entries. Allocations will be done from the
+ * fs_bio_set. Also see @bio_alloc_bioset and @bio_kmalloc.
+ *
+ * If %__GFP_WAIT is set, then bio_alloc will always be able to allocate
+ * a bio. This is due to the mempool guarantees. To make this work, callers
+ * must never allocate more than 1 bio at a time from this pool. Callers
+ * that need to allocate more than 1 bio must always submit the previously
+ * allocated bio for IO before attempting to allocate a new one. Failure to
+ * do so can cause livelocks under memory pressure.
*
* RETURNS:
* Pointer to new bio on success, NULL on failure.
@@ -350,21 +358,13 @@ static void bio_kmalloc_destructor(struct bio *bio)
}
/**
- * bio_alloc - allocate a bio for I/O
+ * bio_kmalloc - allocate a bio for I/O using kmalloc()
* @gfp_mask: the GFP_ mask given to the slab allocator
* @nr_iovecs: number of iovecs to pre-allocate
*
* Description:
- * bio_alloc will allocate a bio and associated bio_vec array that can hold
- * at least @nr_iovecs entries. Allocations will be done from the
- * fs_bio_set. Also see @bio_alloc_bioset.
- *
- * If %__GFP_WAIT is set, then bio_alloc will always be able to allocate
- * a bio. This is due to the mempool guarantees. To make this work, callers
- * must never allocate more than 1 bio at a time from this pool. Callers
- * that need to allocate more than 1 bio must always submit the previously
- * allocated bio for IO before attempting to allocate a new one. Failure to
- * do so can cause livelocks under memory pressure.
+ * Allocate a new bio with @nr_iovecs bvecs. If @gfp_mask contains
+ * %__GFP_WAIT, the allocation is guaranteed to succeed.
*
**/
struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs)
@@ -407,7 +407,7 @@ EXPORT_SYMBOL(zero_fill_bio);
*
* Description:
* Put a reference to a &struct bio, either one you have gotten with
- * bio_alloc or bio_get. The last put of a bio will free it.
+ * bio_alloc, bio_get or bio_clone. The last put of a bio will free it.
**/
void bio_put(struct bio *bio)
{
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 9cf4b926f8e4..8bed0557d88c 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1248,8 +1248,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
}
} else {
- put_disk(disk);
module_put(disk->fops->owner);
+ put_disk(disk);
disk = NULL;
if (bdev->bd_contains == bdev) {
if (bdev->bd_disk->fops->open) {
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 69b355ae7f49..361604244271 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -27,7 +27,7 @@
#include "btrfs_inode.h"
#include "xattr.h"
-#ifdef CONFIG_BTRFS_POSIX_ACL
+#ifdef CONFIG_BTRFS_FS_POSIX_ACL
static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
{
@@ -313,7 +313,7 @@ struct xattr_handler btrfs_xattr_acl_access_handler = {
.set = btrfs_xattr_acl_access_set,
};
-#else /* CONFIG_BTRFS_POSIX_ACL */
+#else /* CONFIG_BTRFS_FS_POSIX_ACL */
int btrfs_acl_chmod(struct inode *inode)
{
@@ -325,4 +325,4 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir)
return 0;
}
-#endif /* CONFIG_BTRFS_POSIX_ACL */
+#endif /* CONFIG_BTRFS_FS_POSIX_ACL */
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index c71abec0ab90..f6783a42f010 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -86,6 +86,12 @@ struct btrfs_inode {
* transid of the trans_handle that last modified this inode
*/
u64 last_trans;
+
+ /*
+ * log transid when this inode was last modified
+ */
+ u64 last_sub_trans;
+
/*
* transid that last logged this inode
*/
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 1bb897ecdeeb..444b3e9b92a4 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1009,6 +1009,7 @@ struct btrfs_root {
atomic_t log_writers;
atomic_t log_commit[2];
unsigned long log_transid;
+ unsigned long last_log_commit;
unsigned long log_batch;
pid_t log_start_pid;
bool log_multiple_pids;
@@ -1152,6 +1153,7 @@ struct btrfs_root {
#define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7)
#define BTRFS_MOUNT_SSD_SPREAD (1 << 8)
#define BTRFS_MOUNT_NOSSD (1 << 9)
+#define BTRFS_MOUNT_DISCARD (1 << 10)
#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
@@ -2373,7 +2375,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options);
int btrfs_sync_fs(struct super_block *sb, int wait);
/* acl.c */
-#ifdef CONFIG_BTRFS_POSIX_ACL
+#ifdef CONFIG_BTRFS_FS_POSIX_ACL
int btrfs_check_acl(struct inode *inode, int mask);
#else
#define btrfs_check_acl NULL
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 100551a66c46..02b6afbd7450 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -917,6 +917,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
atomic_set(&root->log_writers, 0);
root->log_batch = 0;
root->log_transid = 0;
+ root->last_log_commit = 0;
extent_io_tree_init(&root->dirty_log_pages,
fs_info->btree_inode->i_mapping, GFP_NOFS);
@@ -1087,6 +1088,7 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
WARN_ON(root->log_root);
root->log_root = log_root;
root->log_transid = 0;
+ root->last_log_commit = 0;
return 0;
}
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index d0c4d584efad..94627c4cc193 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1568,23 +1568,23 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
return ret;
}
-#ifdef BIO_RW_DISCARD
static void btrfs_issue_discard(struct block_device *bdev,
u64 start, u64 len)
{
blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL,
DISCARD_FL_BARRIER);
}
-#endif
static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
u64 num_bytes)
{
-#ifdef BIO_RW_DISCARD
int ret;
u64 map_length = num_bytes;
struct btrfs_multi_bio *multi = NULL;
+ if (!btrfs_test_opt(root, DISCARD))
+ return 0;
+
/* Tell the block device(s) that the sectors can be discarded */
ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
bytenr, &map_length, &multi, 0);
@@ -1604,9 +1604,6 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
}
return ret;
-#else
- return 0;
-#endif
}
int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
@@ -2980,10 +2977,10 @@ static int maybe_allocate_chunk(struct btrfs_root *root,
free_space = btrfs_super_total_bytes(disk_super);
/*
- * we allow the metadata to grow to a max of either 5gb or 5% of the
+ * we allow the metadata to grow to a max of either 10gb or 5% of the
* space in the volume.
*/
- min_metadata = min((u64)5 * 1024 * 1024 * 1024,
+ min_metadata = min((u64)10 * 1024 * 1024 * 1024,
div64_u64(free_space * 5, 100));
if (info->total_bytes >= min_metadata) {
spin_unlock(&info->lock);
@@ -3690,6 +3687,14 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans,
if (is_data)
goto pinit;
+ /*
+ * discard is sloooow, and so triggering discards on
+ * individual btree blocks isn't a good plan. Just
+ * pin everything in discard mode.
+ */
+ if (btrfs_test_opt(root, DISCARD))
+ goto pinit;
+
buf = btrfs_find_tree_block(root, bytenr, num_bytes);
if (!buf)
goto pinit;
@@ -4097,7 +4102,7 @@ wait_block_group_cache_done(struct btrfs_block_group_cache *cache)
}
enum btrfs_loop_type {
- LOOP_CACHED_ONLY = 0,
+ LOOP_FIND_IDEAL = 0,
LOOP_CACHING_NOWAIT = 1,
LOOP_CACHING_WAIT = 2,
LOOP_ALLOC_CHUNK = 3,
@@ -4126,12 +4131,15 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
struct btrfs_block_group_cache *block_group = NULL;
int empty_cluster = 2 * 1024 * 1024;
int allowed_chunk_alloc = 0;
+ int done_chunk_alloc = 0;
struct btrfs_space_info *space_info;
int last_ptr_loop = 0;
int loop = 0;
bool found_uncached_bg = false;
bool failed_cluster_refill = false;
bool failed_alloc = false;
+ u64 ideal_cache_percent = 0;
+ u64 ideal_cache_offset = 0;
WARN_ON(num_bytes < root->sectorsize);
btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
@@ -4167,14 +4175,19 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
empty_cluster = 0;
if (search_start == hint_byte) {
+ideal_cache:
block_group = btrfs_lookup_block_group(root->fs_info,
search_start);
/*
* we don't want to use the block group if it doesn't match our
* allocation bits, or if its not cached.
+ *
+ * However if we are re-searching with an ideal block group
+ * picked out then we don't care that the block group is cached.
*/
if (block_group && block_group_bits(block_group, data) &&
- block_group_cache_done(block_group)) {
+ (block_group->cached != BTRFS_CACHE_NO ||
+ search_start == ideal_cache_offset)) {
down_read(&space_info->groups_sem);
if (list_empty(&block_group->list) ||
block_group->ro) {
@@ -4186,13 +4199,13 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
*/
btrfs_put_block_group(block_group);
up_read(&space_info->groups_sem);
- } else
+ } else {
goto have_block_group;
+ }
} else if (block_group) {
btrfs_put_block_group(block_group);
}
}
-
search:
down_read(&space_info->groups_sem);
list_for_each_entry(block_group, &space_info->block_groups, list) {
@@ -4204,28 +4217,45 @@ search:
have_block_group:
if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
+ u64 free_percent;
+
+ free_percent = btrfs_block_group_used(&block_group->item);
+ free_percent *= 100;
+ free_percent = div64_u64(free_percent,
+ block_group->key.offset);
+ free_percent = 100 - free_percent;
+ if (free_percent > ideal_cache_percent &&
+ likely(!block_group->ro)) {
+ ideal_cache_offset = block_group->key.objectid;
+ ideal_cache_percent = free_percent;
+ }
+
/*
- * we want to start caching kthreads, but not too many
- * right off the bat so we don't overwhelm the system,
- * so only start them if there are less than 2 and we're
- * in the initial allocation phase.
+ * We only want to start kthread caching if we are at
+ * the point where we will wait for caching to make
+ * progress, or if our ideal search is over and we've
+ * found somebody to start caching.
*/
if (loop > LOOP_CACHING_NOWAIT ||
- atomic_read(&space_info->caching_threads) < 2) {
+ (loop > LOOP_FIND_IDEAL &&
+ atomic_read(&space_info->caching_threads) < 2)) {
ret = cache_block_group(block_group);
BUG_ON(ret);
}
- }
-
- cached = block_group_cache_done(block_group);
- if (unlikely(!cached)) {
found_uncached_bg = true;
- /* if we only want cached bgs, loop */
- if (loop == LOOP_CACHED_ONLY)
+ /*
+ * If loop is set for cached only, try the next block
+ * group.
+ */
+ if (loop == LOOP_FIND_IDEAL)
goto loop;
}
+ cached = block_group_cache_done(block_group);
+ if (unlikely(!cached))
+ found_uncached_bg = true;
+
if (unlikely(block_group->ro))
goto loop;
@@ -4405,9 +4435,11 @@ loop:
}
up_read(&space_info->groups_sem);
- /* LOOP_CACHED_ONLY, only search fully cached block groups
- * LOOP_CACHING_NOWAIT, search partially cached block groups, but
- * dont wait foR them to finish caching
+ /* LOOP_FIND_IDEAL, only search caching/cached bg's, and don't wait for
+ * for them to make caching progress. Also
+ * determine the best possible bg to cache
+ * LOOP_CACHING_NOWAIT, search partially cached block groups, kicking
+ * caching kthreads as we move along
* LOOP_CACHING_WAIT, search everything, and wait if our bg is caching
* LOOP_ALLOC_CHUNK, force a chunk allocation and try again
* LOOP_NO_EMPTY_SIZE, set empty_size and empty_cluster to 0 and try
@@ -4416,12 +4448,47 @@ loop:
if (!ins->objectid && loop < LOOP_NO_EMPTY_SIZE &&
(found_uncached_bg || empty_size || empty_cluster ||
allowed_chunk_alloc)) {
- if (found_uncached_bg) {
+ if (loop == LOOP_FIND_IDEAL && found_uncached_bg) {
found_uncached_bg = false;
- if (loop < LOOP_CACHING_WAIT) {
- loop++;
+ loop++;
+ if (!ideal_cache_percent &&
+ atomic_read(&space_info->caching_threads))
goto search;
- }
+
+ /*
+ * 1 of the following 2 things have happened so far
+ *
+ * 1) We found an ideal block group for caching that
+ * is mostly full and will cache quickly, so we might
+ * as well wait for it.
+ *
+ * 2) We searched for cached only and we didn't find
+ * anything, and we didn't start any caching kthreads
+ * either, so chances are we will loop through and
+ * start a couple caching kthreads, and then come back
+ * around and just wait for them. This will be slower
+ * because we will have 2 caching kthreads reading at
+ * the same time when we could have just started one
+ * and waited for it to get far enough to give us an
+ * allocation, so go ahead and go to the wait caching
+ * loop.
+ */
+ loop = LOOP_CACHING_WAIT;
+ search_start = ideal_cache_offset;
+ ideal_cache_percent = 0;
+ goto ideal_cache;
+ } else if (loop == LOOP_FIND_IDEAL) {
+ /*
+ * Didn't find a uncached bg, wait on anything we find
+ * next.
+ */
+ loop = LOOP_CACHING_WAIT;
+ goto search;
+ }
+
+ if (loop < LOOP_CACHING_WAIT) {
+ loop++;
+ goto search;
}
if (loop == LOOP_ALLOC_CHUNK) {
@@ -4433,7 +4500,8 @@ loop:
ret = do_chunk_alloc(trans, root, num_bytes +
2 * 1024 * 1024, data, 1);
allowed_chunk_alloc = 0;
- } else {
+ done_chunk_alloc = 1;
+ } else if (!done_chunk_alloc) {
space_info->force_alloc = 1;
}
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 2c726b7b9faa..ccbdcb54ec5d 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -208,7 +208,7 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len)
write_lock(&tree->lock);
em = lookup_extent_mapping(tree, start, len);
- WARN_ON(em->start != start || !em);
+ WARN_ON(!em || em->start != start);
if (!em)
goto out;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 2d623aa0625f..06550affbd27 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1086,8 +1086,10 @@ out_nolock:
btrfs_end_transaction(trans, root);
else
btrfs_commit_transaction(trans, root);
- } else {
+ } else if (ret != BTRFS_NO_LOG_SYNC) {
btrfs_commit_transaction(trans, root);
+ } else {
+ btrfs_end_transaction(trans, root);
}
}
if (file->f_flags & O_DIRECT) {
@@ -1137,6 +1139,13 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
int ret = 0;
struct btrfs_trans_handle *trans;
+
+ /* we wait first, since the writeback may change the inode */
+ root->log_batch++;
+ /* the VFS called filemap_fdatawrite for us */
+ btrfs_wait_ordered_range(inode, 0, (u64)-1);
+ root->log_batch++;
+
/*
* check the transaction that last modified this inode
* and see if its already been committed
@@ -1144,6 +1153,11 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
if (!BTRFS_I(inode)->last_trans)
goto out;
+ /*
+ * if the last transaction that changed this file was before
+ * the current transaction, we can bail out now without any
+ * syncing
+ */
mutex_lock(&root->fs_info->trans_mutex);
if (BTRFS_I(inode)->last_trans <=
root->fs_info->last_trans_committed) {
@@ -1153,13 +1167,6 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
}
mutex_unlock(&root->fs_info->trans_mutex);
- root->log_batch++;
- filemap_fdatawrite(inode->i_mapping);
- btrfs_wait_ordered_range(inode, 0, (u64)-1);
- root->log_batch++;
-
- if (datasync && !(inode->i_state & I_DIRTY_PAGES))
- goto out;
/*
* ok we haven't committed the transaction yet, lets do a commit
*/
@@ -1188,14 +1195,18 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
*/
mutex_unlock(&dentry->d_inode->i_mutex);
- if (ret > 0) {
- ret = btrfs_commit_transaction(trans, root);
- } else {
- ret = btrfs_sync_log(trans, root);
- if (ret == 0)
- ret = btrfs_end_transaction(trans, root);
- else
+ if (ret != BTRFS_NO_LOG_SYNC) {
+ if (ret > 0) {
ret = btrfs_commit_transaction(trans, root);
+ } else {
+ ret = btrfs_sync_log(trans, root);
+ if (ret == 0)
+ ret = btrfs_end_transaction(trans, root);
+ else
+ ret = btrfs_commit_transaction(trans, root);
+ }
+ } else {
+ ret = btrfs_end_transaction(trans, root);
}
mutex_lock(&dentry->d_inode->i_mutex);
out:
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 5c2caad76212..cb2849f03251 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -1296,7 +1296,7 @@ again:
window_start = entry->offset;
window_free = entry->bytes;
last = entry;
- max_extent = 0;
+ max_extent = entry->bytes;
} else {
last = next;
window_free += next->bytes;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 9e138b793dc7..b3ad168a0bfc 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -538,7 +538,7 @@ static noinline int submit_compressed_extents(struct inode *inode,
struct btrfs_root *root = BTRFS_I(inode)->root;
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
struct extent_io_tree *io_tree;
- int ret;
+ int ret = 0;
if (list_empty(&async_cow->extents))
return 0;
@@ -552,6 +552,7 @@ static noinline int submit_compressed_extents(struct inode *inode,
io_tree = &BTRFS_I(inode)->io_tree;
+retry:
/* did the compression code fall back to uncompressed IO? */
if (!async_extent->pages) {
int page_started = 0;
@@ -562,11 +563,11 @@ static noinline int submit_compressed_extents(struct inode *inode,
async_extent->ram_size - 1, GFP_NOFS);
/* allocate blocks */
- cow_file_range(inode, async_cow->locked_page,
- async_extent->start,
- async_extent->start +
- async_extent->ram_size - 1,
- &page_started, &nr_written, 0);
+ ret = cow_file_range(inode, async_cow->locked_page,
+ async_extent->start,
+ async_extent->start +
+ async_extent->ram_size - 1,
+ &page_started, &nr_written, 0);
/*
* if page_started, cow_file_range inserted an
@@ -574,7 +575,7 @@ static noinline int submit_compressed_extents(struct inode *inode,
* and IO for us. Otherwise, we need to submit
* all those pages down to the drive.
*/
- if (!page_started)
+ if (!page_started && !ret)
extent_write_locked_range(io_tree,
inode, async_extent->start,
async_extent->start +
@@ -602,7 +603,21 @@ static noinline int submit_compressed_extents(struct inode *inode,
async_extent->compressed_size,
0, alloc_hint,
(u64)-1, &ins, 1);
- BUG_ON(ret);
+ if (ret) {
+ int i;
+ for (i = 0; i < async_extent->nr_pages; i++) {
+ WARN_ON(async_extent->pages[i]->mapping);
+ page_cache_release(async_extent->pages[i]);
+ }
+ kfree(async_extent->pages);
+ async_extent->nr_pages = 0;
+ async_extent->pages = NULL;
+ unlock_extent(io_tree, async_extent->start,
+ async_extent->start +
+ async_extent->ram_size - 1, GFP_NOFS);
+ goto retry;
+ }
+
em = alloc_extent_map(GFP_NOFS);
em->start = async_extent->start;
em->len = async_extent->ram_size;
@@ -743,8 +758,22 @@ static noinline int cow_file_range(struct inode *inode,
em = search_extent_mapping(&BTRFS_I(inode)->extent_tree,
start, num_bytes);
if (em) {
- alloc_hint = em->block_start;
- free_extent_map(em);
+ /*
+ * if block start isn't an actual block number then find the
+ * first block in this inode and use that as a hint. If that
+ * block is also bogus then just don't worry about it.
+ */
+ if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
+ free_extent_map(em);
+ em = search_extent_mapping(em_tree, 0, 0);
+ if (em && em->block_start < EXTENT_MAP_LAST_BYTE)
+ alloc_hint = em->block_start;
+ if (em)
+ free_extent_map(em);
+ } else {
+ alloc_hint = em->block_start;
+ free_extent_map(em);
+ }
}
read_unlock(&BTRFS_I(inode)->extent_tree.lock);
btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0);
@@ -2474,7 +2503,19 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
root = BTRFS_I(dir)->root;
+ /*
+ * 5 items for unlink inode
+ * 1 for orphan
+ */
+ ret = btrfs_reserve_metadata_space(root, 6);
+ if (ret)
+ return ret;
+
trans = btrfs_start_transaction(root, 1);
+ if (IS_ERR(trans)) {
+ btrfs_unreserve_metadata_space(root, 6);
+ return PTR_ERR(trans);
+ }
btrfs_set_trans_block_group(trans, dir);
@@ -2489,6 +2530,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
nr = trans->blocks_used;
btrfs_end_transaction_throttle(trans, root);
+ btrfs_unreserve_metadata_space(root, 6);
btrfs_btree_balance_dirty(root, nr);
return ret;
}
@@ -2569,7 +2611,16 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
return -ENOTEMPTY;
+ ret = btrfs_reserve_metadata_space(root, 5);
+ if (ret)
+ return ret;
+
trans = btrfs_start_transaction(root, 1);
+ if (IS_ERR(trans)) {
+ btrfs_unreserve_metadata_space(root, 5);
+ return PTR_ERR(trans);
+ }
+
btrfs_set_trans_block_group(trans, dir);
if (unlikely(inode->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) {
@@ -2592,6 +2643,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
out:
nr = trans->blocks_used;
ret = btrfs_end_transaction_throttle(trans, root);
+ btrfs_unreserve_metadata_space(root, 5);
btrfs_btree_balance_dirty(root, nr);
if (ret && !err)
@@ -3032,12 +3084,22 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
if ((offset & (blocksize - 1)) == 0)
goto out;
+ ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE);
+ if (ret)
+ goto out;
+
+ ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
+ if (ret)
+ goto out;
ret = -ENOMEM;
again:
page = grab_cache_page(mapping, index);
- if (!page)
+ if (!page) {
+ btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+ btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
goto out;
+ }
page_start = page_offset(page);
page_end = page_start + PAGE_CACHE_SIZE - 1;
@@ -3070,6 +3132,10 @@ again:
goto again;
}
+ clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+ EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
+ GFP_NOFS);
+
ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
if (ret) {
unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
@@ -3088,6 +3154,9 @@ again:
unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
out_unlock:
+ if (ret)
+ btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+ btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
unlock_page(page);
page_cache_release(page);
out:
@@ -3111,7 +3180,9 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
if (size <= hole_start)
return 0;
- btrfs_truncate_page(inode->i_mapping, inode->i_size);
+ err = btrfs_truncate_page(inode->i_mapping, inode->i_size);
+ if (err)
+ return err;
while (1) {
struct btrfs_ordered_extent *ordered;
@@ -3480,6 +3551,7 @@ static noinline void init_btrfs_i(struct inode *inode)
bi->generation = 0;
bi->sequence = 0;
bi->last_trans = 0;
+ bi->last_sub_trans = 0;
bi->logged_trans = 0;
bi->delalloc_bytes = 0;
bi->reserved_bytes = 0;
@@ -4980,7 +5052,9 @@ again:
set_page_dirty(page);
SetPageUptodate(page);
- BTRFS_I(inode)->last_trans = root->fs_info->generation + 1;
+ BTRFS_I(inode)->last_trans = root->fs_info->generation;
+ BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
+
unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
out_unlock:
@@ -5005,7 +5079,9 @@ static void btrfs_truncate(struct inode *inode)
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
- btrfs_truncate_page(inode->i_mapping, inode->i_size);
+ ret = btrfs_truncate_page(inode->i_mapping, inode->i_size);
+ if (ret)
+ return;
btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1);
trans = btrfs_start_transaction(root, 1);
@@ -5100,9 +5176,11 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
if (!ei)
return NULL;
ei->last_trans = 0;
+ ei->last_sub_trans = 0;
ei->logged_trans = 0;
ei->outstanding_extents = 0;
ei->reserved_extents = 0;
+ ei->root = NULL;
spin_lock_init(&ei->accounting_lock);
btrfs_ordered_inode_tree_init(&ei->ordered_tree);
INIT_LIST_HEAD(&ei->i_orphan);
@@ -5119,6 +5197,14 @@ void btrfs_destroy_inode(struct inode *inode)
WARN_ON(inode->i_data.nrpages);
/*
+ * This can happen where we create an inode, but somebody else also
+ * created the same inode and we need to destroy the one we already
+ * created.
+ */
+ if (!root)
+ goto free;
+
+ /*
* Make sure we're properly removed from the ordered operation
* lists.
*/
@@ -5153,6 +5239,7 @@ void btrfs_destroy_inode(struct inode *inode)
}
inode_tree_del(inode);
btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
+free:
kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
}
@@ -5258,11 +5345,14 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
return -ENOTEMPTY;
/*
- * 2 items for dir items
- * 1 item for orphan entry
- * 1 item for ref
+ * We want to reserve the absolute worst case amount of items. So if
+ * both inodes are subvols and we need to unlink them then that would
+ * require 4 item modifications, but if they are both normal inodes it
+ * would require 5 item modifications, so we'll assume their normal
+ * inodes. So 5 * 2 is 10, plus 1 for the new link, so 11 total items
+ * should cover the worst case number of items we'll modify.
*/
- ret = btrfs_reserve_metadata_space(root, 4);
+ ret = btrfs_reserve_metadata_space(root, 11);
if (ret)
return ret;
@@ -5378,7 +5468,7 @@ out_fail:
if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
up_read(&root->fs_info->subvol_sem);
- btrfs_unreserve_metadata_space(root, 4);
+ btrfs_unreserve_metadata_space(root, 11);
return ret;
}
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 9351428f30e2..67fa2d29d663 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -159,7 +159,6 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
write_extent_buffer(l, item, ptr, sizeof(*item));
btrfs_mark_buffer_dirty(path->nodes[0]);
out:
- btrfs_release_path(root, path);
btrfs_free_path(path);
return ret;
}
@@ -332,7 +331,6 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
BUG_ON(refs != 0);
ret = btrfs_del_item(trans, root, path);
out:
- btrfs_release_path(root, path);
btrfs_free_path(path);
return ret;
}
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 9de9b2236419..752a5463bf53 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -66,7 +66,8 @@ enum {
Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl,
- Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_err,
+ Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
+ Opt_discard, Opt_err,
};
static match_table_t tokens = {
@@ -88,6 +89,7 @@ static match_table_t tokens = {
{Opt_notreelog, "notreelog"},
{Opt_flushoncommit, "flushoncommit"},
{Opt_ratio, "metadata_ratio=%d"},
+ {Opt_discard, "discard"},
{Opt_err, NULL},
};
@@ -257,6 +259,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
info->metadata_ratio);
}
break;
+ case Opt_discard:
+ btrfs_set_opt(info->mount_opt, DISCARD);
+ break;
default:
break;
}
@@ -344,7 +349,7 @@ static int btrfs_fill_super(struct super_block *sb,
sb->s_export_op = &btrfs_export_ops;
sb->s_xattr = btrfs_xattr_handlers;
sb->s_time_gran = 1;
-#ifdef CONFIG_BTRFS_POSIX_ACL
+#ifdef CONFIG_BTRFS_FS_POSIX_ACL
sb->s_flags |= MS_POSIXACL;
#endif
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 0b8f36d4400a..c207e8c32c9b 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -163,8 +163,14 @@ static void wait_current_trans(struct btrfs_root *root)
}
}
+enum btrfs_trans_type {
+ TRANS_START,
+ TRANS_JOIN,
+ TRANS_USERSPACE,
+};
+
static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
- int num_blocks, int wait)
+ int num_blocks, int type)
{
struct btrfs_trans_handle *h =
kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
@@ -172,7 +178,8 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
mutex_lock(&root->fs_info->trans_mutex);
if (!root->fs_info->log_root_recovering &&
- ((wait == 1 && !root->fs_info->open_ioctl_trans) || wait == 2))
+ ((type == TRANS_START && !root->fs_info->open_ioctl_trans) ||
+ type == TRANS_USERSPACE))
wait_current_trans(root);
ret = join_transaction(root);
BUG_ON(ret);
@@ -186,7 +193,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
h->alloc_exclude_start = 0;
h->delayed_ref_updates = 0;
- if (!current->journal_info)
+ if (!current->journal_info && type != TRANS_USERSPACE)
current->journal_info = h;
root->fs_info->running_transaction->use_count++;
@@ -198,18 +205,18 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
int num_blocks)
{
- return start_transaction(root, num_blocks, 1);
+ return start_transaction(root, num_blocks, TRANS_START);
}
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
int num_blocks)
{
- return start_transaction(root, num_blocks, 0);
+ return start_transaction(root, num_blocks, TRANS_JOIN);
}
struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
int num_blocks)
{
- return start_transaction(r, num_blocks, 2);
+ return start_transaction(r, num_blocks, TRANS_USERSPACE);
}
/* wait for a transaction commit to be fully complete */
@@ -344,10 +351,10 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
/*
* when btree blocks are allocated, they have some corresponding bits set for
* them in one of two extent_io trees. This is used to make sure all of
- * those extents are on disk for transaction or log commit
+ * those extents are sent to disk but does not wait on them
*/
-int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
- struct extent_io_tree *dirty_pages)
+int btrfs_write_marked_extents(struct btrfs_root *root,
+ struct extent_io_tree *dirty_pages)
{
int ret;
int err = 0;
@@ -394,6 +401,29 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
page_cache_release(page);
}
}
+ if (err)
+ werr = err;
+ return werr;
+}
+
+/*
+ * when btree blocks are allocated, they have some corresponding bits set for
+ * them in one of two extent_io trees. This is used to make sure all of
+ * those extents are on disk for transaction or log commit. We wait
+ * on all the pages and clear them from the dirty pages state tree
+ */
+int btrfs_wait_marked_extents(struct btrfs_root *root,
+ struct extent_io_tree *dirty_pages)
+{
+ int ret;
+ int err = 0;
+ int werr = 0;
+ struct page *page;
+ struct inode *btree_inode = root->fs_info->btree_inode;
+ u64 start = 0;
+ u64 end;
+ unsigned long index;
+
while (1) {
ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
EXTENT_DIRTY);
@@ -424,6 +454,22 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
return werr;
}
+/*
+ * when btree blocks are allocated, they have some corresponding bits set for
+ * them in one of two extent_io trees. This is used to make sure all of
+ * those extents are on disk for transaction or log commit
+ */
+int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
+ struct extent_io_tree *dirty_pages)
+{
+ int ret;
+ int ret2;
+
+ ret = btrfs_write_marked_extents(root, dirty_pages);
+ ret2 = btrfs_wait_marked_extents(root, dirty_pages);
+ return ret || ret2;
+}
+
int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index 663c67404918..d4e3e7a6938c 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -79,6 +79,7 @@ static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
struct inode *inode)
{
BTRFS_I(inode)->last_trans = trans->transaction->transid;
+ BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
}
int btrfs_end_transaction(struct btrfs_trans_handle *trans,
@@ -107,5 +108,9 @@ int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
struct extent_io_tree *dirty_pages);
+int btrfs_write_marked_extents(struct btrfs_root *root,
+ struct extent_io_tree *dirty_pages);
+int btrfs_wait_marked_extents(struct btrfs_root *root,
+ struct extent_io_tree *dirty_pages);
int btrfs_transaction_in_commit(struct btrfs_fs_info *info);
#endif
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 4edfdc2acc5f..741666a7676a 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1980,6 +1980,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
int ret;
struct btrfs_root *log = root->log_root;
struct btrfs_root *log_root_tree = root->fs_info->log_root_tree;
+ u64 log_transid = 0;
mutex_lock(&root->log_mutex);
index1 = root->log_transid % 2;
@@ -1994,12 +1995,13 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
wait_log_commit(trans, root, root->log_transid - 1);
- while (root->log_multiple_pids) {
+ while (1) {
unsigned long batch = root->log_batch;
- mutex_unlock(&root->log_mutex);
- schedule_timeout_uninterruptible(1);
- mutex_lock(&root->log_mutex);
-
+ if (root->log_multiple_pids) {
+ mutex_unlock(&root->log_mutex);
+ schedule_timeout_uninterruptible(1);
+ mutex_lock(&root->log_mutex);
+ }
wait_for_writer(trans, root);
if (batch == root->log_batch)
break;
@@ -2012,12 +2014,16 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
goto out;
}
- ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages);
+ /* we start IO on all the marked extents here, but we don't actually
+ * wait for them until later.
+ */
+ ret = btrfs_write_marked_extents(log, &log->dirty_log_pages);
BUG_ON(ret);
btrfs_set_root_node(&log->root_item, log->node);
root->log_batch = 0;
+ log_transid = root->log_transid;
root->log_transid++;
log->log_transid = root->log_transid;
root->log_start_pid = 0;
@@ -2046,6 +2052,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
index2 = log_root_tree->log_transid % 2;
if (atomic_read(&log_root_tree->log_commit[index2])) {
+ btrfs_wait_marked_extents(log, &log->dirty_log_pages);
wait_log_commit(trans, log_root_tree,
log_root_tree->log_transid);
mutex_unlock(&log_root_tree->log_mutex);
@@ -2065,6 +2072,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
* check the full commit flag again
*/
if (root->fs_info->last_trans_log_full_commit == trans->transid) {
+ btrfs_wait_marked_extents(log, &log->dirty_log_pages);
mutex_unlock(&log_root_tree->log_mutex);
ret = -EAGAIN;
goto out_wake_log_root;
@@ -2073,6 +2081,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
ret = btrfs_write_and_wait_marked_extents(log_root_tree,
&log_root_tree->dirty_log_pages);
BUG_ON(ret);
+ btrfs_wait_marked_extents(log, &log->dirty_log_pages);
btrfs_set_super_log_root(&root->fs_info->super_for_commit,
log_root_tree->node->start);
@@ -2092,9 +2101,14 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
* the running transaction open, so a full commit can't hop
* in and cause problems either.
*/
- write_ctree_super(trans, root->fs_info->tree_root, 2);
+ write_ctree_super(trans, root->fs_info->tree_root, 1);
ret = 0;
+ mutex_lock(&root->log_mutex);
+ if (root->last_log_commit < log_transid)
+ root->last_log_commit = log_transid;
+ mutex_unlock(&root->log_mutex);
+
out_wake_log_root:
atomic_set(&log_root_tree->log_commit[index2], 0);
smp_mb();
@@ -2862,6 +2876,21 @@ out:
return ret;
}
+static int inode_in_log(struct btrfs_trans_handle *trans,
+ struct inode *inode)
+{
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ int ret = 0;
+
+ mutex_lock(&root->log_mutex);
+ if (BTRFS_I(inode)->logged_trans == trans->transid &&
+ BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
+ ret = 1;
+ mutex_unlock(&root->log_mutex);
+ return ret;
+}
+
+
/*
* helper function around btrfs_log_inode to make sure newly created
* parent directories also end up in the log. A minimal inode and backref
@@ -2901,6 +2930,11 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
if (ret)
goto end_no_trans;
+ if (inode_in_log(trans, inode)) {
+ ret = BTRFS_NO_LOG_SYNC;
+ goto end_no_trans;
+ }
+
start_log_trans(trans, root);
ret = btrfs_log_inode(trans, root, inode, inode_only);
diff --git a/fs/btrfs/tree-log.h b/fs/btrfs/tree-log.h
index d09c7609e16b..0776eacb5083 100644
--- a/fs/btrfs/tree-log.h
+++ b/fs/btrfs/tree-log.h
@@ -19,6 +19,9 @@
#ifndef __TREE_LOG_
#define __TREE_LOG_
+/* return value for btrfs_log_dentry_safe that means we don't need to log it at all */
+#define BTRFS_NO_LOG_SYNC 256
+
int btrfs_sync_log(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root);
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index b0fc93f95fd0..b6dd5967c48a 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -260,7 +260,7 @@ err:
* attributes are handled directly.
*/
struct xattr_handler *btrfs_xattr_handlers[] = {
-#ifdef CONFIG_BTRFS_POSIX_ACL
+#ifdef CONFIG_BTRFS_FS_POSIX_ACL
&btrfs_xattr_acl_access_handler,
&btrfs_xattr_acl_default_handler,
#endif
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 431accd475a7..27089311fbea 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -114,8 +114,9 @@ nomem_lookup_data:
/*
* attempt to look up the nominated node in this cache
+ * - return -ETIMEDOUT to be scheduled again
*/
-static void cachefiles_lookup_object(struct fscache_object *_object)
+static int cachefiles_lookup_object(struct fscache_object *_object)
{
struct cachefiles_lookup_data *lookup_data;
struct cachefiles_object *parent, *object;
@@ -145,13 +146,15 @@ static void cachefiles_lookup_object(struct fscache_object *_object)
object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX)
cachefiles_attr_changed(&object->fscache);
- if (ret < 0) {
- printk(KERN_WARNING "CacheFiles: Lookup failed error %d\n",
- ret);
+ if (ret < 0 && ret != -ETIMEDOUT) {
+ if (ret != -ENOBUFS)
+ printk(KERN_WARNING
+ "CacheFiles: Lookup failed error %d\n", ret);
fscache_object_lookup_error(&object->fscache);
}
_leave(" [%d]", ret);
+ return ret;
}
/*
@@ -331,6 +334,7 @@ static void cachefiles_put_object(struct fscache_object *_object)
}
cache = object->fscache.cache;
+ fscache_object_destroy(&object->fscache);
kmem_cache_free(cachefiles_object_jar, object);
fscache_object_destroyed(cache);
}
@@ -403,12 +407,26 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
if (oi_size == ni_size)
return 0;
- newattrs.ia_size = ni_size;
- newattrs.ia_valid = ATTR_SIZE;
-
cachefiles_begin_secure(cache, &saved_cred);
mutex_lock(&object->backer->d_inode->i_mutex);
+
+ /* if there's an extension to a partial page at the end of the backing
+ * file, we need to discard the partial page so that we pick up new
+ * data after it */
+ if (oi_size & ~PAGE_MASK && ni_size > oi_size) {
+ _debug("discard tail %llx", oi_size);
+ newattrs.ia_valid = ATTR_SIZE;
+ newattrs.ia_size = oi_size & PAGE_MASK;
+ ret = notify_change(object->backer, &newattrs);
+ if (ret < 0)
+ goto truncate_failed;
+ }
+
+ newattrs.ia_valid = ATTR_SIZE;
+ newattrs.ia_size = ni_size;
ret = notify_change(object->backer, &newattrs);
+
+truncate_failed:
mutex_unlock(&object->backer->d_inode->i_mutex);
cachefiles_end_secure(cache, saved_cred);
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index 4ce818ae39ea..14ac4806e291 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -21,17 +21,81 @@
#include <linux/security.h>
#include "internal.h"
-static int cachefiles_wait_bit(void *flags)
+#define CACHEFILES_KEYBUF_SIZE 512
+
+/*
+ * dump debugging info about an object
+ */
+static noinline
+void __cachefiles_printk_object(struct cachefiles_object *object,
+ const char *prefix,
+ u8 *keybuf)
{
- schedule();
- return 0;
+ struct fscache_cookie *cookie;
+ unsigned keylen, loop;
+
+ printk(KERN_ERR "%sobject: OBJ%x\n",
+ prefix, object->fscache.debug_id);
+ printk(KERN_ERR "%sobjstate=%s fl=%lx swfl=%lx ev=%lx[%lx]\n",
+ prefix, fscache_object_states[object->fscache.state],
+ object->fscache.flags, object->fscache.work.flags,
+ object->fscache.events,
+ object->fscache.event_mask & FSCACHE_OBJECT_EVENTS_MASK);
+ printk(KERN_ERR "%sops=%u inp=%u exc=%u\n",
+ prefix, object->fscache.n_ops, object->fscache.n_in_progress,
+ object->fscache.n_exclusive);
+ printk(KERN_ERR "%sparent=%p\n",
+ prefix, object->fscache.parent);
+
+ spin_lock(&object->fscache.lock);
+ cookie = object->fscache.cookie;
+ if (cookie) {
+ printk(KERN_ERR "%scookie=%p [pr=%p nd=%p fl=%lx]\n",
+ prefix,
+ object->fscache.cookie,
+ object->fscache.cookie->parent,
+ object->fscache.cookie->netfs_data,
+ object->fscache.cookie->flags);
+ if (keybuf)
+ keylen = cookie->def->get_key(cookie->netfs_data, keybuf,
+ CACHEFILES_KEYBUF_SIZE);
+ else
+ keylen = 0;
+ } else {
+ printk(KERN_ERR "%scookie=NULL\n", prefix);
+ keylen = 0;
+ }
+ spin_unlock(&object->fscache.lock);
+
+ if (keylen) {
+ printk(KERN_ERR "%skey=[%u] '", prefix, keylen);
+ for (loop = 0; loop < keylen; loop++)
+ printk("%02x", keybuf[loop]);
+ printk("'\n");
+ }
+}
+
+/*
+ * dump debugging info about a pair of objects
+ */
+static noinline void cachefiles_printk_object(struct cachefiles_object *object,
+ struct cachefiles_object *xobject)
+{
+ u8 *keybuf;
+
+ keybuf = kmalloc(CACHEFILES_KEYBUF_SIZE, GFP_NOIO);
+ if (object)
+ __cachefiles_printk_object(object, "", keybuf);
+ if (xobject)
+ __cachefiles_printk_object(xobject, "x", keybuf);
+ kfree(keybuf);
}
/*
* record the fact that an object is now active
*/
-static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
- struct cachefiles_object *object)
+static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
+ struct cachefiles_object *object)
{
struct cachefiles_object *xobject;
struct rb_node **_p, *_parent = NULL;
@@ -42,8 +106,11 @@ static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
try_again:
write_lock(&cache->active_lock);
- if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags))
+ if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
+ printk(KERN_ERR "CacheFiles: Error: Object already active\n");
+ cachefiles_printk_object(object, NULL);
BUG();
+ }
dentry = object->dentry;
_p = &cache->active_nodes.rb_node;
@@ -66,8 +133,8 @@ try_again:
rb_insert_color(&object->active_node, &cache->active_nodes);
write_unlock(&cache->active_lock);
- _leave("");
- return;
+ _leave(" = 0");
+ return 0;
/* an old object from a previous incarnation is hogging the slot - we
* need to wait for it to be destroyed */
@@ -76,44 +143,70 @@ wait_for_old_object:
printk(KERN_ERR "\n");
printk(KERN_ERR "CacheFiles: Error:"
" Unexpected object collision\n");
- printk(KERN_ERR "xobject: OBJ%x\n",
- xobject->fscache.debug_id);
- printk(KERN_ERR "xobjstate=%s\n",
- fscache_object_states[xobject->fscache.state]);
- printk(KERN_ERR "xobjflags=%lx\n", xobject->fscache.flags);
- printk(KERN_ERR "xobjevent=%lx [%lx]\n",
- xobject->fscache.events, xobject->fscache.event_mask);
- printk(KERN_ERR "xops=%u inp=%u exc=%u\n",
- xobject->fscache.n_ops, xobject->fscache.n_in_progress,
- xobject->fscache.n_exclusive);
- printk(KERN_ERR "xcookie=%p [pr=%p nd=%p fl=%lx]\n",
- xobject->fscache.cookie,
- xobject->fscache.cookie->parent,
- xobject->fscache.cookie->netfs_data,
- xobject->fscache.cookie->flags);
- printk(KERN_ERR "xparent=%p\n",
- xobject->fscache.parent);
- printk(KERN_ERR "object: OBJ%x\n",
- object->fscache.debug_id);
- printk(KERN_ERR "cookie=%p [pr=%p nd=%p fl=%lx]\n",
- object->fscache.cookie,
- object->fscache.cookie->parent,
- object->fscache.cookie->netfs_data,
- object->fscache.cookie->flags);
- printk(KERN_ERR "parent=%p\n",
- object->fscache.parent);
+ cachefiles_printk_object(object, xobject);
BUG();
}
atomic_inc(&xobject->usage);
write_unlock(&cache->active_lock);
- _debug(">>> wait");
- wait_on_bit(&xobject->flags, CACHEFILES_OBJECT_ACTIVE,
- cachefiles_wait_bit, TASK_UNINTERRUPTIBLE);
- _debug("<<< waited");
+ if (test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) {
+ wait_queue_head_t *wq;
+
+ signed long timeout = 60 * HZ;
+ wait_queue_t wait;
+ bool requeue;
+
+ /* if the object we're waiting for is queued for processing,
+ * then just put ourselves on the queue behind it */
+ if (slow_work_is_queued(&xobject->fscache.work)) {
+ _debug("queue OBJ%x behind OBJ%x immediately",
+ object->fscache.debug_id,
+ xobject->fscache.debug_id);
+ goto requeue;
+ }
+
+ /* otherwise we sleep until either the object we're waiting for
+ * is done, or the slow-work facility wants the thread back to
+ * do other work */
+ wq = bit_waitqueue(&xobject->flags, CACHEFILES_OBJECT_ACTIVE);
+ init_wait(&wait);
+ requeue = false;
+ do {
+ prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
+ if (!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags))
+ break;
+ requeue = slow_work_sleep_till_thread_needed(
+ &object->fscache.work, &timeout);
+ } while (timeout > 0 && !requeue);
+ finish_wait(wq, &wait);
+
+ if (requeue &&
+ test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) {
+ _debug("queue OBJ%x behind OBJ%x after wait",
+ object->fscache.debug_id,
+ xobject->fscache.debug_id);
+ goto requeue;
+ }
+
+ if (timeout <= 0) {
+ printk(KERN_ERR "\n");
+ printk(KERN_ERR "CacheFiles: Error: Overlong"
+ " wait for old active object to go away\n");
+ cachefiles_printk_object(object, xobject);
+ goto requeue;
+ }
+ }
+
+ ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));
cache->cache.ops->put_object(&xobject->fscache);
goto try_again;
+
+requeue:
+ clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
+ cache->cache.ops->put_object(&xobject->fscache);
+ _leave(" = -ETIMEDOUT");
+ return -ETIMEDOUT;
}
/*
@@ -254,7 +347,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
dir = dget_parent(object->dentry);
- mutex_lock(&dir->d_inode->i_mutex);
+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
ret = cachefiles_bury_object(cache, dir, object->dentry);
dput(dir);
@@ -307,7 +400,7 @@ lookup_again:
/* search the current directory for the element name */
_debug("lookup '%s'", name);
- mutex_lock(&dir->d_inode->i_mutex);
+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
start = jiffies;
next = lookup_one_len(name, dir, nlen);
@@ -418,12 +511,15 @@ lookup_again:
}
/* note that we're now using this object */
- cachefiles_mark_object_active(cache, object);
+ ret = cachefiles_mark_object_active(cache, object);
mutex_unlock(&dir->d_inode->i_mutex);
dput(dir);
dir = NULL;
+ if (ret == -ETIMEDOUT)
+ goto mark_active_timed_out;
+
_debug("=== OBTAINED_OBJECT ===");
if (object->new) {
@@ -467,6 +563,10 @@ create_error:
cachefiles_io_error(cache, "Create/mkdir failed");
goto error;
+mark_active_timed_out:
+ _debug("mark active timed out");
+ goto release_dentry;
+
check_error:
_debug("check error %d", ret);
write_lock(&cache->active_lock);
@@ -474,7 +574,7 @@ check_error:
clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE);
write_unlock(&cache->active_lock);
-
+release_dentry:
dput(object->dentry);
object->dentry = NULL;
goto error_out;
@@ -495,9 +595,6 @@ error:
error_out2:
dput(dir);
error_out:
- if (ret == -ENOSPC)
- ret = -ENOBUFS;
-
_leave(" = error %d", -ret);
return ret;
}
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index a69787e7dd96..a6c8c6fe8df9 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -11,6 +11,7 @@
#include <linux/mount.h>
#include <linux/file.h>
+#include <linux/ima.h>
#include "internal.h"
/*
@@ -40,8 +41,10 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
_debug("--- monitor %p %lx ---", page, page->flags);
- if (!PageUptodate(page) && !PageError(page))
- dump_stack();
+ if (!PageUptodate(page) && !PageError(page)) {
+ /* unlocked, not uptodate and not erronous? */
+ _debug("page probably truncated");
+ }
/* remove from the waitqueue */
list_del(&wait->task_list);
@@ -61,6 +64,84 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
}
/*
+ * handle a probably truncated page
+ * - check to see if the page is still relevant and reissue the read if
+ * possible
+ * - return -EIO on error, -ENODATA if the page is gone, -EINPROGRESS if we
+ * must wait again and 0 if successful
+ */
+static int cachefiles_read_reissue(struct cachefiles_object *object,
+ struct cachefiles_one_read *monitor)
+{
+ struct address_space *bmapping = object->backer->d_inode->i_mapping;
+ struct page *backpage = monitor->back_page, *backpage2;
+ int ret;
+
+ kenter("{ino=%lx},{%lx,%lx}",
+ object->backer->d_inode->i_ino,
+ backpage->index, backpage->flags);
+
+ /* skip if the page was truncated away completely */
+ if (backpage->mapping != bmapping) {
+ kleave(" = -ENODATA [mapping]");
+ return -ENODATA;
+ }
+
+ backpage2 = find_get_page(bmapping, backpage->index);
+ if (!backpage2) {
+ kleave(" = -ENODATA [gone]");
+ return -ENODATA;
+ }
+
+ if (backpage != backpage2) {
+ put_page(backpage2);
+ kleave(" = -ENODATA [different]");
+ return -ENODATA;
+ }
+
+ /* the page is still there and we already have a ref on it, so we don't
+ * need a second */
+ put_page(backpage2);
+
+ INIT_LIST_HEAD(&monitor->op_link);
+ add_page_wait_queue(backpage, &monitor->monitor);
+
+ if (trylock_page(backpage)) {
+ ret = -EIO;
+ if (PageError(backpage))
+ goto unlock_discard;
+ ret = 0;
+ if (PageUptodate(backpage))
+ goto unlock_discard;
+
+ kdebug("reissue read");
+ ret = bmapping->a_ops->readpage(NULL, backpage);
+ if (ret < 0)
+ goto unlock_discard;
+ }
+
+ /* but the page may have been read before the monitor was installed, so
+ * the monitor may miss the event - so we have to ensure that we do get
+ * one in such a case */
+ if (trylock_page(backpage)) {
+ _debug("jumpstart %p {%lx}", backpage, backpage->flags);
+ unlock_page(backpage);
+ }
+
+ /* it'll reappear on the todo list */
+ kleave(" = -EINPROGRESS");
+ return -EINPROGRESS;
+
+unlock_discard:
+ unlock_page(backpage);
+ spin_lock_irq(&object->work_lock);
+ list_del(&monitor->op_link);
+ spin_unlock_irq(&object->work_lock);
+ kleave(" = %d", ret);
+ return ret;
+}
+
+/*
* copy data from backing pages to netfs pages to complete a read operation
* - driven by FS-Cache's thread pool
*/
@@ -92,20 +173,26 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
_debug("- copy {%lu}", monitor->back_page->index);
- error = -EIO;
+ recheck:
if (PageUptodate(monitor->back_page)) {
copy_highpage(monitor->netfs_page, monitor->back_page);
pagevec_add(&pagevec, monitor->netfs_page);
fscache_mark_pages_cached(monitor->op, &pagevec);
error = 0;
- }
-
- if (error)
+ } else if (!PageError(monitor->back_page)) {
+ /* the page has probably been truncated */
+ error = cachefiles_read_reissue(object, monitor);
+ if (error == -EINPROGRESS)
+ goto next;
+ goto recheck;
+ } else {
cachefiles_io_error_obj(
object,
"Readpage failed on backing file %lx",
(unsigned long) monitor->back_page->flags);
+ error = -EIO;
+ }
page_cache_release(monitor->back_page);
@@ -114,6 +201,7 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
fscache_put_retrieval(op);
kfree(monitor);
+ next:
/* let the thread pool have some air occasionally */
max--;
if (max < 0 || need_resched()) {
@@ -333,7 +421,8 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
- op->op.flags = FSCACHE_OP_FAST;
+ op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
+ op->op.flags |= FSCACHE_OP_FAST;
op->op.processor = cachefiles_read_copier;
pagevec_init(&pagevec, 0);
@@ -639,7 +728,8 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
pagevec_init(&pagevec, 0);
- op->op.flags = FSCACHE_OP_FAST;
+ op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
+ op->op.flags |= FSCACHE_OP_FAST;
op->op.processor = cachefiles_read_copier;
INIT_LIST_HEAD(&backpages);
@@ -801,7 +891,8 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
struct cachefiles_cache *cache;
mm_segment_t old_fs;
struct file *file;
- loff_t pos;
+ loff_t pos, eof;
+ size_t len;
void *data;
int ret;
@@ -832,18 +923,33 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
if (IS_ERR(file)) {
ret = PTR_ERR(file);
} else {
+ ima_counts_get(file);
ret = -EIO;
if (file->f_op->write) {
pos = (loff_t) page->index << PAGE_SHIFT;
+
+ /* we mustn't write more data than we have, so we have
+ * to beware of a partial page at EOF */
+ eof = object->fscache.store_limit_l;
+ len = PAGE_SIZE;
+ if (eof & ~PAGE_MASK) {
+ ASSERTCMP(pos, <, eof);
+ if (eof - pos < PAGE_SIZE) {
+ _debug("cut short %llx to %llx",
+ pos, eof);
+ len = eof - pos;
+ ASSERTCMP(pos + len, ==, eof);
+ }
+ }
+
data = kmap(page);
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = file->f_op->write(
- file, (const void __user *) data, PAGE_SIZE,
- &pos);
+ file, (const void __user *) data, len, &pos);
set_fs(old_fs);
kunmap(page);
- if (ret != PAGE_SIZE)
+ if (ret != len)
ret = -EIO;
}
fput(file);
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 145540a316ab..094ea65afc85 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,12 @@
+Version 1.61
+------------
+Fix append problem to Samba servers (files opened with O_APPEND could
+have duplicated data). Fix oops in cifs_lookup. Workaround problem
+mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session.
+Disable use of server inode numbers when server only
+partially supports them (e.g. for one server querying inode numbers on
+FindFirst fails but QPathInfo queries works).
+
Version 1.60
-------------
Fix memory leak in reconnect. Fix oops in DFS mount error path.
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 9a5e4f5f3122..29f1da761bbf 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1037,7 +1037,7 @@ init_cifs(void)
if (rc)
goto out_unregister_key_type;
#endif
- rc = slow_work_register_user();
+ rc = slow_work_register_user(THIS_MODULE);
if (rc)
goto out_unregister_resolver_key;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 6928c24d1d42..5646727e33f5 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -388,4 +388,5 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
const struct nls_table *nls_codepage, int remap_special_chars);
extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
+extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 43003e0bef18..63ea83ff687f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1577,7 +1577,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
out_err:
if (tcp_ses) {
- kfree(tcp_ses->hostname);
+ if (!IS_ERR(tcp_ses->hostname))
+ kfree(tcp_ses->hostname);
if (tcp_ses->ssocket)
sock_release(tcp_ses->ssocket);
kfree(tcp_ses);
@@ -2219,16 +2220,8 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon,
struct cifs_sb_info *cifs_sb, const char *full_path)
{
int rc;
- __u64 inode_num;
FILE_ALL_INFO *pfile_info;
- rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc != -EOPNOTSUPP)
- return rc;
-
pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
if (pfile_info == NULL)
return -ENOMEM;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 627a60a6c1b1..1f42f772865a 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -214,8 +214,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
posix_flags |= SMB_O_EXCL;
if (oflags & O_TRUNC)
posix_flags |= SMB_O_TRUNC;
- if (oflags & O_APPEND)
- posix_flags |= SMB_O_APPEND;
if (oflags & O_SYNC)
posix_flags |= SMB_O_SYNC;
if (oflags & O_DIRECTORY)
@@ -643,9 +641,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
* O_EXCL: optimize away the lookup, but don't hash the dentry. Let
* the VFS handle the create.
*/
- if (nd->flags & LOOKUP_EXCL) {
+ if (nd && (nd->flags & LOOKUP_EXCL)) {
d_instantiate(direntry, NULL);
- return 0;
+ return NULL;
}
/* can not grab the rename sem here since it would
@@ -675,7 +673,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
* reduction in network traffic in the other paths.
*/
if (pTcon->unix_ext) {
- if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
+ if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
(nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
(nd->intent.open.flags & O_CREAT)) {
rc = cifs_posix_open(full_path, &newInode, nd->path.mnt,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 5e2492535daa..cababd8a52df 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -512,13 +512,10 @@ int cifs_get_inode_info(struct inode **pinode,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc1) {
+ if (rc1 || !fattr.cf_uniqueid) {
cFYI(1, ("GetSrvInodeNum rc %d", rc1));
fattr.cf_uniqueid = iunique(sb, ROOT_I);
- /* disable serverino if call not supported */
- if (rc1 == -EINVAL)
- cifs_sb->mnt_cifs_flags &=
- ~CIFS_MOUNT_SERVER_INUM;
+ cifs_autodisable_serverino(cifs_sb);
}
} else {
fattr.cf_uniqueid = iunique(sb, ROOT_I);
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 0241b25ac33f..d27d4ec6579b 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -715,3 +715,17 @@ cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
ctoUCS_out:
return i;
}
+
+void
+cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
+{
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
+ cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
+ cERROR(1, ("Autodisabling the use of server inode numbers on "
+ "%s. This server doesn't seem to support them "
+ "properly. Hardlinks will not be recognized on this "
+ "mount. Consider mounting with the \"noserverino\" "
+ "option to silence this message.",
+ cifs_sb->tcon->treeName));
+ }
+}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 1f098ca71636..f84062f9a985 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -727,11 +727,12 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *)
pfindEntry, cifs_sb);
- /* FIXME: make _to_fattr functions fill this out */
- if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO)
+ if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
fattr.cf_uniqueid = inum;
- else
+ } else {
fattr.cf_uniqueid = iunique(sb, ROOT_I);
+ cifs_autodisable_serverino(cifs_sb);
+ }
ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr);
diff --git a/fs/compat.c b/fs/compat.c
index d576b552e8e2..6c19040ffeef 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1532,6 +1532,8 @@ int compat_do_execve(char * filename,
if (retval < 0)
goto out;
+ current->stack_start = current->mm->start_stack;
+
/* execve succeeded */
current->fs->in_exec = 0;
current->in_execve = 0;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index f91fd51b32e3..d84e7058c298 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1800,7 +1800,7 @@ struct space_resv_32 {
/* just account for different alignment */
static int compat_ioctl_preallocate(struct file *file, unsigned long arg)
{
- struct space_resv_32 __user *p32 = (void __user *)arg;
+ struct space_resv_32 __user *p32 = compat_ptr(arg);
struct space_resv __user *p = compat_alloc_user_space(sizeof(*p));
if (copy_in_user(&p->l_type, &p32->l_type, sizeof(s16)) ||
@@ -2802,7 +2802,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
#else
case FS_IOC_RESVSP:
case FS_IOC_RESVSP64:
- error = ioctl_preallocate(filp, (void __user *)arg);
+ error = ioctl_preallocate(filp, compat_ptr(arg));
goto out_fput;
#endif
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 240cef14fe58..70736eb4b516 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -316,6 +316,10 @@ int dlm_lowcomms_connect_node(int nodeid)
{
struct connection *con;
+ /* with sctp there's no connecting without sending */
+ if (dlm_config.ci_protocol != 0)
+ return 0;
+
if (nodeid == dlm_our_nodeid())
return 0;
@@ -455,9 +459,9 @@ static void process_sctp_notification(struct connection *con,
int prim_len, ret;
int addr_len;
struct connection *new_con;
- struct file *file;
sctp_peeloff_arg_t parg;
int parglen = sizeof(parg);
+ int err;
/*
* We get this before any data for an association.
@@ -512,19 +516,22 @@ static void process_sctp_notification(struct connection *con,
ret = kernel_getsockopt(con->sock, IPPROTO_SCTP,
SCTP_SOCKOPT_PEELOFF,
(void *)&parg, &parglen);
- if (ret) {
+ if (ret < 0) {
log_print("Can't peel off a socket for "
- "connection %d to node %d: err=%d\n",
+ "connection %d to node %d: err=%d",
parg.associd, nodeid, ret);
+ return;
+ }
+ new_con->sock = sockfd_lookup(parg.sd, &err);
+ if (!new_con->sock) {
+ log_print("sockfd_lookup error %d", err);
+ return;
}
- file = fget(parg.sd);
- new_con->sock = SOCKET_I(file->f_dentry->d_inode);
add_sock(new_con->sock, new_con);
- fput(file);
- put_unused_fd(parg.sd);
+ sockfd_put(new_con->sock);
- log_print("got new/restarted association %d nodeid %d",
- (int)sn->sn_assoc_change.sac_assoc_id, nodeid);
+ log_print("connecting to %d sctp association %d",
+ nodeid, (int)sn->sn_assoc_change.sac_assoc_id);
/* Send any pending writes */
clear_bit(CF_CONNECT_PENDING, &new_con->flags);
@@ -837,8 +844,6 @@ static void sctp_init_assoc(struct connection *con)
if (con->retries++ > MAX_CONNECT_RETRIES)
return;
- log_print("Initiating association with node %d", con->nodeid);
-
if (nodeid_to_addr(con->nodeid, (struct sockaddr *)&rem_addr)) {
log_print("no address for nodeid %d", con->nodeid);
return;
@@ -855,11 +860,14 @@ static void sctp_init_assoc(struct connection *con)
outmessage.msg_flags = MSG_EOR;
spin_lock(&con->writequeue_lock);
- e = list_entry(con->writequeue.next, struct writequeue_entry,
- list);
- BUG_ON((struct list_head *) e == &con->writequeue);
+ if (list_empty(&con->writequeue)) {
+ spin_unlock(&con->writequeue_lock);
+ log_print("writequeue empty for nodeid %d", con->nodeid);
+ return;
+ }
+ e = list_first_entry(&con->writequeue, struct writequeue_entry, list);
len = e->len;
offset = e->offset;
spin_unlock(&con->writequeue_lock);
diff --git a/fs/exec.c b/fs/exec.c
index d49be6bc1793..c0c636e34f60 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -46,7 +46,6 @@
#include <linux/proc_fs.h>
#include <linux/mount.h>
#include <linux/security.h>
-#include <linux/ima.h>
#include <linux/syscalls.h>
#include <linux/tsacct_kern.h>
#include <linux/cn_proc.h>
@@ -624,10 +623,8 @@ int setup_arg_pages(struct linux_binprm *bprm,
/* Move stack pages down in memory. */
if (stack_shift) {
ret = shift_arg_pages(vma, stack_shift);
- if (ret) {
- up_write(&mm->mmap_sem);
- return ret;
- }
+ if (ret)
+ goto out_unlock;
}
#ifdef CONFIG_STACK_GROWSUP
@@ -641,7 +638,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
out_unlock:
up_write(&mm->mmap_sem);
- return 0;
+ return ret;
}
EXPORT_SYMBOL(setup_arg_pages);
@@ -1211,9 +1208,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
retval = security_bprm_check(bprm);
if (retval)
return retval;
- retval = ima_bprm_check(bprm);
- if (retval)
- return retval;
/* kernel module loader fixup */
/* so we don't try to load run modprobe in kernel space. */
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c
index 451d166bbe93..8209f266e9ad 100644
--- a/fs/ext3/fsync.c
+++ b/fs/ext3/fsync.c
@@ -46,19 +46,21 @@
int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
{
struct inode *inode = dentry->d_inode;
+ struct ext3_inode_info *ei = EXT3_I(inode);
+ journal_t *journal = EXT3_SB(inode->i_sb)->s_journal;
int ret = 0;
+ tid_t commit_tid;
+
+ if (inode->i_sb->s_flags & MS_RDONLY)
+ return 0;
J_ASSERT(ext3_journal_current_handle() == NULL);
/*
- * data=writeback:
+ * data=writeback,ordered:
* The caller's filemap_fdatawrite()/wait will sync the data.
- * sync_inode() will sync the metadata
- *
- * data=ordered:
- * The caller's filemap_fdatawrite() will write the data and
- * sync_inode() will write the inode if it is dirty. Then the caller's
- * filemap_fdatawait() will wait on the pages.
+ * Metadata is in the journal, we wait for a proper transaction
+ * to commit here.
*
* data=journal:
* filemap_fdatawrite won't do anything (the buffers are clean).
@@ -73,22 +75,16 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
goto out;
}
- if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
- goto flush;
+ if (datasync)
+ commit_tid = atomic_read(&ei->i_datasync_tid);
+ else
+ commit_tid = atomic_read(&ei->i_sync_tid);
- /*
- * The VFS has written the file data. If the inode is unaltered
- * then we need not start a commit.
- */
- if (inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC)) {
- struct writeback_control wbc = {
- .sync_mode = WB_SYNC_ALL,
- .nr_to_write = 0, /* sys_fsync did this */
- };
- ret = sync_inode(inode, &wbc);
+ if (log_start_commit(journal, commit_tid)) {
+ log_wait_commit(journal, commit_tid);
goto out;
}
-flush:
+
/*
* In case we didn't commit a transaction, we have to flush
* disk caches manually so that data really is on persistent
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index acf1b1423327..354ed3b47b30 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -699,8 +699,9 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode,
int err = 0;
struct ext3_block_alloc_info *block_i;
ext3_fsblk_t current_block;
+ struct ext3_inode_info *ei = EXT3_I(inode);
- block_i = EXT3_I(inode)->i_block_alloc_info;
+ block_i = ei->i_block_alloc_info;
/*
* If we're splicing into a [td]indirect block (as opposed to the
* inode) then we need to get write access to the [td]indirect block
@@ -741,6 +742,8 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode,
inode->i_ctime = CURRENT_TIME_SEC;
ext3_mark_inode_dirty(handle, inode);
+ /* ext3_mark_inode_dirty already updated i_sync_tid */
+ atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid);
/* had we spliced it onto indirect block? */
if (where->bh) {
@@ -1735,6 +1738,7 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb,
ssize_t ret;
int orphan = 0;
size_t count = iov_length(iov, nr_segs);
+ int retries = 0;
if (rw == WRITE) {
loff_t final_size = offset + count;
@@ -1757,9 +1761,12 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb,
}
}
+retry:
ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs,
ext3_get_block, NULL);
+ if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
+ goto retry;
if (orphan) {
int err;
@@ -2750,6 +2757,8 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
struct ext3_inode_info *ei;
struct buffer_head *bh;
struct inode *inode;
+ journal_t *journal = EXT3_SB(sb)->s_journal;
+ transaction_t *transaction;
long ret;
int block;
@@ -2827,6 +2836,30 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
ei->i_data[block] = raw_inode->i_block[block];
INIT_LIST_HEAD(&ei->i_orphan);
+ /*
+ * Set transaction id's of transactions that have to be committed
+ * to finish f[data]sync. We set them to currently running transaction
+ * as we cannot be sure that the inode or some of its metadata isn't
+ * part of the transaction - the inode could have been reclaimed and
+ * now it is reread from disk.
+ */
+ if (journal) {
+ tid_t tid;
+
+ spin_lock(&journal->j_state_lock);
+ if (journal->j_running_transaction)
+ transaction = journal->j_running_transaction;
+ else
+ transaction = journal->j_committing_transaction;
+ if (transaction)
+ tid = transaction->t_tid;
+ else
+ tid = journal->j_commit_sequence;
+ spin_unlock(&journal->j_state_lock);
+ atomic_set(&ei->i_sync_tid, tid);
+ atomic_set(&ei->i_datasync_tid, tid);
+ }
+
if (inode->i_ino >= EXT3_FIRST_INO(inode->i_sb) + 1 &&
EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) {
/*
@@ -3011,6 +3044,7 @@ again:
err = rc;
ei->i_state &= ~EXT3_STATE_NEW;
+ atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid);
out_brelse:
brelse (bh);
ext3_std_error(inode->i_sb, err);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 7a520a862f49..427496c4767c 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -466,6 +466,8 @@ static struct inode *ext3_alloc_inode(struct super_block *sb)
return NULL;
ei->i_block_alloc_info = NULL;
ei->vfs_inode.i_version = 1;
+ atomic_set(&ei->i_datasync_tid, 0);
+ atomic_set(&ei->i_sync_tid, 0);
return &ei->vfs_inode;
}
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 984ca0cb38c3..8825515eeddd 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -322,6 +322,7 @@ static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags)
#define EXT4_STATE_NO_EXPAND 0x00000008 /* No space for expansion */
#define EXT4_STATE_DA_ALLOC_CLOSE 0x00000010 /* Alloc DA blks on close */
#define EXT4_STATE_EXT_MIGRATE 0x00000020 /* Inode is migrating */
+#define EXT4_STATE_DIO_UNWRITTEN 0x00000040 /* need convert on dio done*/
/* Used to pass group descriptor data when online resize is done */
struct ext4_new_group_input {
@@ -743,6 +744,7 @@ struct ext4_inode_info {
#define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
#define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
#define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
+#define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
#define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
#define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */
#define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 10539e364283..715264b4bae4 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2807,6 +2807,8 @@ fix_extent_len:
* into three uninitialized extent(at most). After IO complete, the part
* being filled will be convert to initialized by the end_io callback function
* via ext4_convert_unwritten_extents().
+ *
+ * Returns the size of uninitialized extent to be written on success.
*/
static int ext4_split_unwritten_extents(handle_t *handle,
struct inode *inode,
@@ -2824,7 +2826,6 @@ static int ext4_split_unwritten_extents(handle_t *handle,
unsigned int allocated, ee_len, depth;
ext4_fsblk_t newblock;
int err = 0;
- int ret = 0;
ext_debug("ext4_split_unwritten_extents: inode %lu,"
"iblock %llu, max_blocks %u\n", inode->i_ino,
@@ -2842,12 +2843,12 @@ static int ext4_split_unwritten_extents(handle_t *handle,
ext4_ext_store_pblock(&orig_ex, ext_pblock(ex));
/*
- * if the entire unintialized extent length less than
- * the size of extent to write, there is no need to split
- * uninitialized extent
+ * If the uninitialized extent begins at the same logical
+ * block where the write begins, and the write completely
+ * covers the extent, then we don't need to split it.
*/
- if (allocated <= max_blocks)
- return ret;
+ if ((iblock == ee_block) && (allocated <= max_blocks))
+ return allocated;
err = ext4_ext_get_access(handle, inode, path + depth);
if (err)
@@ -3048,12 +3049,18 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
ret = ext4_split_unwritten_extents(handle,
inode, path, iblock,
max_blocks, flags);
- /* flag the io_end struct that we need convert when IO done */
+ /*
+ * Flag the inode(non aio case) or end_io struct (aio case)
+ * that this IO needs to convertion to written when IO is
+ * completed
+ */
if (io)
io->flag = DIO_AIO_UNWRITTEN;
+ else
+ EXT4_I(inode)->i_state |= EXT4_STATE_DIO_UNWRITTEN;
goto out;
}
- /* DIO end_io complete, convert the filled extent to written */
+ /* async DIO end_io complete, convert the filled extent to written */
if (flags == EXT4_GET_BLOCKS_DIO_CONVERT_EXT) {
ret = ext4_convert_unwritten_extents_dio(handle, inode,
path);
@@ -3295,10 +3302,16 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
* To avoid unecessary convertion for every aio dio rewrite
* to the mid of file, here we flag the IO that is really
* need the convertion.
- *
+ * For non asycn direct IO case, flag the inode state
+ * that we need to perform convertion when IO is done.
*/
- if (io && flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT)
- io->flag = DIO_AIO_UNWRITTEN;
+ if (flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT) {
+ if (io)
+ io->flag = DIO_AIO_UNWRITTEN;
+ else
+ EXT4_I(inode)->i_state |=
+ EXT4_STATE_DIO_UNWRITTEN;;
+ }
}
err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
if (err) {
@@ -3519,6 +3532,7 @@ retry:
*
* This function is called from the direct IO end io call back
* function, to convert the fallocated extents after IO is completed.
+ * Returns 0 on success.
*/
int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
loff_t len)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5c5bc5dafff8..2c8caa51addb 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -193,7 +193,7 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
* so before we call here everything must be consistently dirtied against
* this transaction.
*/
- int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode,
+int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode,
int nblocks)
{
int ret;
@@ -209,6 +209,7 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
up_write(&EXT4_I(inode)->i_data_sem);
ret = ext4_journal_restart(handle, blocks_for_truncate(inode));
down_write(&EXT4_I(inode)->i_data_sem);
+ ext4_discard_preallocations(inode);
return ret;
}
@@ -3445,8 +3446,6 @@ out:
return ret;
}
-/* Maximum number of blocks we map for direct IO at once. */
-
static int ext4_get_block_dio_write(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
@@ -3654,13 +3653,14 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
ext4_io_end_t *io_end = iocb->private;
struct workqueue_struct *wq;
+ /* if not async direct IO or dio with 0 bytes write, just return */
+ if (!io_end || !size)
+ return;
+
ext_debug("ext4_end_io_dio(): io_end 0x%p"
"for inode %lu, iocb 0x%p, offset %llu, size %llu\n",
iocb->private, io_end->inode->i_ino, iocb, offset,
size);
- /* if not async direct IO or dio with 0 bytes write, just return */
- if (!io_end || !size)
- return;
/* if not aio dio with unwritten extents, just free io and return */
if (io_end->flag != DIO_AIO_UNWRITTEN){
@@ -3771,13 +3771,19 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
if (ret != -EIOCBQUEUED && ret <= 0 && iocb->private) {
ext4_free_io_end(iocb->private);
iocb->private = NULL;
- } else if (ret > 0)
+ } else if (ret > 0 && (EXT4_I(inode)->i_state &
+ EXT4_STATE_DIO_UNWRITTEN)) {
+ int err;
/*
* for non AIO case, since the IO is already
* completed, we could do the convertion right here
*/
- ret = ext4_convert_unwritten_extents(inode,
- offset, ret);
+ err = ext4_convert_unwritten_extents(inode,
+ offset, ret);
+ if (err < 0)
+ ret = err;
+ EXT4_I(inode)->i_state &= ~EXT4_STATE_DIO_UNWRITTEN;
+ }
return ret;
}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 7c8fe80bacdd..6d2c1b897fc7 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1518,12 +1518,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
return retval;
if (blocks == 1 && !dx_fallback &&
- EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
- retval = make_indexed_dir(handle, dentry, inode, bh);
- if (retval == -ENOSPC)
- brelse(bh);
- return retval;
- }
+ EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
+ return make_indexed_dir(handle, dentry, inode, bh);
brelse(bh);
}
bh = ext4_append(handle, dir, &block, &retval);
@@ -1532,10 +1528,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
de = (struct ext4_dir_entry_2 *) bh->b_data;
de->inode = 0;
de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize);
- retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
- if (retval == -ENOSPC)
- brelse(bh);
- return retval;
+ return add_dirent_to_buf(handle, dentry, inode, de, bh);
}
/*
@@ -1664,8 +1657,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
if (!de)
goto cleanup;
err = add_dirent_to_buf(handle, dentry, inode, de, bh);
- if (err != -ENOSPC)
- bh = NULL;
+ bh = NULL;
goto cleanup;
journal_error:
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 312211ee05af..d4ca92aab514 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1300,9 +1300,11 @@ static int parse_options(char *options, struct super_block *sb,
*journal_devnum = option;
break;
case Opt_journal_checksum:
- break; /* Kept for backwards compatibility */
+ set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
+ break;
case Opt_journal_async_commit:
set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT);
+ set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
break;
case Opt_noload:
set_opt(sbi->s_mount_opt, NOLOAD);
@@ -2759,14 +2761,20 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount4;
}
- jbd2_journal_set_features(sbi->s_journal,
- JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0);
- if (test_opt(sb, JOURNAL_ASYNC_COMMIT))
- jbd2_journal_set_features(sbi->s_journal, 0, 0,
+ if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
+ jbd2_journal_set_features(sbi->s_journal,
+ JBD2_FEATURE_COMPAT_CHECKSUM, 0,
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
- else
+ } else if (test_opt(sb, JOURNAL_CHECKSUM)) {
+ jbd2_journal_set_features(sbi->s_journal,
+ JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0);
jbd2_journal_clear_features(sbi->s_journal, 0, 0,
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
+ } else {
+ jbd2_journal_clear_features(sbi->s_journal,
+ JBD2_FEATURE_COMPAT_CHECKSUM, 0,
+ JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
+ }
/* We have now updated the journal if required, so we can
* validate the data journaling mode. */
diff --git a/fs/fcntl.c b/fs/fcntl.c
index fc089f2f7f56..2cf93ec40a67 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -284,7 +284,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
type = PIDTYPE_PID;
break;
- case F_OWNER_GID:
+ case F_OWNER_PGRP:
type = PIDTYPE_PGID;
break;
@@ -321,7 +321,7 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
break;
case PIDTYPE_PGID:
- owner.type = F_OWNER_GID;
+ owner.type = F_OWNER_PGRP;
break;
default:
diff --git a/fs/file_table.c b/fs/file_table.c
index 8eb44042e009..4bef4c01ec6f 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/security.h>
-#include <linux/ima.h>
#include <linux/eventpoll.h>
#include <linux/rcupdate.h>
#include <linux/mount.h>
@@ -280,7 +279,6 @@ void __fput(struct file *file)
if (file->f_op && file->f_op->release)
file->f_op->release(inode, file);
security_file_free(file);
- ima_file_free(file);
if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL))
cdev_put(inode->i_cdev);
fops_put(file->f_op);
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig
index 9bbb8ce7bea0..864dac20a242 100644
--- a/fs/fscache/Kconfig
+++ b/fs/fscache/Kconfig
@@ -54,3 +54,10 @@ config FSCACHE_DEBUG
enabled by setting bits in /sys/modules/fscache/parameter/debug.
See Documentation/filesystems/caching/fscache.txt for more information.
+
+config FSCACHE_OBJECT_LIST
+ bool "Maintain global object list for debugging purposes"
+ depends on FSCACHE && PROC_FS
+ help
+ Maintain a global list of active fscache objects that can be
+ retrieved through /proc/fs/fscache/objects for debugging purposes
diff --git a/fs/fscache/Makefile b/fs/fscache/Makefile
index 91571b95aacc..6d561531cb36 100644
--- a/fs/fscache/Makefile
+++ b/fs/fscache/Makefile
@@ -15,5 +15,6 @@ fscache-y := \
fscache-$(CONFIG_PROC_FS) += proc.o
fscache-$(CONFIG_FSCACHE_STATS) += stats.o
fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o
+fscache-$(CONFIG_FSCACHE_OBJECT_LIST) += object-list.o
obj-$(CONFIG_FSCACHE) := fscache.o
diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c
index e21985bbb1fb..6a3c48abd677 100644
--- a/fs/fscache/cache.c
+++ b/fs/fscache/cache.c
@@ -263,6 +263,7 @@ int fscache_add_cache(struct fscache_cache *cache,
spin_lock(&cache->object_list_lock);
list_add_tail(&ifsdef->cache_link, &cache->object_list);
spin_unlock(&cache->object_list_lock);
+ fscache_objlist_add(ifsdef);
/* add the cache's netfs definition index object to the top level index
* cookie as a known backing object */
@@ -380,11 +381,15 @@ void fscache_withdraw_cache(struct fscache_cache *cache)
/* make sure all pages pinned by operations on behalf of the netfs are
* written to disk */
+ fscache_stat(&fscache_n_cop_sync_cache);
cache->ops->sync_cache(cache);
+ fscache_stat_d(&fscache_n_cop_sync_cache);
/* dissociate all the netfs pages backed by this cache from the block
* mappings in the cache */
+ fscache_stat(&fscache_n_cop_dissociate_pages);
cache->ops->dissociate_pages(cache);
+ fscache_stat_d(&fscache_n_cop_dissociate_pages);
/* we now have to destroy all the active objects pertaining to this
* cache - which we do by passing them off to thread pool to be
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index 72fd18f6c71f..990535071a8a 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -36,6 +36,7 @@ void fscache_cookie_init_once(void *_cookie)
memset(cookie, 0, sizeof(*cookie));
spin_lock_init(&cookie->lock);
+ spin_lock_init(&cookie->stores_lock);
INIT_HLIST_HEAD(&cookie->backing_objects);
}
@@ -102,7 +103,9 @@ struct fscache_cookie *__fscache_acquire_cookie(
cookie->netfs_data = netfs_data;
cookie->flags = 0;
- INIT_RADIX_TREE(&cookie->stores, GFP_NOFS);
+ /* radix tree insertion won't use the preallocation pool unless it's
+ * told it may not wait */
+ INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_WAIT);
switch (cookie->def->type) {
case FSCACHE_COOKIE_TYPE_INDEX:
@@ -249,7 +252,9 @@ static int fscache_alloc_object(struct fscache_cache *cache,
/* ask the cache to allocate an object (we may end up with duplicate
* objects at this stage, but we sort that out later) */
+ fscache_stat(&fscache_n_cop_alloc_object);
object = cache->ops->alloc_object(cache, cookie);
+ fscache_stat_d(&fscache_n_cop_alloc_object);
if (IS_ERR(object)) {
fscache_stat(&fscache_n_object_no_alloc);
ret = PTR_ERR(object);
@@ -270,8 +275,11 @@ static int fscache_alloc_object(struct fscache_cache *cache,
/* only attach if we managed to allocate all we needed, otherwise
* discard the object we just allocated and instead use the one
* attached to the cookie */
- if (fscache_attach_object(cookie, object) < 0)
+ if (fscache_attach_object(cookie, object) < 0) {
+ fscache_stat(&fscache_n_cop_put_object);
cache->ops->put_object(object);
+ fscache_stat_d(&fscache_n_cop_put_object);
+ }
_leave(" = 0");
return 0;
@@ -287,7 +295,9 @@ object_already_extant:
return 0;
error_put:
+ fscache_stat(&fscache_n_cop_put_object);
cache->ops->put_object(object);
+ fscache_stat_d(&fscache_n_cop_put_object);
error:
_leave(" = %d", ret);
return ret;
@@ -349,6 +359,8 @@ static int fscache_attach_object(struct fscache_cookie *cookie,
object->cookie = cookie;
atomic_inc(&cookie->usage);
hlist_add_head(&object->cookie_link, &cookie->backing_objects);
+
+ fscache_objlist_add(object);
ret = 0;
cant_attach_object:
@@ -403,6 +415,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
unsigned long event;
fscache_stat(&fscache_n_relinquishes);
+ if (retire)
+ fscache_stat(&fscache_n_relinquishes_retire);
if (!cookie) {
fscache_stat(&fscache_n_relinquishes_null);
@@ -428,12 +442,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
- /* detach pointers back to the netfs */
spin_lock(&cookie->lock);
- cookie->netfs_data = NULL;
- cookie->def = NULL;
-
/* break links with all the active objects */
while (!hlist_empty(&cookie->backing_objects)) {
object = hlist_entry(cookie->backing_objects.first,
@@ -456,6 +466,10 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
BUG();
}
+ /* detach pointers back to the netfs */
+ cookie->netfs_data = NULL;
+ cookie->def = NULL;
+
spin_unlock(&cookie->lock);
if (cookie->parent) {
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index 1c341304621f..edd7434ab6e5 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -17,6 +17,7 @@
* - cache->object_list_lock
* - object->lock
* - object->parent->lock
+ * - cookie->stores_lock
* - fscache_thread_lock
*
*/
@@ -88,17 +89,31 @@ extern int fscache_wait_bit_interruptible(void *);
/*
* object.c
*/
+extern const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5];
+
extern void fscache_withdrawing_object(struct fscache_cache *,
struct fscache_object *);
extern void fscache_enqueue_object(struct fscache_object *);
/*
+ * object-list.c
+ */
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+extern const struct file_operations fscache_objlist_fops;
+
+extern void fscache_objlist_add(struct fscache_object *);
+#else
+#define fscache_objlist_add(object) do {} while(0)
+#endif
+
+/*
* operation.c
*/
extern int fscache_submit_exclusive_op(struct fscache_object *,
struct fscache_operation *);
extern int fscache_submit_op(struct fscache_object *,
struct fscache_operation *);
+extern int fscache_cancel_op(struct fscache_operation *);
extern void fscache_abort_object(struct fscache_object *);
extern void fscache_start_operations(struct fscache_object *);
extern void fscache_operation_gc(struct work_struct *);
@@ -127,6 +142,8 @@ extern atomic_t fscache_n_op_enqueue;
extern atomic_t fscache_n_op_deferred_release;
extern atomic_t fscache_n_op_release;
extern atomic_t fscache_n_op_gc;
+extern atomic_t fscache_n_op_cancelled;
+extern atomic_t fscache_n_op_rejected;
extern atomic_t fscache_n_attr_changed;
extern atomic_t fscache_n_attr_changed_ok;
@@ -138,6 +155,8 @@ extern atomic_t fscache_n_allocs;
extern atomic_t fscache_n_allocs_ok;
extern atomic_t fscache_n_allocs_wait;
extern atomic_t fscache_n_allocs_nobufs;
+extern atomic_t fscache_n_allocs_intr;
+extern atomic_t fscache_n_allocs_object_dead;
extern atomic_t fscache_n_alloc_ops;
extern atomic_t fscache_n_alloc_op_waits;
@@ -148,6 +167,7 @@ extern atomic_t fscache_n_retrievals_nodata;
extern atomic_t fscache_n_retrievals_nobufs;
extern atomic_t fscache_n_retrievals_intr;
extern atomic_t fscache_n_retrievals_nomem;
+extern atomic_t fscache_n_retrievals_object_dead;
extern atomic_t fscache_n_retrieval_ops;
extern atomic_t fscache_n_retrieval_op_waits;
@@ -158,6 +178,14 @@ extern atomic_t fscache_n_stores_nobufs;
extern atomic_t fscache_n_stores_oom;
extern atomic_t fscache_n_store_ops;
extern atomic_t fscache_n_store_calls;
+extern atomic_t fscache_n_store_pages;
+extern atomic_t fscache_n_store_radix_deletes;
+extern atomic_t fscache_n_store_pages_over_limit;
+
+extern atomic_t fscache_n_store_vmscan_not_storing;
+extern atomic_t fscache_n_store_vmscan_gone;
+extern atomic_t fscache_n_store_vmscan_busy;
+extern atomic_t fscache_n_store_vmscan_cancelled;
extern atomic_t fscache_n_marks;
extern atomic_t fscache_n_uncaches;
@@ -176,6 +204,7 @@ extern atomic_t fscache_n_updates_run;
extern atomic_t fscache_n_relinquishes;
extern atomic_t fscache_n_relinquishes_null;
extern atomic_t fscache_n_relinquishes_waitcrt;
+extern atomic_t fscache_n_relinquishes_retire;
extern atomic_t fscache_n_cookie_index;
extern atomic_t fscache_n_cookie_data;
@@ -186,6 +215,7 @@ extern atomic_t fscache_n_object_no_alloc;
extern atomic_t fscache_n_object_lookups;
extern atomic_t fscache_n_object_lookups_negative;
extern atomic_t fscache_n_object_lookups_positive;
+extern atomic_t fscache_n_object_lookups_timed_out;
extern atomic_t fscache_n_object_created;
extern atomic_t fscache_n_object_avail;
extern atomic_t fscache_n_object_dead;
@@ -195,15 +225,41 @@ extern atomic_t fscache_n_checkaux_okay;
extern atomic_t fscache_n_checkaux_update;
extern atomic_t fscache_n_checkaux_obsolete;
+extern atomic_t fscache_n_cop_alloc_object;
+extern atomic_t fscache_n_cop_lookup_object;
+extern atomic_t fscache_n_cop_lookup_complete;
+extern atomic_t fscache_n_cop_grab_object;
+extern atomic_t fscache_n_cop_update_object;
+extern atomic_t fscache_n_cop_drop_object;
+extern atomic_t fscache_n_cop_put_object;
+extern atomic_t fscache_n_cop_sync_cache;
+extern atomic_t fscache_n_cop_attr_changed;
+extern atomic_t fscache_n_cop_read_or_alloc_page;
+extern atomic_t fscache_n_cop_read_or_alloc_pages;
+extern atomic_t fscache_n_cop_allocate_page;
+extern atomic_t fscache_n_cop_allocate_pages;
+extern atomic_t fscache_n_cop_write_page;
+extern atomic_t fscache_n_cop_uncache_page;
+extern atomic_t fscache_n_cop_dissociate_pages;
+
static inline void fscache_stat(atomic_t *stat)
{
atomic_inc(stat);
}
+static inline void fscache_stat_d(atomic_t *stat)
+{
+ atomic_dec(stat);
+}
+
+#define __fscache_stat(stat) (stat)
+
extern const struct file_operations fscache_stats_fops;
#else
+#define __fscache_stat(stat) (NULL)
#define fscache_stat(stat) do {} while (0)
+#define fscache_stat_d(stat) do {} while (0)
#endif
/*
diff --git a/fs/fscache/main.c b/fs/fscache/main.c
index 4de41b597499..add6bdb53f04 100644
--- a/fs/fscache/main.c
+++ b/fs/fscache/main.c
@@ -48,7 +48,7 @@ static int __init fscache_init(void)
{
int ret;
- ret = slow_work_register_user();
+ ret = slow_work_register_user(THIS_MODULE);
if (ret < 0)
goto error_slow_work;
@@ -80,7 +80,7 @@ error_kobj:
error_cookie_jar:
fscache_proc_cleanup();
error_proc:
- slow_work_unregister_user();
+ slow_work_unregister_user(THIS_MODULE);
error_slow_work:
return ret;
}
@@ -97,7 +97,7 @@ static void __exit fscache_exit(void)
kobject_put(fscache_root);
kmem_cache_destroy(fscache_cookie_jar);
fscache_proc_cleanup();
- slow_work_unregister_user();
+ slow_work_unregister_user(THIS_MODULE);
printk(KERN_NOTICE "FS-Cache: Unloaded\n");
}
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
new file mode 100644
index 000000000000..e590242fa41a
--- /dev/null
+++ b/fs/fscache/object-list.c
@@ -0,0 +1,432 @@
+/* Global fscache object list maintainer and viewer
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL COOKIE
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/key.h>
+#include <keys/user-type.h>
+#include "internal.h"
+
+static struct rb_root fscache_object_list;
+static DEFINE_RWLOCK(fscache_object_list_lock);
+
+struct fscache_objlist_data {
+ unsigned long config; /* display configuration */
+#define FSCACHE_OBJLIST_CONFIG_KEY 0x00000001 /* show object keys */
+#define FSCACHE_OBJLIST_CONFIG_AUX 0x00000002 /* show object auxdata */
+#define FSCACHE_OBJLIST_CONFIG_COOKIE 0x00000004 /* show objects with cookies */
+#define FSCACHE_OBJLIST_CONFIG_NOCOOKIE 0x00000008 /* show objects without cookies */
+#define FSCACHE_OBJLIST_CONFIG_BUSY 0x00000010 /* show busy objects */
+#define FSCACHE_OBJLIST_CONFIG_IDLE 0x00000020 /* show idle objects */
+#define FSCACHE_OBJLIST_CONFIG_PENDWR 0x00000040 /* show objects with pending writes */
+#define FSCACHE_OBJLIST_CONFIG_NOPENDWR 0x00000080 /* show objects without pending writes */
+#define FSCACHE_OBJLIST_CONFIG_READS 0x00000100 /* show objects with active reads */
+#define FSCACHE_OBJLIST_CONFIG_NOREADS 0x00000200 /* show objects without active reads */
+#define FSCACHE_OBJLIST_CONFIG_EVENTS 0x00000400 /* show objects with events */
+#define FSCACHE_OBJLIST_CONFIG_NOEVENTS 0x00000800 /* show objects without no events */
+#define FSCACHE_OBJLIST_CONFIG_WORK 0x00001000 /* show objects with slow work */
+#define FSCACHE_OBJLIST_CONFIG_NOWORK 0x00002000 /* show objects without slow work */
+
+ u8 buf[512]; /* key and aux data buffer */
+};
+
+/*
+ * Add an object to the object list
+ * - we use the address of the fscache_object structure as the key into the
+ * tree
+ */
+void fscache_objlist_add(struct fscache_object *obj)
+{
+ struct fscache_object *xobj;
+ struct rb_node **p = &fscache_object_list.rb_node, *parent = NULL;
+
+ write_lock(&fscache_object_list_lock);
+
+ while (*p) {
+ parent = *p;
+ xobj = rb_entry(parent, struct fscache_object, objlist_link);
+
+ if (obj < xobj)
+ p = &(*p)->rb_left;
+ else if (obj > xobj)
+ p = &(*p)->rb_right;
+ else
+ BUG();
+ }
+
+ rb_link_node(&obj->objlist_link, parent, p);
+ rb_insert_color(&obj->objlist_link, &fscache_object_list);
+
+ write_unlock(&fscache_object_list_lock);
+}
+
+/**
+ * fscache_object_destroy - Note that a cache object is about to be destroyed
+ * @object: The object to be destroyed
+ *
+ * Note the imminent destruction and deallocation of a cache object record.
+ */
+void fscache_object_destroy(struct fscache_object *obj)
+{
+ write_lock(&fscache_object_list_lock);
+
+ BUG_ON(RB_EMPTY_ROOT(&fscache_object_list));
+ rb_erase(&obj->objlist_link, &fscache_object_list);
+
+ write_unlock(&fscache_object_list_lock);
+}
+EXPORT_SYMBOL(fscache_object_destroy);
+
+/*
+ * find the object in the tree on or after the specified index
+ */
+static struct fscache_object *fscache_objlist_lookup(loff_t *_pos)
+{
+ struct fscache_object *pobj, *obj, *minobj = NULL;
+ struct rb_node *p;
+ unsigned long pos;
+
+ if (*_pos >= (unsigned long) ERR_PTR(-ENOENT))
+ return NULL;
+ pos = *_pos;
+
+ /* banners (can't represent line 0 by pos 0 as that would involve
+ * returning a NULL pointer) */
+ if (pos == 0)
+ return (struct fscache_object *) ++(*_pos);
+ if (pos < 3)
+ return (struct fscache_object *)pos;
+
+ pobj = (struct fscache_object *)pos;
+ p = fscache_object_list.rb_node;
+ while (p) {
+ obj = rb_entry(p, struct fscache_object, objlist_link);
+ if (pobj < obj) {
+ if (!minobj || minobj > obj)
+ minobj = obj;
+ p = p->rb_left;
+ } else if (pobj > obj) {
+ p = p->rb_right;
+ } else {
+ minobj = obj;
+ break;
+ }
+ obj = NULL;
+ }
+
+ if (!minobj)
+ *_pos = (unsigned long) ERR_PTR(-ENOENT);
+ else if (minobj != obj)
+ *_pos = (unsigned long) minobj;
+ return minobj;
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *fscache_objlist_start(struct seq_file *m, loff_t *_pos)
+ __acquires(&fscache_object_list_lock)
+{
+ read_lock(&fscache_object_list_lock);
+ return fscache_objlist_lookup(_pos);
+}
+
+/*
+ * move to the next line
+ */
+static void *fscache_objlist_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+ (*_pos)++;
+ return fscache_objlist_lookup(_pos);
+}
+
+/*
+ * clean up after reading
+ */
+static void fscache_objlist_stop(struct seq_file *m, void *v)
+ __releases(&fscache_object_list_lock)
+{
+ read_unlock(&fscache_object_list_lock);
+}
+
+/*
+ * display an object
+ */
+static int fscache_objlist_show(struct seq_file *m, void *v)
+{
+ struct fscache_objlist_data *data = m->private;
+ struct fscache_object *obj = v;
+ unsigned long config = data->config;
+ uint16_t keylen, auxlen;
+ char _type[3], *type;
+ bool no_cookie;
+ u8 *buf = data->buf, *p;
+
+ if ((unsigned long) v == 1) {
+ seq_puts(m, "OBJECT PARENT STAT CHLDN OPS OOP IPR EX READS"
+ " EM EV F S"
+ " | NETFS_COOKIE_DEF TY FL NETFS_DATA");
+ if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
+ FSCACHE_OBJLIST_CONFIG_AUX))
+ seq_puts(m, " ");
+ if (config & FSCACHE_OBJLIST_CONFIG_KEY)
+ seq_puts(m, "OBJECT_KEY");
+ if ((config & (FSCACHE_OBJLIST_CONFIG_KEY |
+ FSCACHE_OBJLIST_CONFIG_AUX)) ==
+ (FSCACHE_OBJLIST_CONFIG_KEY | FSCACHE_OBJLIST_CONFIG_AUX))
+ seq_puts(m, ", ");
+ if (config & FSCACHE_OBJLIST_CONFIG_AUX)
+ seq_puts(m, "AUX_DATA");
+ seq_puts(m, "\n");
+ return 0;
+ }
+
+ if ((unsigned long) v == 2) {
+ seq_puts(m, "======== ======== ==== ===== === === === == ====="
+ " == == = ="
+ " | ================ == == ================");
+ if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
+ FSCACHE_OBJLIST_CONFIG_AUX))
+ seq_puts(m, " ================");
+ seq_puts(m, "\n");
+ return 0;
+ }
+
+ /* filter out any unwanted objects */
+#define FILTER(criterion, _yes, _no) \
+ do { \
+ unsigned long yes = FSCACHE_OBJLIST_CONFIG_##_yes; \
+ unsigned long no = FSCACHE_OBJLIST_CONFIG_##_no; \
+ if (criterion) { \
+ if (!(config & yes)) \
+ return 0; \
+ } else { \
+ if (!(config & no)) \
+ return 0; \
+ } \
+ } while(0)
+
+ if (~config) {
+ FILTER(obj->cookie,
+ COOKIE, NOCOOKIE);
+ FILTER(obj->state != FSCACHE_OBJECT_ACTIVE ||
+ obj->n_ops != 0 ||
+ obj->n_obj_ops != 0 ||
+ obj->flags ||
+ !list_empty(&obj->dependents),
+ BUSY, IDLE);
+ FILTER(test_bit(FSCACHE_OBJECT_PENDING_WRITE, &obj->flags),
+ PENDWR, NOPENDWR);
+ FILTER(atomic_read(&obj->n_reads),
+ READS, NOREADS);
+ FILTER(obj->events & obj->event_mask,
+ EVENTS, NOEVENTS);
+ FILTER(obj->work.flags & ~(1UL << SLOW_WORK_VERY_SLOW),
+ WORK, NOWORK);
+ }
+
+ seq_printf(m,
+ "%8x %8x %s %5u %3u %3u %3u %2u %5u %2lx %2lx %1lx %1lx | ",
+ obj->debug_id,
+ obj->parent ? obj->parent->debug_id : -1,
+ fscache_object_states_short[obj->state],
+ obj->n_children,
+ obj->n_ops,
+ obj->n_obj_ops,
+ obj->n_in_progress,
+ obj->n_exclusive,
+ atomic_read(&obj->n_reads),
+ obj->event_mask & FSCACHE_OBJECT_EVENTS_MASK,
+ obj->events,
+ obj->flags,
+ obj->work.flags);
+
+ no_cookie = true;
+ keylen = auxlen = 0;
+ if (obj->cookie) {
+ spin_lock(&obj->lock);
+ if (obj->cookie) {
+ switch (obj->cookie->def->type) {
+ case 0:
+ type = "IX";
+ break;
+ case 1:
+ type = "DT";
+ break;
+ default:
+ sprintf(_type, "%02u",
+ obj->cookie->def->type);
+ type = _type;
+ break;
+ }
+
+ seq_printf(m, "%-16s %s %2lx %16p",
+ obj->cookie->def->name,
+ type,
+ obj->cookie->flags,
+ obj->cookie->netfs_data);
+
+ if (obj->cookie->def->get_key &&
+ config & FSCACHE_OBJLIST_CONFIG_KEY)
+ keylen = obj->cookie->def->get_key(
+ obj->cookie->netfs_data,
+ buf, 400);
+
+ if (obj->cookie->def->get_aux &&
+ config & FSCACHE_OBJLIST_CONFIG_AUX)
+ auxlen = obj->cookie->def->get_aux(
+ obj->cookie->netfs_data,
+ buf + keylen, 512 - keylen);
+
+ no_cookie = false;
+ }
+ spin_unlock(&obj->lock);
+
+ if (!no_cookie && (keylen > 0 || auxlen > 0)) {
+ seq_printf(m, " ");
+ for (p = buf; keylen > 0; keylen--)
+ seq_printf(m, "%02x", *p++);
+ if (auxlen > 0) {
+ if (config & FSCACHE_OBJLIST_CONFIG_KEY)
+ seq_printf(m, ", ");
+ for (; auxlen > 0; auxlen--)
+ seq_printf(m, "%02x", *p++);
+ }
+ }
+ }
+
+ if (no_cookie)
+ seq_printf(m, "<no_cookie>\n");
+ else
+ seq_printf(m, "\n");
+ return 0;
+}
+
+static const struct seq_operations fscache_objlist_ops = {
+ .start = fscache_objlist_start,
+ .stop = fscache_objlist_stop,
+ .next = fscache_objlist_next,
+ .show = fscache_objlist_show,
+};
+
+/*
+ * get the configuration for filtering the list
+ */
+static void fscache_objlist_config(struct fscache_objlist_data *data)
+{
+#ifdef CONFIG_KEYS
+ struct user_key_payload *confkey;
+ unsigned long config;
+ struct key *key;
+ const char *buf;
+ int len;
+
+ key = request_key(&key_type_user, "fscache:objlist", NULL);
+ if (IS_ERR(key))
+ goto no_config;
+
+ config = 0;
+ rcu_read_lock();
+
+ confkey = key->payload.data;
+ buf = confkey->data;
+
+ for (len = confkey->datalen - 1; len >= 0; len--) {
+ switch (buf[len]) {
+ case 'K': config |= FSCACHE_OBJLIST_CONFIG_KEY; break;
+ case 'A': config |= FSCACHE_OBJLIST_CONFIG_AUX; break;
+ case 'C': config |= FSCACHE_OBJLIST_CONFIG_COOKIE; break;
+ case 'c': config |= FSCACHE_OBJLIST_CONFIG_NOCOOKIE; break;
+ case 'B': config |= FSCACHE_OBJLIST_CONFIG_BUSY; break;
+ case 'b': config |= FSCACHE_OBJLIST_CONFIG_IDLE; break;
+ case 'W': config |= FSCACHE_OBJLIST_CONFIG_PENDWR; break;
+ case 'w': config |= FSCACHE_OBJLIST_CONFIG_NOPENDWR; break;
+ case 'R': config |= FSCACHE_OBJLIST_CONFIG_READS; break;
+ case 'r': config |= FSCACHE_OBJLIST_CONFIG_NOREADS; break;
+ case 'S': config |= FSCACHE_OBJLIST_CONFIG_WORK; break;
+ case 's': config |= FSCACHE_OBJLIST_CONFIG_NOWORK; break;
+ }
+ }
+
+ rcu_read_unlock();
+ key_put(key);
+
+ if (!(config & (FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE)))
+ config |= FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE;
+ if (!(config & (FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE)))
+ config |= FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE;
+ if (!(config & (FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR)))
+ config |= FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR;
+ if (!(config & (FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS)))
+ config |= FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS;
+ if (!(config & (FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS)))
+ config |= FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS;
+ if (!(config & (FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK)))
+ config |= FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK;
+
+ data->config = config;
+ return;
+
+no_config:
+#endif
+ data->config = ULONG_MAX;
+}
+
+/*
+ * open "/proc/fs/fscache/objects" to provide a list of active objects
+ * - can be configured by a user-defined key added to the caller's keyrings
+ */
+static int fscache_objlist_open(struct inode *inode, struct file *file)
+{
+ struct fscache_objlist_data *data;
+ struct seq_file *m;
+ int ret;
+
+ ret = seq_open(file, &fscache_objlist_ops);
+ if (ret < 0)
+ return ret;
+
+ m = file->private_data;
+
+ /* buffer for key extraction */
+ data = kmalloc(sizeof(struct fscache_objlist_data), GFP_KERNEL);
+ if (!data) {
+ seq_release(inode, file);
+ return -ENOMEM;
+ }
+
+ /* get the configuration key */
+ fscache_objlist_config(data);
+
+ m->private = data;
+ return 0;
+}
+
+/*
+ * clean up on close
+ */
+static int fscache_objlist_release(struct inode *inode, struct file *file)
+{
+ struct seq_file *m = file->private_data;
+
+ kfree(m->private);
+ m->private = NULL;
+ return seq_release(inode, file);
+}
+
+const struct file_operations fscache_objlist_fops = {
+ .owner = THIS_MODULE,
+ .open = fscache_objlist_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = fscache_objlist_release,
+};
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index 392a41b1b79d..e513ac599c8e 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
@@ -14,9 +14,10 @@
#define FSCACHE_DEBUG_LEVEL COOKIE
#include <linux/module.h>
+#include <linux/seq_file.h>
#include "internal.h"
-const char *fscache_object_states[] = {
+const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = {
[FSCACHE_OBJECT_INIT] = "OBJECT_INIT",
[FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP",
[FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING",
@@ -33,9 +34,28 @@ const char *fscache_object_states[] = {
};
EXPORT_SYMBOL(fscache_object_states);
+const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = {
+ [FSCACHE_OBJECT_INIT] = "INIT",
+ [FSCACHE_OBJECT_LOOKING_UP] = "LOOK",
+ [FSCACHE_OBJECT_CREATING] = "CRTN",
+ [FSCACHE_OBJECT_AVAILABLE] = "AVBL",
+ [FSCACHE_OBJECT_ACTIVE] = "ACTV",
+ [FSCACHE_OBJECT_UPDATING] = "UPDT",
+ [FSCACHE_OBJECT_DYING] = "DYNG",
+ [FSCACHE_OBJECT_LC_DYING] = "LCDY",
+ [FSCACHE_OBJECT_ABORT_INIT] = "ABTI",
+ [FSCACHE_OBJECT_RELEASING] = "RELS",
+ [FSCACHE_OBJECT_RECYCLING] = "RCYC",
+ [FSCACHE_OBJECT_WITHDRAWING] = "WTHD",
+ [FSCACHE_OBJECT_DEAD] = "DEAD",
+};
+
static void fscache_object_slow_work_put_ref(struct slow_work *);
static int fscache_object_slow_work_get_ref(struct slow_work *);
static void fscache_object_slow_work_execute(struct slow_work *);
+#ifdef CONFIG_SLOW_WORK_PROC
+static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *);
+#endif
static void fscache_initialise_object(struct fscache_object *);
static void fscache_lookup_object(struct fscache_object *);
static void fscache_object_available(struct fscache_object *);
@@ -45,9 +65,13 @@ static void fscache_enqueue_dependents(struct fscache_object *);
static void fscache_dequeue_object(struct fscache_object *);
const struct slow_work_ops fscache_object_slow_work_ops = {
+ .owner = THIS_MODULE,
.get_ref = fscache_object_slow_work_get_ref,
.put_ref = fscache_object_slow_work_put_ref,
.execute = fscache_object_slow_work_execute,
+#ifdef CONFIG_SLOW_WORK_PROC
+ .desc = fscache_object_slow_work_desc,
+#endif
};
EXPORT_SYMBOL(fscache_object_slow_work_ops);
@@ -81,6 +105,7 @@ static inline void fscache_done_parent_op(struct fscache_object *object)
static void fscache_object_state_machine(struct fscache_object *object)
{
enum fscache_object_state new_state;
+ struct fscache_cookie *cookie;
ASSERT(object != NULL);
@@ -120,20 +145,31 @@ static void fscache_object_state_machine(struct fscache_object *object)
case FSCACHE_OBJECT_UPDATING:
clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events);
fscache_stat(&fscache_n_updates_run);
+ fscache_stat(&fscache_n_cop_update_object);
object->cache->ops->update_object(object);
+ fscache_stat_d(&fscache_n_cop_update_object);
goto active_transit;
/* handle an object dying during lookup or creation */
case FSCACHE_OBJECT_LC_DYING:
object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE);
+ fscache_stat(&fscache_n_cop_lookup_complete);
object->cache->ops->lookup_complete(object);
+ fscache_stat_d(&fscache_n_cop_lookup_complete);
spin_lock(&object->lock);
object->state = FSCACHE_OBJECT_DYING;
- if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
- &object->cookie->flags))
- wake_up_bit(&object->cookie->flags,
- FSCACHE_COOKIE_CREATING);
+ cookie = object->cookie;
+ if (cookie) {
+ if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP,
+ &cookie->flags))
+ wake_up_bit(&cookie->flags,
+ FSCACHE_COOKIE_LOOKING_UP);
+ if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
+ &cookie->flags))
+ wake_up_bit(&cookie->flags,
+ FSCACHE_COOKIE_CREATING);
+ }
spin_unlock(&object->lock);
fscache_done_parent_op(object);
@@ -165,6 +201,7 @@ static void fscache_object_state_machine(struct fscache_object *object)
}
spin_unlock(&object->lock);
fscache_enqueue_dependents(object);
+ fscache_start_operations(object);
goto terminal_transit;
/* handle an abort during initialisation */
@@ -316,14 +353,29 @@ static void fscache_object_slow_work_execute(struct slow_work *work)
_enter("{OBJ%x}", object->debug_id);
- clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
-
start = jiffies;
fscache_object_state_machine(object);
fscache_hist(fscache_objs_histogram, start);
if (object->events & object->event_mask)
fscache_enqueue_object(object);
+ clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+}
+
+/*
+ * describe an object for slow-work debugging
+ */
+#ifdef CONFIG_SLOW_WORK_PROC
+static void fscache_object_slow_work_desc(struct slow_work *work,
+ struct seq_file *m)
+{
+ struct fscache_object *object =
+ container_of(work, struct fscache_object, work);
+
+ seq_printf(m, "FSC: OBJ%x: %s",
+ object->debug_id,
+ fscache_object_states_short[object->state]);
}
+#endif
/*
* initialise an object
@@ -376,7 +428,9 @@ static void fscache_initialise_object(struct fscache_object *object)
* binding on to us, so we need to make sure we don't
* add ourself to the list multiple times */
if (list_empty(&object->dep_link)) {
+ fscache_stat(&fscache_n_cop_grab_object);
object->cache->ops->grab_object(object);
+ fscache_stat_d(&fscache_n_cop_grab_object);
list_add(&object->dep_link,
&parent->dependents);
@@ -414,6 +468,7 @@ static void fscache_lookup_object(struct fscache_object *object)
{
struct fscache_cookie *cookie = object->cookie;
struct fscache_object *parent;
+ int ret;
_enter("");
@@ -438,11 +493,20 @@ static void fscache_lookup_object(struct fscache_object *object)
object->cache->tag->name);
fscache_stat(&fscache_n_object_lookups);
- object->cache->ops->lookup_object(object);
+ fscache_stat(&fscache_n_cop_lookup_object);
+ ret = object->cache->ops->lookup_object(object);
+ fscache_stat_d(&fscache_n_cop_lookup_object);
if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events))
set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
+ if (ret == -ETIMEDOUT) {
+ /* probably stuck behind another object, so move this one to
+ * the back of the queue */
+ fscache_stat(&fscache_n_object_lookups_timed_out);
+ set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+ }
+
_leave("");
}
@@ -546,7 +610,8 @@ static void fscache_object_available(struct fscache_object *object)
spin_lock(&object->lock);
- if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
+ if (object->cookie &&
+ test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING);
fscache_done_parent_op(object);
@@ -562,7 +627,9 @@ static void fscache_object_available(struct fscache_object *object)
}
spin_unlock(&object->lock);
+ fscache_stat(&fscache_n_cop_lookup_complete);
object->cache->ops->lookup_complete(object);
+ fscache_stat_d(&fscache_n_cop_lookup_complete);
fscache_enqueue_dependents(object);
fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif);
@@ -581,11 +648,16 @@ static void fscache_drop_object(struct fscache_object *object)
_enter("{OBJ%x,%d}", object->debug_id, object->n_children);
+ ASSERTCMP(object->cookie, ==, NULL);
+ ASSERT(hlist_unhashed(&object->cookie_link));
+
spin_lock(&cache->object_list_lock);
list_del_init(&object->cache_link);
spin_unlock(&cache->object_list_lock);
+ fscache_stat(&fscache_n_cop_drop_object);
cache->ops->drop_object(object);
+ fscache_stat_d(&fscache_n_cop_drop_object);
if (parent) {
_debug("release parent OBJ%x {%d}",
@@ -600,7 +672,9 @@ static void fscache_drop_object(struct fscache_object *object)
}
/* this just shifts the object release to the slow work processor */
+ fscache_stat(&fscache_n_cop_put_object);
object->cache->ops->put_object(object);
+ fscache_stat_d(&fscache_n_cop_put_object);
_leave("");
}
@@ -690,8 +764,12 @@ static int fscache_object_slow_work_get_ref(struct slow_work *work)
{
struct fscache_object *object =
container_of(work, struct fscache_object, work);
+ int ret;
- return object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
+ fscache_stat(&fscache_n_cop_grab_object);
+ ret = object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
+ fscache_stat_d(&fscache_n_cop_grab_object);
+ return ret;
}
/*
@@ -702,7 +780,9 @@ static void fscache_object_slow_work_put_ref(struct slow_work *work)
struct fscache_object *object =
container_of(work, struct fscache_object, work);
- return object->cache->ops->put_object(object);
+ fscache_stat(&fscache_n_cop_put_object);
+ object->cache->ops->put_object(object);
+ fscache_stat_d(&fscache_n_cop_put_object);
}
/*
@@ -739,7 +819,9 @@ static void fscache_enqueue_dependents(struct fscache_object *object)
/* sort onto appropriate lists */
fscache_enqueue_object(dep);
+ fscache_stat(&fscache_n_cop_put_object);
dep->cache->ops->put_object(dep);
+ fscache_stat_d(&fscache_n_cop_put_object);
if (!list_empty(&object->dependents))
cond_resched_lock(&object->lock);
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index e7f8d53b8b6b..313e79a14266 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
@@ -13,6 +13,7 @@
#define FSCACHE_DEBUG_LEVEL OPERATION
#include <linux/module.h>
+#include <linux/seq_file.h>
#include "internal.h"
atomic_t fscache_op_debug_id;
@@ -31,32 +32,33 @@ void fscache_enqueue_operation(struct fscache_operation *op)
_enter("{OBJ%x OP%x,%u}",
op->object->debug_id, op->debug_id, atomic_read(&op->usage));
+ fscache_set_op_state(op, "EnQ");
+
+ ASSERT(list_empty(&op->pend_link));
ASSERT(op->processor != NULL);
ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE);
ASSERTCMP(atomic_read(&op->usage), >, 0);
- if (list_empty(&op->pend_link)) {
- switch (op->flags & FSCACHE_OP_TYPE) {
- case FSCACHE_OP_FAST:
- _debug("queue fast");
- atomic_inc(&op->usage);
- if (!schedule_work(&op->fast_work))
- fscache_put_operation(op);
- break;
- case FSCACHE_OP_SLOW:
- _debug("queue slow");
- slow_work_enqueue(&op->slow_work);
- break;
- case FSCACHE_OP_MYTHREAD:
- _debug("queue for caller's attention");
- break;
- default:
- printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
- op->flags);
- BUG();
- break;
- }
- fscache_stat(&fscache_n_op_enqueue);
+ fscache_stat(&fscache_n_op_enqueue);
+ switch (op->flags & FSCACHE_OP_TYPE) {
+ case FSCACHE_OP_FAST:
+ _debug("queue fast");
+ atomic_inc(&op->usage);
+ if (!schedule_work(&op->fast_work))
+ fscache_put_operation(op);
+ break;
+ case FSCACHE_OP_SLOW:
+ _debug("queue slow");
+ slow_work_enqueue(&op->slow_work);
+ break;
+ case FSCACHE_OP_MYTHREAD:
+ _debug("queue for caller's attention");
+ break;
+ default:
+ printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
+ op->flags);
+ BUG();
+ break;
}
}
EXPORT_SYMBOL(fscache_enqueue_operation);
@@ -67,6 +69,8 @@ EXPORT_SYMBOL(fscache_enqueue_operation);
static void fscache_run_op(struct fscache_object *object,
struct fscache_operation *op)
{
+ fscache_set_op_state(op, "Run");
+
object->n_in_progress++;
if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
@@ -87,9 +91,12 @@ int fscache_submit_exclusive_op(struct fscache_object *object,
_enter("{OBJ%x OP%x},", object->debug_id, op->debug_id);
+ fscache_set_op_state(op, "SubmitX");
+
spin_lock(&object->lock);
ASSERTCMP(object->n_ops, >=, object->n_in_progress);
ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+ ASSERT(list_empty(&op->pend_link));
ret = -ENOBUFS;
if (fscache_object_is_active(object)) {
@@ -190,9 +197,12 @@ int fscache_submit_op(struct fscache_object *object,
ASSERTCMP(atomic_read(&op->usage), >, 0);
+ fscache_set_op_state(op, "Submit");
+
spin_lock(&object->lock);
ASSERTCMP(object->n_ops, >=, object->n_in_progress);
ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+ ASSERT(list_empty(&op->pend_link));
ostate = object->state;
smp_rmb();
@@ -222,6 +232,11 @@ int fscache_submit_op(struct fscache_object *object,
list_add_tail(&op->pend_link, &object->pending_ops);
fscache_stat(&fscache_n_op_pend);
ret = 0;
+ } else if (object->state == FSCACHE_OBJECT_DYING ||
+ object->state == FSCACHE_OBJECT_LC_DYING ||
+ object->state == FSCACHE_OBJECT_WITHDRAWING) {
+ fscache_stat(&fscache_n_op_rejected);
+ ret = -ENOBUFS;
} else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
fscache_report_unexpected_submission(object, op, ostate);
ASSERT(!fscache_object_is_active(object));
@@ -264,12 +279,7 @@ void fscache_start_operations(struct fscache_object *object)
stop = true;
}
list_del_init(&op->pend_link);
- object->n_in_progress++;
-
- if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
- wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
- if (op->processor)
- fscache_enqueue_operation(op);
+ fscache_run_op(object, op);
/* the pending queue was holding a ref on the object */
fscache_put_operation(op);
@@ -282,6 +292,36 @@ void fscache_start_operations(struct fscache_object *object)
}
/*
+ * cancel an operation that's pending on an object
+ */
+int fscache_cancel_op(struct fscache_operation *op)
+{
+ struct fscache_object *object = op->object;
+ int ret;
+
+ _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id);
+
+ spin_lock(&object->lock);
+
+ ret = -EBUSY;
+ if (!list_empty(&op->pend_link)) {
+ fscache_stat(&fscache_n_op_cancelled);
+ list_del_init(&op->pend_link);
+ object->n_ops--;
+ if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
+ object->n_exclusive--;
+ if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
+ wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
+ fscache_put_operation(op);
+ ret = 0;
+ }
+
+ spin_unlock(&object->lock);
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
* release an operation
* - queues pending ops if this is the last in-progress op
*/
@@ -298,6 +338,8 @@ void fscache_put_operation(struct fscache_operation *op)
if (!atomic_dec_and_test(&op->usage))
return;
+ fscache_set_op_state(op, "Put");
+
_debug("PUT OP");
if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags))
BUG();
@@ -311,6 +353,9 @@ void fscache_put_operation(struct fscache_operation *op)
object = op->object;
+ if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags))
+ atomic_dec(&object->n_reads);
+
/* now... we may get called with the object spinlock held, so we
* complete the cleanup here only if we can immediately acquire the
* lock, and defer it otherwise */
@@ -452,8 +497,27 @@ static void fscache_op_execute(struct slow_work *work)
_leave("");
}
+/*
+ * describe an operation for slow-work debugging
+ */
+#ifdef CONFIG_SLOW_WORK_PROC
+static void fscache_op_desc(struct slow_work *work, struct seq_file *m)
+{
+ struct fscache_operation *op =
+ container_of(work, struct fscache_operation, slow_work);
+
+ seq_printf(m, "FSC: OBJ%x OP%x: %s/%s fl=%lx",
+ op->object->debug_id, op->debug_id,
+ op->name, op->state, op->flags);
+}
+#endif
+
const struct slow_work_ops fscache_op_slow_work_ops = {
+ .owner = THIS_MODULE,
.get_ref = fscache_op_get_ref,
.put_ref = fscache_op_put_ref,
.execute = fscache_op_execute,
+#ifdef CONFIG_SLOW_WORK_PROC
+ .desc = fscache_op_desc,
+#endif
};
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 2568e0eb644f..c598ea4c4e7d 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -43,18 +43,102 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa
EXPORT_SYMBOL(__fscache_wait_on_page_write);
/*
- * note that a page has finished being written to the cache
+ * decide whether a page can be released, possibly by cancelling a store to it
+ * - we're allowed to sleep if __GFP_WAIT is flagged
*/
-static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *page)
+bool __fscache_maybe_release_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp)
{
struct page *xpage;
+ void *val;
+
+ _enter("%p,%p,%x", cookie, page, gfp);
+
+ rcu_read_lock();
+ val = radix_tree_lookup(&cookie->stores, page->index);
+ if (!val) {
+ rcu_read_unlock();
+ fscache_stat(&fscache_n_store_vmscan_not_storing);
+ __fscache_uncache_page(cookie, page);
+ return true;
+ }
+
+ /* see if the page is actually undergoing storage - if so we can't get
+ * rid of it till the cache has finished with it */
+ if (radix_tree_tag_get(&cookie->stores, page->index,
+ FSCACHE_COOKIE_STORING_TAG)) {
+ rcu_read_unlock();
+ goto page_busy;
+ }
+
+ /* the page is pending storage, so we attempt to cancel the store and
+ * discard the store request so that the page can be reclaimed */
+ spin_lock(&cookie->stores_lock);
+ rcu_read_unlock();
+
+ if (radix_tree_tag_get(&cookie->stores, page->index,
+ FSCACHE_COOKIE_STORING_TAG)) {
+ /* the page started to undergo storage whilst we were looking,
+ * so now we can only wait or return */
+ spin_unlock(&cookie->stores_lock);
+ goto page_busy;
+ }
- spin_lock(&cookie->lock);
xpage = radix_tree_delete(&cookie->stores, page->index);
- spin_unlock(&cookie->lock);
- ASSERT(xpage != NULL);
+ spin_unlock(&cookie->stores_lock);
+
+ if (xpage) {
+ fscache_stat(&fscache_n_store_vmscan_cancelled);
+ fscache_stat(&fscache_n_store_radix_deletes);
+ ASSERTCMP(xpage, ==, page);
+ } else {
+ fscache_stat(&fscache_n_store_vmscan_gone);
+ }
wake_up_bit(&cookie->flags, 0);
+ if (xpage)
+ page_cache_release(xpage);
+ __fscache_uncache_page(cookie, page);
+ return true;
+
+page_busy:
+ /* we might want to wait here, but that could deadlock the allocator as
+ * the slow-work threads writing to the cache may all end up sleeping
+ * on memory allocation */
+ fscache_stat(&fscache_n_store_vmscan_busy);
+ return false;
+}
+EXPORT_SYMBOL(__fscache_maybe_release_page);
+
+/*
+ * note that a page has finished being written to the cache
+ */
+static void fscache_end_page_write(struct fscache_object *object,
+ struct page *page)
+{
+ struct fscache_cookie *cookie;
+ struct page *xpage = NULL;
+
+ spin_lock(&object->lock);
+ cookie = object->cookie;
+ if (cookie) {
+ /* delete the page from the tree if it is now no longer
+ * pending */
+ spin_lock(&cookie->stores_lock);
+ radix_tree_tag_clear(&cookie->stores, page->index,
+ FSCACHE_COOKIE_STORING_TAG);
+ if (!radix_tree_tag_get(&cookie->stores, page->index,
+ FSCACHE_COOKIE_PENDING_TAG)) {
+ fscache_stat(&fscache_n_store_radix_deletes);
+ xpage = radix_tree_delete(&cookie->stores, page->index);
+ }
+ spin_unlock(&cookie->stores_lock);
+ wake_up_bit(&cookie->flags, 0);
+ }
+ spin_unlock(&object->lock);
+ if (xpage)
+ page_cache_release(xpage);
}
/*
@@ -63,14 +147,21 @@ static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *p
static void fscache_attr_changed_op(struct fscache_operation *op)
{
struct fscache_object *object = op->object;
+ int ret;
_enter("{OBJ%x OP%x}", object->debug_id, op->debug_id);
fscache_stat(&fscache_n_attr_changed_calls);
- if (fscache_object_is_active(object) &&
- object->cache->ops->attr_changed(object) < 0)
- fscache_abort_object(object);
+ if (fscache_object_is_active(object)) {
+ fscache_set_op_state(op, "CallFS");
+ fscache_stat(&fscache_n_cop_attr_changed);
+ ret = object->cache->ops->attr_changed(object);
+ fscache_stat_d(&fscache_n_cop_attr_changed);
+ fscache_set_op_state(op, "Done");
+ if (ret < 0)
+ fscache_abort_object(object);
+ }
_leave("");
}
@@ -99,6 +190,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
fscache_operation_init(op, NULL);
fscache_operation_init_slow(op, fscache_attr_changed_op);
op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE);
+ fscache_set_op_name(op, "Attr");
spin_lock(&cookie->lock);
@@ -184,6 +276,7 @@ static struct fscache_retrieval *fscache_alloc_retrieval(
op->start_time = jiffies;
INIT_WORK(&op->op.fast_work, fscache_retrieval_work);
INIT_LIST_HEAD(&op->to_do);
+ fscache_set_op_name(&op->op, "Retr");
return op;
}
@@ -221,6 +314,43 @@ static int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie)
}
/*
+ * wait for an object to become active (or dead)
+ */
+static int fscache_wait_for_retrieval_activation(struct fscache_object *object,
+ struct fscache_retrieval *op,
+ atomic_t *stat_op_waits,
+ atomic_t *stat_object_dead)
+{
+ int ret;
+
+ if (!test_bit(FSCACHE_OP_WAITING, &op->op.flags))
+ goto check_if_dead;
+
+ _debug(">>> WT");
+ fscache_stat(stat_op_waits);
+ if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+ fscache_wait_bit_interruptible,
+ TASK_INTERRUPTIBLE) < 0) {
+ ret = fscache_cancel_op(&op->op);
+ if (ret == 0)
+ return -ERESTARTSYS;
+
+ /* it's been removed from the pending queue by another party,
+ * so we should get to run shortly */
+ wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+ fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+ }
+ _debug("<<< GO");
+
+check_if_dead:
+ if (unlikely(fscache_object_is_dead(object))) {
+ fscache_stat(stat_object_dead);
+ return -ENOBUFS;
+ }
+ return 0;
+}
+
+/*
* read a page from the cache or allocate a block in which to store it
* - we return:
* -ENOMEM - out of memory, nothing done
@@ -257,6 +387,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
_leave(" = -ENOMEM");
return -ENOMEM;
}
+ fscache_set_op_name(&op->op, "RetrRA1");
spin_lock(&cookie->lock);
@@ -267,6 +398,9 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
ASSERTCMP(object->state, >, FSCACHE_OBJECT_LOOKING_UP);
+ atomic_inc(&object->n_reads);
+ set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
+
if (fscache_submit_op(object, &op->op) < 0)
goto nobufs_unlock;
spin_unlock(&cookie->lock);
@@ -279,23 +413,27 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
/* we wait for the operation to become active, and then process it
* *here*, in this thread, and not in the thread pool */
- if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
- _debug(">>> WT");
- fscache_stat(&fscache_n_retrieval_op_waits);
- wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
- fscache_wait_bit, TASK_UNINTERRUPTIBLE);
- _debug("<<< GO");
- }
+ ret = fscache_wait_for_retrieval_activation(
+ object, op,
+ __fscache_stat(&fscache_n_retrieval_op_waits),
+ __fscache_stat(&fscache_n_retrievals_object_dead));
+ if (ret < 0)
+ goto error;
/* ask the cache to honour the operation */
if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
+ fscache_stat(&fscache_n_cop_allocate_page);
ret = object->cache->ops->allocate_page(op, page, gfp);
+ fscache_stat_d(&fscache_n_cop_allocate_page);
if (ret == 0)
ret = -ENODATA;
} else {
+ fscache_stat(&fscache_n_cop_read_or_alloc_page);
ret = object->cache->ops->read_or_alloc_page(op, page, gfp);
+ fscache_stat_d(&fscache_n_cop_read_or_alloc_page);
}
+error:
if (ret == -ENOMEM)
fscache_stat(&fscache_n_retrievals_nomem);
else if (ret == -ERESTARTSYS)
@@ -347,7 +485,6 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
void *context,
gfp_t gfp)
{
- fscache_pages_retrieval_func_t func;
struct fscache_retrieval *op;
struct fscache_object *object;
int ret;
@@ -369,6 +506,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
op = fscache_alloc_retrieval(mapping, end_io_func, context);
if (!op)
return -ENOMEM;
+ fscache_set_op_name(&op->op, "RetrRAN");
spin_lock(&cookie->lock);
@@ -377,6 +515,9 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
object = hlist_entry(cookie->backing_objects.first,
struct fscache_object, cookie_link);
+ atomic_inc(&object->n_reads);
+ set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
+
if (fscache_submit_op(object, &op->op) < 0)
goto nobufs_unlock;
spin_unlock(&cookie->lock);
@@ -389,21 +530,27 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
/* we wait for the operation to become active, and then process it
* *here*, in this thread, and not in the thread pool */
- if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
- _debug(">>> WT");
- fscache_stat(&fscache_n_retrieval_op_waits);
- wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
- fscache_wait_bit, TASK_UNINTERRUPTIBLE);
- _debug("<<< GO");
- }
+ ret = fscache_wait_for_retrieval_activation(
+ object, op,
+ __fscache_stat(&fscache_n_retrieval_op_waits),
+ __fscache_stat(&fscache_n_retrievals_object_dead));
+ if (ret < 0)
+ goto error;
/* ask the cache to honour the operation */
- if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags))
- func = object->cache->ops->allocate_pages;
- else
- func = object->cache->ops->read_or_alloc_pages;
- ret = func(op, pages, nr_pages, gfp);
+ if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
+ fscache_stat(&fscache_n_cop_allocate_pages);
+ ret = object->cache->ops->allocate_pages(
+ op, pages, nr_pages, gfp);
+ fscache_stat_d(&fscache_n_cop_allocate_pages);
+ } else {
+ fscache_stat(&fscache_n_cop_read_or_alloc_pages);
+ ret = object->cache->ops->read_or_alloc_pages(
+ op, pages, nr_pages, gfp);
+ fscache_stat_d(&fscache_n_cop_read_or_alloc_pages);
+ }
+error:
if (ret == -ENOMEM)
fscache_stat(&fscache_n_retrievals_nomem);
else if (ret == -ERESTARTSYS)
@@ -461,6 +608,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
op = fscache_alloc_retrieval(page->mapping, NULL, NULL);
if (!op)
return -ENOMEM;
+ fscache_set_op_name(&op->op, "RetrAL1");
spin_lock(&cookie->lock);
@@ -475,18 +623,22 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
fscache_stat(&fscache_n_alloc_ops);
- if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
- _debug(">>> WT");
- fscache_stat(&fscache_n_alloc_op_waits);
- wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
- fscache_wait_bit, TASK_UNINTERRUPTIBLE);
- _debug("<<< GO");
- }
+ ret = fscache_wait_for_retrieval_activation(
+ object, op,
+ __fscache_stat(&fscache_n_alloc_op_waits),
+ __fscache_stat(&fscache_n_allocs_object_dead));
+ if (ret < 0)
+ goto error;
/* ask the cache to honour the operation */
+ fscache_stat(&fscache_n_cop_allocate_page);
ret = object->cache->ops->allocate_page(op, page, gfp);
+ fscache_stat_d(&fscache_n_cop_allocate_page);
- if (ret < 0)
+error:
+ if (ret == -ERESTARTSYS)
+ fscache_stat(&fscache_n_allocs_intr);
+ else if (ret < 0)
fscache_stat(&fscache_n_allocs_nobufs);
else
fscache_stat(&fscache_n_allocs_ok);
@@ -521,7 +673,7 @@ static void fscache_write_op(struct fscache_operation *_op)
struct fscache_storage *op =
container_of(_op, struct fscache_storage, op);
struct fscache_object *object = op->op.object;
- struct fscache_cookie *cookie = object->cookie;
+ struct fscache_cookie *cookie;
struct page *page;
unsigned n;
void *results[1];
@@ -529,16 +681,19 @@ static void fscache_write_op(struct fscache_operation *_op)
_enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage));
- spin_lock(&cookie->lock);
+ fscache_set_op_state(&op->op, "GetPage");
+
spin_lock(&object->lock);
+ cookie = object->cookie;
- if (!fscache_object_is_active(object)) {
+ if (!fscache_object_is_active(object) || !cookie) {
spin_unlock(&object->lock);
- spin_unlock(&cookie->lock);
_leave("");
return;
}
+ spin_lock(&cookie->stores_lock);
+
fscache_stat(&fscache_n_store_calls);
/* find a page to store */
@@ -549,23 +704,35 @@ static void fscache_write_op(struct fscache_operation *_op)
goto superseded;
page = results[0];
_debug("gang %d [%lx]", n, page->index);
- if (page->index > op->store_limit)
+ if (page->index > op->store_limit) {
+ fscache_stat(&fscache_n_store_pages_over_limit);
goto superseded;
+ }
- radix_tree_tag_clear(&cookie->stores, page->index,
- FSCACHE_COOKIE_PENDING_TAG);
+ if (page) {
+ radix_tree_tag_set(&cookie->stores, page->index,
+ FSCACHE_COOKIE_STORING_TAG);
+ radix_tree_tag_clear(&cookie->stores, page->index,
+ FSCACHE_COOKIE_PENDING_TAG);
+ }
+ spin_unlock(&cookie->stores_lock);
spin_unlock(&object->lock);
- spin_unlock(&cookie->lock);
if (page) {
+ fscache_set_op_state(&op->op, "Store");
+ fscache_stat(&fscache_n_store_pages);
+ fscache_stat(&fscache_n_cop_write_page);
ret = object->cache->ops->write_page(op, page);
- fscache_end_page_write(cookie, page);
- page_cache_release(page);
- if (ret < 0)
+ fscache_stat_d(&fscache_n_cop_write_page);
+ fscache_set_op_state(&op->op, "EndWrite");
+ fscache_end_page_write(object, page);
+ if (ret < 0) {
+ fscache_set_op_state(&op->op, "Abort");
fscache_abort_object(object);
- else
+ } else {
fscache_enqueue_operation(&op->op);
+ }
}
_leave("");
@@ -575,9 +742,9 @@ superseded:
/* this writer is going away and there aren't any more things to
* write */
_debug("cease");
+ spin_unlock(&cookie->stores_lock);
clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
spin_unlock(&object->lock);
- spin_unlock(&cookie->lock);
_leave("");
}
@@ -634,6 +801,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
fscache_operation_init(&op->op, fscache_release_write_op);
fscache_operation_init_slow(&op->op, fscache_write_op);
op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING);
+ fscache_set_op_name(&op->op, "Write1");
ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM);
if (ret < 0)
@@ -652,6 +820,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
/* add the page to the pending-storage radix tree on the backing
* object */
spin_lock(&object->lock);
+ spin_lock(&cookie->stores_lock);
_debug("store limit %llx", (unsigned long long) object->store_limit);
@@ -672,6 +841,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags))
goto already_pending;
+ spin_unlock(&cookie->stores_lock);
spin_unlock(&object->lock);
op->op.debug_id = atomic_inc_return(&fscache_op_debug_id);
@@ -693,6 +863,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
already_queued:
fscache_stat(&fscache_n_stores_again);
already_pending:
+ spin_unlock(&cookie->stores_lock);
spin_unlock(&object->lock);
spin_unlock(&cookie->lock);
radix_tree_preload_end();
@@ -702,7 +873,9 @@ already_pending:
return 0;
submit_failed:
+ spin_lock(&cookie->stores_lock);
radix_tree_delete(&cookie->stores, page->index);
+ spin_unlock(&cookie->stores_lock);
page_cache_release(page);
ret = -ENOBUFS;
goto nobufs;
@@ -763,7 +936,9 @@ void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page)
if (TestClearPageFsCache(page) &&
object->cache->ops->uncache_page) {
/* the cache backend releases the cookie lock */
+ fscache_stat(&fscache_n_cop_uncache_page);
object->cache->ops->uncache_page(object, page);
+ fscache_stat_d(&fscache_n_cop_uncache_page);
goto done;
}
diff --git a/fs/fscache/proc.c b/fs/fscache/proc.c
index beeab44bc31a..1d9e4951a597 100644
--- a/fs/fscache/proc.c
+++ b/fs/fscache/proc.c
@@ -37,10 +37,20 @@ int __init fscache_proc_init(void)
goto error_histogram;
#endif
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+ if (!proc_create("fs/fscache/objects", S_IFREG | 0444, NULL,
+ &fscache_objlist_fops))
+ goto error_objects;
+#endif
+
_leave(" = 0");
return 0;
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+error_objects:
+#endif
#ifdef CONFIG_FSCACHE_HISTOGRAM
+ remove_proc_entry("fs/fscache/histogram", NULL);
error_histogram:
#endif
#ifdef CONFIG_FSCACHE_STATS
@@ -58,6 +68,9 @@ error_dir:
*/
void fscache_proc_cleanup(void)
{
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+ remove_proc_entry("fs/fscache/objects", NULL);
+#endif
#ifdef CONFIG_FSCACHE_HISTOGRAM
remove_proc_entry("fs/fscache/histogram", NULL);
#endif
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
index 65deb99e756b..46435f3aae68 100644
--- a/fs/fscache/stats.c
+++ b/fs/fscache/stats.c
@@ -25,6 +25,8 @@ atomic_t fscache_n_op_requeue;
atomic_t fscache_n_op_deferred_release;
atomic_t fscache_n_op_release;
atomic_t fscache_n_op_gc;
+atomic_t fscache_n_op_cancelled;
+atomic_t fscache_n_op_rejected;
atomic_t fscache_n_attr_changed;
atomic_t fscache_n_attr_changed_ok;
@@ -36,6 +38,8 @@ atomic_t fscache_n_allocs;
atomic_t fscache_n_allocs_ok;
atomic_t fscache_n_allocs_wait;
atomic_t fscache_n_allocs_nobufs;
+atomic_t fscache_n_allocs_intr;
+atomic_t fscache_n_allocs_object_dead;
atomic_t fscache_n_alloc_ops;
atomic_t fscache_n_alloc_op_waits;
@@ -46,6 +50,7 @@ atomic_t fscache_n_retrievals_nodata;
atomic_t fscache_n_retrievals_nobufs;
atomic_t fscache_n_retrievals_intr;
atomic_t fscache_n_retrievals_nomem;
+atomic_t fscache_n_retrievals_object_dead;
atomic_t fscache_n_retrieval_ops;
atomic_t fscache_n_retrieval_op_waits;
@@ -56,6 +61,14 @@ atomic_t fscache_n_stores_nobufs;
atomic_t fscache_n_stores_oom;
atomic_t fscache_n_store_ops;
atomic_t fscache_n_store_calls;
+atomic_t fscache_n_store_pages;
+atomic_t fscache_n_store_radix_deletes;
+atomic_t fscache_n_store_pages_over_limit;
+
+atomic_t fscache_n_store_vmscan_not_storing;
+atomic_t fscache_n_store_vmscan_gone;
+atomic_t fscache_n_store_vmscan_busy;
+atomic_t fscache_n_store_vmscan_cancelled;
atomic_t fscache_n_marks;
atomic_t fscache_n_uncaches;
@@ -74,6 +87,7 @@ atomic_t fscache_n_updates_run;
atomic_t fscache_n_relinquishes;
atomic_t fscache_n_relinquishes_null;
atomic_t fscache_n_relinquishes_waitcrt;
+atomic_t fscache_n_relinquishes_retire;
atomic_t fscache_n_cookie_index;
atomic_t fscache_n_cookie_data;
@@ -84,6 +98,7 @@ atomic_t fscache_n_object_no_alloc;
atomic_t fscache_n_object_lookups;
atomic_t fscache_n_object_lookups_negative;
atomic_t fscache_n_object_lookups_positive;
+atomic_t fscache_n_object_lookups_timed_out;
atomic_t fscache_n_object_created;
atomic_t fscache_n_object_avail;
atomic_t fscache_n_object_dead;
@@ -93,6 +108,23 @@ atomic_t fscache_n_checkaux_okay;
atomic_t fscache_n_checkaux_update;
atomic_t fscache_n_checkaux_obsolete;
+atomic_t fscache_n_cop_alloc_object;
+atomic_t fscache_n_cop_lookup_object;
+atomic_t fscache_n_cop_lookup_complete;
+atomic_t fscache_n_cop_grab_object;
+atomic_t fscache_n_cop_update_object;
+atomic_t fscache_n_cop_drop_object;
+atomic_t fscache_n_cop_put_object;
+atomic_t fscache_n_cop_sync_cache;
+atomic_t fscache_n_cop_attr_changed;
+atomic_t fscache_n_cop_read_or_alloc_page;
+atomic_t fscache_n_cop_read_or_alloc_pages;
+atomic_t fscache_n_cop_allocate_page;
+atomic_t fscache_n_cop_allocate_pages;
+atomic_t fscache_n_cop_write_page;
+atomic_t fscache_n_cop_uncache_page;
+atomic_t fscache_n_cop_dissociate_pages;
+
/*
* display the general statistics
*/
@@ -129,10 +161,11 @@ static int fscache_stats_show(struct seq_file *m, void *v)
atomic_read(&fscache_n_acquires_nobufs),
atomic_read(&fscache_n_acquires_oom));
- seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u\n",
+ seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u tmo=%u\n",
atomic_read(&fscache_n_object_lookups),
atomic_read(&fscache_n_object_lookups_negative),
atomic_read(&fscache_n_object_lookups_positive),
+ atomic_read(&fscache_n_object_lookups_timed_out),
atomic_read(&fscache_n_object_created));
seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
@@ -140,10 +173,11 @@ static int fscache_stats_show(struct seq_file *m, void *v)
atomic_read(&fscache_n_updates_null),
atomic_read(&fscache_n_updates_run));
- seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u\n",
+ seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u rtr=%u\n",
atomic_read(&fscache_n_relinquishes),
atomic_read(&fscache_n_relinquishes_null),
- atomic_read(&fscache_n_relinquishes_waitcrt));
+ atomic_read(&fscache_n_relinquishes_waitcrt),
+ atomic_read(&fscache_n_relinquishes_retire));
seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n",
atomic_read(&fscache_n_attr_changed),
@@ -152,14 +186,16 @@ static int fscache_stats_show(struct seq_file *m, void *v)
atomic_read(&fscache_n_attr_changed_nomem),
atomic_read(&fscache_n_attr_changed_calls));
- seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n",
+ seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u int=%u\n",
atomic_read(&fscache_n_allocs),
atomic_read(&fscache_n_allocs_ok),
atomic_read(&fscache_n_allocs_wait),
- atomic_read(&fscache_n_allocs_nobufs));
- seq_printf(m, "Allocs : ops=%u owt=%u\n",
+ atomic_read(&fscache_n_allocs_nobufs),
+ atomic_read(&fscache_n_allocs_intr));
+ seq_printf(m, "Allocs : ops=%u owt=%u abt=%u\n",
atomic_read(&fscache_n_alloc_ops),
- atomic_read(&fscache_n_alloc_op_waits));
+ atomic_read(&fscache_n_alloc_op_waits),
+ atomic_read(&fscache_n_allocs_object_dead));
seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u"
" int=%u oom=%u\n",
@@ -170,9 +206,10 @@ static int fscache_stats_show(struct seq_file *m, void *v)
atomic_read(&fscache_n_retrievals_nobufs),
atomic_read(&fscache_n_retrievals_intr),
atomic_read(&fscache_n_retrievals_nomem));
- seq_printf(m, "Retrvls: ops=%u owt=%u\n",
+ seq_printf(m, "Retrvls: ops=%u owt=%u abt=%u\n",
atomic_read(&fscache_n_retrieval_ops),
- atomic_read(&fscache_n_retrieval_op_waits));
+ atomic_read(&fscache_n_retrieval_op_waits),
+ atomic_read(&fscache_n_retrievals_object_dead));
seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n",
atomic_read(&fscache_n_stores),
@@ -180,18 +217,49 @@ static int fscache_stats_show(struct seq_file *m, void *v)
atomic_read(&fscache_n_stores_again),
atomic_read(&fscache_n_stores_nobufs),
atomic_read(&fscache_n_stores_oom));
- seq_printf(m, "Stores : ops=%u run=%u\n",
+ seq_printf(m, "Stores : ops=%u run=%u pgs=%u rxd=%u olm=%u\n",
atomic_read(&fscache_n_store_ops),
- atomic_read(&fscache_n_store_calls));
+ atomic_read(&fscache_n_store_calls),
+ atomic_read(&fscache_n_store_pages),
+ atomic_read(&fscache_n_store_radix_deletes),
+ atomic_read(&fscache_n_store_pages_over_limit));
- seq_printf(m, "Ops : pend=%u run=%u enq=%u\n",
+ seq_printf(m, "VmScan : nos=%u gon=%u bsy=%u can=%u\n",
+ atomic_read(&fscache_n_store_vmscan_not_storing),
+ atomic_read(&fscache_n_store_vmscan_gone),
+ atomic_read(&fscache_n_store_vmscan_busy),
+ atomic_read(&fscache_n_store_vmscan_cancelled));
+
+ seq_printf(m, "Ops : pend=%u run=%u enq=%u can=%u rej=%u\n",
atomic_read(&fscache_n_op_pend),
atomic_read(&fscache_n_op_run),
- atomic_read(&fscache_n_op_enqueue));
+ atomic_read(&fscache_n_op_enqueue),
+ atomic_read(&fscache_n_op_cancelled),
+ atomic_read(&fscache_n_op_rejected));
seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n",
atomic_read(&fscache_n_op_deferred_release),
atomic_read(&fscache_n_op_release),
atomic_read(&fscache_n_op_gc));
+
+ seq_printf(m, "CacheOp: alo=%d luo=%d luc=%d gro=%d\n",
+ atomic_read(&fscache_n_cop_alloc_object),
+ atomic_read(&fscache_n_cop_lookup_object),
+ atomic_read(&fscache_n_cop_lookup_complete),
+ atomic_read(&fscache_n_cop_grab_object));
+ seq_printf(m, "CacheOp: upo=%d dro=%d pto=%d atc=%d syn=%d\n",
+ atomic_read(&fscache_n_cop_update_object),
+ atomic_read(&fscache_n_cop_drop_object),
+ atomic_read(&fscache_n_cop_put_object),
+ atomic_read(&fscache_n_cop_attr_changed),
+ atomic_read(&fscache_n_cop_sync_cache));
+ seq_printf(m, "CacheOp: rap=%d ras=%d alp=%d als=%d wrp=%d ucp=%d dsp=%d\n",
+ atomic_read(&fscache_n_cop_read_or_alloc_page),
+ atomic_read(&fscache_n_cop_read_or_alloc_pages),
+ atomic_read(&fscache_n_cop_allocate_page),
+ atomic_read(&fscache_n_cop_allocate_pages),
+ atomic_read(&fscache_n_cop_write_page),
+ atomic_read(&fscache_n_cop_uncache_page),
+ atomic_read(&fscache_n_cop_dissociate_pages));
return 0;
}
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 992f6c9410bb..4787ae6c5c1c 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -385,6 +385,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
if (fc->no_create)
return -ENOSYS;
+ if (flags & O_DIRECT)
+ return -EINVAL;
+
forget_req = fuse_get_req(fc);
if (IS_ERR(forget_req))
return PTR_ERR(forget_req);
@@ -712,8 +715,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
fuse_invalidate_attr(newdir);
/* newent will end up negative */
- if (newent->d_inode)
+ if (newent->d_inode) {
+ fuse_invalidate_attr(newent->d_inode);
fuse_invalidate_entry_cache(newent);
+ }
} else if (err == -EINTR) {
/* If request was interrupted, DEITY only knows if the
rename actually took place. If the invalidation
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index a3492f7d207c..c18913a777ae 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1063,7 +1063,8 @@ ssize_t fuse_direct_io(struct file *file, const char __user *buf,
break;
}
}
- fuse_put_request(fc, req);
+ if (!IS_ERR(req))
+ fuse_put_request(fc, req);
if (res > 0)
*ppos = pos;
@@ -1599,7 +1600,7 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov,
kaddr += copy;
}
- kunmap(map);
+ kunmap(page);
}
return 0;
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig
index 5971359d2090..4dcddf83326f 100644
--- a/fs/gfs2/Kconfig
+++ b/fs/gfs2/Kconfig
@@ -8,6 +8,8 @@ config GFS2_FS
select FS_POSIX_ACL
select CRC32
select SLOW_WORK
+ select QUOTA
+ select QUOTACTL
help
A cluster filesystem.
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index 3fc4e3ac7d84..3eb1ea846173 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -12,6 +12,7 @@
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
+#include <linux/xattr.h>
#include <linux/posix_acl.h>
#include <linux/posix_acl_xattr.h>
#include <linux/gfs2_ondisk.h>
@@ -26,108 +27,44 @@
#include "trans.h"
#include "util.h"
-#define ACL_ACCESS 1
-#define ACL_DEFAULT 0
-
-int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
- struct gfs2_ea_request *er, int *remove, mode_t *mode)
+static const char *gfs2_acl_name(int type)
{
- struct posix_acl *acl;
- int error;
-
- error = gfs2_acl_validate_remove(ip, access);
- if (error)
- return error;
-
- if (!er->er_data)
- return -EINVAL;
-
- acl = posix_acl_from_xattr(er->er_data, er->er_data_len);
- if (IS_ERR(acl))
- return PTR_ERR(acl);
- if (!acl) {
- *remove = 1;
- return 0;
- }
-
- error = posix_acl_valid(acl);
- if (error)
- goto out;
-
- if (access) {
- error = posix_acl_equiv_mode(acl, mode);
- if (!error)
- *remove = 1;
- else if (error > 0)
- error = 0;
+ switch (type) {
+ case ACL_TYPE_ACCESS:
+ return GFS2_POSIX_ACL_ACCESS;
+ case ACL_TYPE_DEFAULT:
+ return GFS2_POSIX_ACL_DEFAULT;
}
-
-out:
- posix_acl_release(acl);
- return error;
-}
-
-int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
-{
- if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl)
- return -EOPNOTSUPP;
- if (!is_owner_or_cap(&ip->i_inode))
- return -EPERM;
- if (S_ISLNK(ip->i_inode.i_mode))
- return -EOPNOTSUPP;
- if (!access && !S_ISDIR(ip->i_inode.i_mode))
- return -EACCES;
-
- return 0;
+ return NULL;
}
-static int acl_get(struct gfs2_inode *ip, const char *name,
- struct posix_acl **acl, struct gfs2_ea_location *el,
- char **datap, unsigned int *lenp)
+static struct posix_acl *gfs2_acl_get(struct gfs2_inode *ip, int type)
{
+ struct posix_acl *acl;
+ const char *name;
char *data;
- unsigned int len;
- int error;
-
- el->el_bh = NULL;
+ int len;
if (!ip->i_eattr)
- return 0;
-
- error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, el);
- if (error)
- return error;
- if (!el->el_ea)
- return 0;
- if (!GFS2_EA_DATA_LEN(el->el_ea))
- goto out;
+ return NULL;
- len = GFS2_EA_DATA_LEN(el->el_ea);
- data = kmalloc(len, GFP_NOFS);
- error = -ENOMEM;
- if (!data)
- goto out;
+ acl = get_cached_acl(&ip->i_inode, type);
+ if (acl != ACL_NOT_CACHED)
+ return acl;
- error = gfs2_ea_get_copy(ip, el, data, len);
- if (error < 0)
- goto out_kfree;
- error = 0;
+ name = gfs2_acl_name(type);
+ if (name == NULL)
+ return ERR_PTR(-EINVAL);
- if (acl) {
- *acl = posix_acl_from_xattr(data, len);
- if (IS_ERR(*acl))
- error = PTR_ERR(*acl);
- }
+ len = gfs2_xattr_acl_get(ip, name, &data);
+ if (len < 0)
+ return ERR_PTR(len);
+ if (len == 0)
+ return NULL;
-out_kfree:
- if (error || !datap) {
- kfree(data);
- } else {
- *datap = data;
- *lenp = len;
- }
-out:
- return error;
+ acl = posix_acl_from_xattr(data, len);
+ kfree(data);
+ return acl;
}
/**
@@ -140,14 +77,12 @@ out:
int gfs2_check_acl(struct inode *inode, int mask)
{
- struct gfs2_ea_location el;
- struct posix_acl *acl = NULL;
+ struct posix_acl *acl;
int error;
- error = acl_get(GFS2_I(inode), GFS2_POSIX_ACL_ACCESS, &acl, &el, NULL, NULL);
- brelse(el.el_bh);
- if (error)
- return error;
+ acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
if (acl) {
error = posix_acl_permission(inode, acl, mask);
@@ -158,57 +93,75 @@ int gfs2_check_acl(struct inode *inode, int mask)
return -EAGAIN;
}
-static int munge_mode(struct gfs2_inode *ip, mode_t mode)
+static int gfs2_set_mode(struct inode *inode, mode_t mode)
{
- struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
- struct buffer_head *dibh;
- int error;
+ int error = 0;
- error = gfs2_trans_begin(sdp, RES_DINODE, 0);
- if (error)
- return error;
+ if (mode != inode->i_mode) {
+ struct iattr iattr;
- error = gfs2_meta_inode_buffer(ip, &dibh);
- if (!error) {
- gfs2_assert_withdraw(sdp,
- (ip->i_inode.i_mode & S_IFMT) == (mode & S_IFMT));
- ip->i_inode.i_mode = mode;
- gfs2_trans_add_bh(ip->i_gl, dibh, 1);
- gfs2_dinode_out(ip, dibh->b_data);
- brelse(dibh);
+ iattr.ia_valid = ATTR_MODE;
+ iattr.ia_mode = mode;
+
+ error = gfs2_setattr_simple(GFS2_I(inode), &iattr);
}
- gfs2_trans_end(sdp);
+ return error;
+}
+
+static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl)
+{
+ int error;
+ int len;
+ char *data;
+ const char *name = gfs2_acl_name(type);
- return 0;
+ BUG_ON(name == NULL);
+ len = posix_acl_to_xattr(acl, NULL, 0);
+ if (len == 0)
+ return 0;
+ data = kmalloc(len, GFP_NOFS);
+ if (data == NULL)
+ return -ENOMEM;
+ error = posix_acl_to_xattr(acl, data, len);
+ if (error < 0)
+ goto out;
+ error = gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, data, len, 0);
+ if (!error)
+ set_cached_acl(inode, type, acl);
+out:
+ kfree(data);
+ return error;
}
-int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
+int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode)
{
- struct gfs2_ea_location el;
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
- struct posix_acl *acl = NULL, *clone;
- mode_t mode = ip->i_inode.i_mode;
- char *data = NULL;
- unsigned int len;
- int error;
+ struct posix_acl *acl, *clone;
+ mode_t mode = inode->i_mode;
+ int error = 0;
if (!sdp->sd_args.ar_posix_acl)
return 0;
- if (S_ISLNK(ip->i_inode.i_mode))
+ if (S_ISLNK(inode->i_mode))
return 0;
- error = acl_get(dip, GFS2_POSIX_ACL_DEFAULT, &acl, &el, &data, &len);
- brelse(el.el_bh);
- if (error)
- return error;
+ acl = gfs2_acl_get(dip, ACL_TYPE_DEFAULT);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
if (!acl) {
mode &= ~current_umask();
- if (mode != ip->i_inode.i_mode)
- error = munge_mode(ip, mode);
+ if (mode != inode->i_mode)
+ error = gfs2_set_mode(inode, mode);
return error;
}
+ if (S_ISDIR(inode->i_mode)) {
+ error = gfs2_acl_set(inode, ACL_TYPE_DEFAULT, acl);
+ if (error)
+ goto out;
+ }
+
clone = posix_acl_clone(acl, GFP_NOFS);
error = -ENOMEM;
if (!clone)
@@ -216,43 +169,32 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
posix_acl_release(acl);
acl = clone;
- if (S_ISDIR(ip->i_inode.i_mode)) {
- error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS,
- GFS2_POSIX_ACL_DEFAULT, data, len, 0);
- if (error)
- goto out;
- }
-
error = posix_acl_create_masq(acl, &mode);
if (error < 0)
goto out;
if (error == 0)
goto munge;
- posix_acl_to_xattr(acl, data, len);
- error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS,
- GFS2_POSIX_ACL_ACCESS, data, len, 0);
+ error = gfs2_acl_set(inode, ACL_TYPE_ACCESS, acl);
if (error)
goto out;
munge:
- error = munge_mode(ip, mode);
+ error = gfs2_set_mode(inode, mode);
out:
posix_acl_release(acl);
- kfree(data);
return error;
}
int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
{
- struct posix_acl *acl = NULL, *clone;
- struct gfs2_ea_location el;
+ struct posix_acl *acl, *clone;
char *data;
unsigned int len;
int error;
- error = acl_get(ip, GFS2_POSIX_ACL_ACCESS, &acl, &el, &data, &len);
- if (error)
- goto out_brelse;
+ acl = gfs2_acl_get(ip, ACL_TYPE_ACCESS);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
if (!acl)
return gfs2_setattr_simple(ip, attr);
@@ -265,15 +207,134 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
error = posix_acl_chmod_masq(acl, attr->ia_mode);
if (!error) {
+ len = posix_acl_to_xattr(acl, NULL, 0);
+ data = kmalloc(len, GFP_NOFS);
+ error = -ENOMEM;
+ if (data == NULL)
+ goto out;
posix_acl_to_xattr(acl, data, len);
- error = gfs2_ea_acl_chmod(ip, &el, attr, data);
+ error = gfs2_xattr_acl_chmod(ip, attr, data);
+ kfree(data);
+ set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl);
}
out:
posix_acl_release(acl);
- kfree(data);
-out_brelse:
- brelse(el.el_bh);
return error;
}
+static int gfs2_acl_type(const char *name)
+{
+ if (strcmp(name, GFS2_POSIX_ACL_ACCESS) == 0)
+ return ACL_TYPE_ACCESS;
+ if (strcmp(name, GFS2_POSIX_ACL_DEFAULT) == 0)
+ return ACL_TYPE_DEFAULT;
+ return -EINVAL;
+}
+
+static int gfs2_xattr_system_get(struct inode *inode, const char *name,
+ void *buffer, size_t size)
+{
+ struct posix_acl *acl;
+ int type;
+ int error;
+
+ type = gfs2_acl_type(name);
+ if (type < 0)
+ return type;
+
+ acl = gfs2_acl_get(GFS2_I(inode), type);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ if (acl == NULL)
+ return -ENODATA;
+
+ error = posix_acl_to_xattr(acl, buffer, size);
+ posix_acl_release(acl);
+
+ return error;
+}
+
+static int gfs2_xattr_system_set(struct inode *inode, const char *name,
+ const void *value, size_t size, int flags)
+{
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
+ struct posix_acl *acl = NULL;
+ int error = 0, type;
+
+ if (!sdp->sd_args.ar_posix_acl)
+ return -EOPNOTSUPP;
+
+ type = gfs2_acl_type(name);
+ if (type < 0)
+ return type;
+ if (flags & XATTR_CREATE)
+ return -EINVAL;
+ if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
+ return value ? -EACCES : 0;
+ if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EPERM;
+ if (S_ISLNK(inode->i_mode))
+ return -EOPNOTSUPP;
+
+ if (!value)
+ goto set_acl;
+
+ acl = posix_acl_from_xattr(value, size);
+ if (!acl) {
+ /*
+ * acl_set_file(3) may request that we set default ACLs with
+ * zero length -- defend (gracefully) against that here.
+ */
+ goto out;
+ }
+ if (IS_ERR(acl)) {
+ error = PTR_ERR(acl);
+ goto out;
+ }
+
+ error = posix_acl_valid(acl);
+ if (error)
+ goto out_release;
+
+ error = -EINVAL;
+ if (acl->a_count > GFS2_ACL_MAX_ENTRIES)
+ goto out_release;
+
+ if (type == ACL_TYPE_ACCESS) {
+ mode_t mode = inode->i_mode;
+ error = posix_acl_equiv_mode(acl, &mode);
+
+ if (error <= 0) {
+ posix_acl_release(acl);
+ acl = NULL;
+
+ if (error < 0)
+ return error;
+ }
+
+ error = gfs2_set_mode(inode, mode);
+ if (error)
+ goto out_release;
+ }
+
+set_acl:
+ error = gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, 0);
+ if (!error) {
+ if (acl)
+ set_cached_acl(inode, type, acl);
+ else
+ forget_cached_acl(inode, type);
+ }
+out_release:
+ posix_acl_release(acl);
+out:
+ return error;
+}
+
+struct xattr_handler gfs2_xattr_system_handler = {
+ .prefix = XATTR_SYSTEM_PREFIX,
+ .get = gfs2_xattr_system_get,
+ .set = gfs2_xattr_system_set,
+};
+
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h
index 6751930bfb64..9306a2e6620c 100644
--- a/fs/gfs2/acl.h
+++ b/fs/gfs2/acl.h
@@ -13,26 +13,12 @@
#include "incore.h"
#define GFS2_POSIX_ACL_ACCESS "posix_acl_access"
-#define GFS2_POSIX_ACL_ACCESS_LEN 16
#define GFS2_POSIX_ACL_DEFAULT "posix_acl_default"
-#define GFS2_POSIX_ACL_DEFAULT_LEN 17
+#define GFS2_ACL_MAX_ENTRIES 25
-#define GFS2_ACL_IS_ACCESS(name, len) \
- ((len) == GFS2_POSIX_ACL_ACCESS_LEN && \
- !memcmp(GFS2_POSIX_ACL_ACCESS, (name), (len)))
-
-#define GFS2_ACL_IS_DEFAULT(name, len) \
- ((len) == GFS2_POSIX_ACL_DEFAULT_LEN && \
- !memcmp(GFS2_POSIX_ACL_DEFAULT, (name), (len)))
-
-struct gfs2_ea_request;
-
-int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
- struct gfs2_ea_request *er,
- int *remove, mode_t *mode);
-int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access);
-int gfs2_check_acl(struct inode *inode, int mask);
-int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip);
-int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
+extern int gfs2_check_acl(struct inode *inode, int mask);
+extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode);
+extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
+extern struct xattr_handler gfs2_xattr_system_handler;
#endif /* __ACL_DOT_H__ */
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 694b5d48f036..7b8da9415267 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -269,7 +269,6 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
unsigned offset = i_size & (PAGE_CACHE_SIZE-1);
unsigned nrblocks = nr_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize);
- struct backing_dev_info *bdi = mapping->backing_dev_info;
int i;
int ret;
@@ -313,11 +312,6 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
if (ret || (--(wbc->nr_to_write) <= 0))
ret = 1;
- if (wbc->nonblocking && bdi_write_congested(bdi)) {
- wbc->encountered_congestion = 1;
- ret = 1;
- }
-
}
gfs2_trans_end(sdp);
return ret;
@@ -338,7 +332,6 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
static int gfs2_write_cache_jdata(struct address_space *mapping,
struct writeback_control *wbc)
{
- struct backing_dev_info *bdi = mapping->backing_dev_info;
int ret = 0;
int done = 0;
struct pagevec pvec;
@@ -348,11 +341,6 @@ static int gfs2_write_cache_jdata(struct address_space *mapping,
int scanned = 0;
int range_whole = 0;
- if (wbc->nonblocking && bdi_write_congested(bdi)) {
- wbc->encountered_congestion = 1;
- return 0;
- }
-
pagevec_init(&pvec, 0);
if (wbc->range_cyclic) {
index = mapping->writeback_index; /* Start from prev offset */
@@ -819,8 +807,10 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
mark_inode_dirty(inode);
}
- if (inode == sdp->sd_rindex)
+ if (inode == sdp->sd_rindex) {
adjust_fs_space(inode);
+ ip->i_gh.gh_flags |= GL_NOCACHE;
+ }
brelse(dibh);
gfs2_trans_end(sdp);
@@ -889,8 +879,10 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
mark_inode_dirty(inode);
}
- if (inode == sdp->sd_rindex)
+ if (inode == sdp->sd_rindex) {
adjust_fs_space(inode);
+ ip->i_gh.gh_flags |= GL_NOCACHE;
+ }
brelse(dibh);
gfs2_trans_end(sdp);
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 297d7e5cebad..25fddc100f18 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -525,38 +525,6 @@ consist_inode:
return ERR_PTR(-EIO);
}
-
-/**
- * dirent_first - Return the first dirent
- * @dip: the directory
- * @bh: The buffer
- * @dent: Pointer to list of dirents
- *
- * return first dirent whether bh points to leaf or stuffed dinode
- *
- * Returns: IS_LEAF, IS_DINODE, or -errno
- */
-
-static int dirent_first(struct gfs2_inode *dip, struct buffer_head *bh,
- struct gfs2_dirent **dent)
-{
- struct gfs2_meta_header *h = (struct gfs2_meta_header *)bh->b_data;
-
- if (be32_to_cpu(h->mh_type) == GFS2_METATYPE_LF) {
- if (gfs2_meta_check(GFS2_SB(&dip->i_inode), bh))
- return -EIO;
- *dent = (struct gfs2_dirent *)(bh->b_data +
- sizeof(struct gfs2_leaf));
- return IS_LEAF;
- } else {
- if (gfs2_metatype_check(GFS2_SB(&dip->i_inode), bh, GFS2_METATYPE_DI))
- return -EIO;
- *dent = (struct gfs2_dirent *)(bh->b_data +
- sizeof(struct gfs2_dinode));
- return IS_DINODE;
- }
-}
-
static int dirent_check_reclen(struct gfs2_inode *dip,
const struct gfs2_dirent *d, const void *end_p)
{
@@ -1006,7 +974,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
divider = (start + half_len) << (32 - dip->i_depth);
/* Copy the entries */
- dirent_first(dip, obh, &dent);
+ dent = (struct gfs2_dirent *)(obh->b_data + sizeof(struct gfs2_leaf));
do {
next = dent;
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 8b674b1f3a55..f455a03a09e2 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -241,15 +241,14 @@ int gfs2_glock_put(struct gfs2_glock *gl)
int rv = 0;
write_lock(gl_lock_addr(gl->gl_hash));
- if (atomic_dec_and_test(&gl->gl_ref)) {
+ if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) {
hlist_del(&gl->gl_list);
- write_unlock(gl_lock_addr(gl->gl_hash));
- spin_lock(&lru_lock);
if (!list_empty(&gl->gl_lru)) {
list_del_init(&gl->gl_lru);
atomic_dec(&lru_count);
}
spin_unlock(&lru_lock);
+ write_unlock(gl_lock_addr(gl->gl_hash));
GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
glock_free(gl);
rv = 1;
@@ -513,7 +512,6 @@ retry:
GLOCK_BUG_ON(gl, 1);
}
spin_unlock(&gl->gl_spin);
- gfs2_glock_put(gl);
return;
}
@@ -524,8 +522,6 @@ retry:
if (glops->go_xmote_bh) {
spin_unlock(&gl->gl_spin);
rv = glops->go_xmote_bh(gl, gh);
- if (rv == -EAGAIN)
- return;
spin_lock(&gl->gl_spin);
if (rv) {
do_error(gl, rv);
@@ -540,7 +536,6 @@ out:
clear_bit(GLF_LOCK, &gl->gl_flags);
out_locked:
spin_unlock(&gl->gl_spin);
- gfs2_glock_put(gl);
}
static unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock,
@@ -600,7 +595,6 @@ __acquires(&gl->gl_spin)
if (!(ret & LM_OUT_ASYNC)) {
finish_xmote(gl, ret);
- gfs2_glock_hold(gl);
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
gfs2_glock_put(gl);
} else {
@@ -672,12 +666,17 @@ out:
return;
out_sched:
+ clear_bit(GLF_LOCK, &gl->gl_flags);
+ smp_mb__after_clear_bit();
gfs2_glock_hold(gl);
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
gfs2_glock_put_nolock(gl);
+ return;
+
out_unlock:
clear_bit(GLF_LOCK, &gl->gl_flags);
- goto out;
+ smp_mb__after_clear_bit();
+ return;
}
static void delete_work_func(struct work_struct *work)
@@ -707,9 +706,12 @@ static void glock_work_func(struct work_struct *work)
{
unsigned long delay = 0;
struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work);
+ int drop_ref = 0;
- if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags))
+ if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) {
finish_xmote(gl, gl->gl_reply);
+ drop_ref = 1;
+ }
down_read(&gfs2_umount_flush_sem);
spin_lock(&gl->gl_spin);
if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
@@ -727,6 +729,8 @@ static void glock_work_func(struct work_struct *work)
if (!delay ||
queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
gfs2_glock_put(gl);
+ if (drop_ref)
+ gfs2_glock_put(gl);
}
/**
@@ -1361,10 +1365,6 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask)
list_del_init(&gl->gl_lru);
atomic_dec(&lru_count);
- /* Check if glock is about to be freed */
- if (atomic_read(&gl->gl_ref) == 0)
- continue;
-
/* Test for being demotable */
if (!test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
gfs2_glock_hold(gl);
@@ -1375,10 +1375,11 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask)
handle_callback(gl, LM_ST_UNLOCKED, 0);
nr--;
}
+ clear_bit(GLF_LOCK, &gl->gl_flags);
+ smp_mb__after_clear_bit();
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
gfs2_glock_put_nolock(gl);
spin_unlock(&gl->gl_spin);
- clear_bit(GLF_LOCK, &gl->gl_flags);
spin_lock(&lru_lock);
continue;
}
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index c609894ec0d0..13f0bd228132 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -180,15 +180,6 @@ static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl)
return gl->gl_state == LM_ST_SHARED;
}
-static inline int gfs2_glock_is_blocking(struct gfs2_glock *gl)
-{
- int ret;
- spin_lock(&gl->gl_spin);
- ret = test_bit(GLF_DEMOTE, &gl->gl_flags);
- spin_unlock(&gl->gl_spin);
- return ret;
-}
-
int gfs2_glock_get(struct gfs2_sbd *sdp,
u64 number, const struct gfs2_glock_operations *glops,
int create, struct gfs2_glock **glp);
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 6985eef06c39..78554acc0605 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -13,6 +13,7 @@
#include <linux/buffer_head.h>
#include <linux/gfs2_ondisk.h>
#include <linux/bio.h>
+#include <linux/posix_acl.h>
#include "gfs2.h"
#include "incore.h"
@@ -184,8 +185,10 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
if (flags & DIO_METADATA) {
struct address_space *mapping = gl->gl_aspace->i_mapping;
truncate_inode_pages(mapping, 0);
- if (ip)
+ if (ip) {
set_bit(GIF_INVALID, &ip->i_flags);
+ forget_all_cached_acls(&ip->i_inode);
+ }
}
if (ip == GFS2_I(gl->gl_sbd->sd_rindex))
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 6edb423f90b3..4792200978c8 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -429,7 +429,11 @@ struct gfs2_args {
unsigned int ar_meta:1; /* mount metafs */
unsigned int ar_discard:1; /* discard requests */
unsigned int ar_errors:2; /* errors=withdraw | panic */
+ unsigned int ar_nobarrier:1; /* do not send barriers */
int ar_commit; /* Commit interval */
+ int ar_statfs_quantum; /* The fast statfs interval */
+ int ar_quota_quantum; /* The quota interval */
+ int ar_statfs_percent; /* The % change to force sync */
};
struct gfs2_tune {
@@ -558,6 +562,7 @@ struct gfs2_sbd {
spinlock_t sd_statfs_spin;
struct gfs2_statfs_change_host sd_statfs_master;
struct gfs2_statfs_change_host sd_statfs_local;
+ int sd_statfs_force_sync;
/* Resource group stuff */
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index fb15d3b1f409..26ba2a4c4a2d 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -871,7 +871,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
if (error)
goto fail_gunlock2;
- error = gfs2_acl_create(dip, GFS2_I(inode));
+ error = gfs2_acl_create(dip, inode);
if (error)
goto fail_gunlock2;
@@ -947,9 +947,7 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI);
- str->di_header.__pad0 = 0;
str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI);
- str->di_header.__pad1 = 0;
str->di_num.no_addr = cpu_to_be64(ip->i_no_addr);
str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 13c6237c5f67..4511b08fc451 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -596,7 +596,9 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
memset(lh, 0, sizeof(struct gfs2_log_header));
lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
+ lh->lh_header.__pad0 = cpu_to_be64(0);
lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
+ lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++);
lh->lh_flags = cpu_to_be32(flags);
lh->lh_tail = cpu_to_be32(tail);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 9969ff062c5b..de97632ba32f 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -132,6 +132,7 @@ static struct buffer_head *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
{
struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
+ struct gfs2_meta_header *mh;
struct gfs2_trans *tr;
lock_buffer(bd->bd_bh);
@@ -148,6 +149,9 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
gfs2_meta_check(sdp, bd->bd_bh);
gfs2_pin(sdp, bd->bd_bh);
+ mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
+ mh->__pad0 = cpu_to_be64(0);
+ mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
sdp->sd_log_num_buf++;
list_add(&le->le_list, &sdp->sd_log_le_buf);
tr->tr_num_buf_new++;
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index eacd78a5d082..5b31f7741a8f 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -114,7 +114,7 @@ static int __init init_gfs2_fs(void)
if (error)
goto fail_unregister;
- error = slow_work_register_user();
+ error = slow_work_register_user(THIS_MODULE);
if (error)
goto fail_slow;
@@ -163,7 +163,7 @@ static void __exit exit_gfs2_fs(void)
gfs2_unregister_debugfs();
unregister_filesystem(&gfs2_fs_type);
unregister_filesystem(&gfs2meta_fs_type);
- slow_work_unregister_user();
+ slow_work_unregister_user(THIS_MODULE);
kmem_cache_destroy(gfs2_quotad_cachep);
kmem_cache_destroy(gfs2_rgrpd_cachep);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 52fb6c048981..edfee24f3636 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -18,6 +18,7 @@
#include <linux/mount.h>
#include <linux/gfs2_ondisk.h>
#include <linux/slow-work.h>
+#include <linux/quotaops.h>
#include "gfs2.h"
#include "incore.h"
@@ -62,13 +63,10 @@ static void gfs2_tune_init(struct gfs2_tune *gt)
gt->gt_quota_warn_period = 10;
gt->gt_quota_scale_num = 1;
gt->gt_quota_scale_den = 1;
- gt->gt_quota_quantum = 60;
gt->gt_new_files_jdata = 0;
gt->gt_max_readahead = 1 << 18;
gt->gt_stall_secs = 600;
gt->gt_complain_secs = 10;
- gt->gt_statfs_quantum = 30;
- gt->gt_statfs_slow = 0;
}
static struct gfs2_sbd *init_sbd(struct super_block *sb)
@@ -1114,7 +1112,7 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp)
* Returns: errno
*/
-static int fill_super(struct super_block *sb, void *data, int silent)
+static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent)
{
struct gfs2_sbd *sdp;
struct gfs2_holder mount_gh;
@@ -1125,17 +1123,7 @@ static int fill_super(struct super_block *sb, void *data, int silent)
printk(KERN_WARNING "GFS2: can't alloc struct gfs2_sbd\n");
return -ENOMEM;
}
-
- sdp->sd_args.ar_quota = GFS2_QUOTA_DEFAULT;
- sdp->sd_args.ar_data = GFS2_DATA_DEFAULT;
- sdp->sd_args.ar_commit = 60;
- sdp->sd_args.ar_errors = GFS2_ERRORS_DEFAULT;
-
- error = gfs2_mount_args(sdp, &sdp->sd_args, data);
- if (error) {
- printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
- goto fail;
- }
+ sdp->sd_args = *args;
if (sdp->sd_args.ar_spectator) {
sb->s_flags |= MS_RDONLY;
@@ -1143,11 +1131,15 @@ static int fill_super(struct super_block *sb, void *data, int silent)
}
if (sdp->sd_args.ar_posix_acl)
sb->s_flags |= MS_POSIXACL;
+ if (sdp->sd_args.ar_nobarrier)
+ set_bit(SDF_NOBARRIERS, &sdp->sd_flags);
sb->s_magic = GFS2_MAGIC;
sb->s_op = &gfs2_super_ops;
sb->s_export_op = &gfs2_export_ops;
sb->s_xattr = gfs2_xattr_handlers;
+ sb->s_qcop = &gfs2_quotactl_ops;
+ sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
sb->s_time_gran = 1;
sb->s_maxbytes = MAX_LFS_FILESIZE;
@@ -1160,6 +1152,15 @@ static int fill_super(struct super_block *sb, void *data, int silent)
sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
sdp->sd_tune.gt_log_flush_secs = sdp->sd_args.ar_commit;
+ sdp->sd_tune.gt_quota_quantum = sdp->sd_args.ar_quota_quantum;
+ if (sdp->sd_args.ar_statfs_quantum) {
+ sdp->sd_tune.gt_statfs_slow = 0;
+ sdp->sd_tune.gt_statfs_quantum = sdp->sd_args.ar_statfs_quantum;
+ }
+ else {
+ sdp->sd_tune.gt_statfs_slow = 1;
+ sdp->sd_tune.gt_statfs_quantum = 30;
+ }
error = init_names(sdp, silent);
if (error)
@@ -1243,18 +1244,127 @@ fail:
return error;
}
-static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *data, struct vfsmount *mnt)
+static int set_gfs2_super(struct super_block *s, void *data)
{
- return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt);
+ s->s_bdev = data;
+ s->s_dev = s->s_bdev->bd_dev;
+
+ /*
+ * We set the bdi here to the queue backing, file systems can
+ * overwrite this in ->fill_super()
+ */
+ s->s_bdi = &bdev_get_queue(s->s_bdev)->backing_dev_info;
+ return 0;
}
-static int test_meta_super(struct super_block *s, void *ptr)
+static int test_gfs2_super(struct super_block *s, void *ptr)
{
struct block_device *bdev = ptr;
return (bdev == s->s_bdev);
}
+/**
+ * gfs2_get_sb - Get the GFS2 superblock
+ * @fs_type: The GFS2 filesystem type
+ * @flags: Mount flags
+ * @dev_name: The name of the device
+ * @data: The mount arguments
+ * @mnt: The vfsmnt for this mount
+ *
+ * Q. Why not use get_sb_bdev() ?
+ * A. We need to select one of two root directories to mount, independent
+ * of whether this is the initial, or subsequent, mount of this sb
+ *
+ * Returns: 0 or -ve on error
+ */
+
+static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data, struct vfsmount *mnt)
+{
+ struct block_device *bdev;
+ struct super_block *s;
+ fmode_t mode = FMODE_READ;
+ int error;
+ struct gfs2_args args;
+ struct gfs2_sbd *sdp;
+
+ if (!(flags & MS_RDONLY))
+ mode |= FMODE_WRITE;
+
+ bdev = open_bdev_exclusive(dev_name, mode, fs_type);
+ if (IS_ERR(bdev))
+ return PTR_ERR(bdev);
+
+ /*
+ * once the super is inserted into the list by sget, s_umount
+ * will protect the lockfs code from trying to start a snapshot
+ * while we are mounting
+ */
+ mutex_lock(&bdev->bd_fsfreeze_mutex);
+ if (bdev->bd_fsfreeze_count > 0) {
+ mutex_unlock(&bdev->bd_fsfreeze_mutex);
+ error = -EBUSY;
+ goto error_bdev;
+ }
+ s = sget(fs_type, test_gfs2_super, set_gfs2_super, bdev);
+ mutex_unlock(&bdev->bd_fsfreeze_mutex);
+ error = PTR_ERR(s);
+ if (IS_ERR(s))
+ goto error_bdev;
+
+ memset(&args, 0, sizeof(args));
+ args.ar_quota = GFS2_QUOTA_DEFAULT;
+ args.ar_data = GFS2_DATA_DEFAULT;
+ args.ar_commit = 60;
+ args.ar_statfs_quantum = 30;
+ args.ar_quota_quantum = 60;
+ args.ar_errors = GFS2_ERRORS_DEFAULT;
+
+ error = gfs2_mount_args(&args, data);
+ if (error) {
+ printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
+ if (s->s_root)
+ goto error_super;
+ deactivate_locked_super(s);
+ return error;
+ }
+
+ if (s->s_root) {
+ error = -EBUSY;
+ if ((flags ^ s->s_flags) & MS_RDONLY)
+ goto error_super;
+ close_bdev_exclusive(bdev, mode);
+ } else {
+ char b[BDEVNAME_SIZE];
+
+ s->s_flags = flags;
+ s->s_mode = mode;
+ strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+ sb_set_blocksize(s, block_size(bdev));
+ error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0);
+ if (error) {
+ deactivate_locked_super(s);
+ return error;
+ }
+ s->s_flags |= MS_ACTIVE;
+ bdev->bd_super = s;
+ }
+
+ sdp = s->s_fs_info;
+ mnt->mnt_sb = s;
+ if (args.ar_meta)
+ mnt->mnt_root = dget(sdp->sd_master_dir);
+ else
+ mnt->mnt_root = dget(sdp->sd_root_dir);
+ return 0;
+
+error_super:
+ deactivate_locked_super(s);
+error_bdev:
+ close_bdev_exclusive(bdev, mode);
+ return error;
+}
+
static int set_meta_super(struct super_block *s, void *ptr)
{
return -EINVAL;
@@ -1274,13 +1384,17 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
dev_name, error);
return error;
}
- s = sget(&gfs2_fs_type, test_meta_super, set_meta_super,
+ s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super,
path.dentry->d_inode->i_sb->s_bdev);
path_put(&path);
if (IS_ERR(s)) {
printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
return PTR_ERR(s);
}
+ if ((flags ^ s->s_flags) & MS_RDONLY) {
+ deactivate_locked_super(s);
+ return -EBUSY;
+ }
sdp = s->s_fs_info;
mnt->mnt_sb = s;
mnt->mnt_root = dget(sdp->sd_master_dir);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 2e9b9326bfc9..e3bf6eab8750 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -15,7 +15,7 @@
* fuzziness in the current usage value of IDs that are being used on different
* nodes in the cluster simultaneously. So, it is possible for a user on
* multiple nodes to overrun their quota, but that overrun is controlable.
- * Since quota tags are part of transactions, there is no need to a quota check
+ * Since quota tags are part of transactions, there is no need for a quota check
* program to be run on node crashes or anything like that.
*
* There are couple of knobs that let the administrator manage the quota
@@ -47,6 +47,8 @@
#include <linux/gfs2_ondisk.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/quota.h>
+#include <linux/dqblk_xfs.h>
#include "gfs2.h"
#include "incore.h"
@@ -65,13 +67,6 @@
#define QUOTA_USER 1
#define QUOTA_GROUP 0
-struct gfs2_quota_host {
- u64 qu_limit;
- u64 qu_warn;
- s64 qu_value;
- u32 qu_ll_next;
-};
-
struct gfs2_quota_change_host {
u64 qc_change;
u32 qc_flags; /* GFS2_QCF_... */
@@ -164,7 +159,7 @@ fail:
return error;
}
-static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
+static int qd_get(struct gfs2_sbd *sdp, int user, u32 id,
struct gfs2_quota_data **qdp)
{
struct gfs2_quota_data *qd = NULL, *new_qd = NULL;
@@ -202,7 +197,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
spin_unlock(&qd_lru_lock);
- if (qd || !create) {
+ if (qd) {
if (new_qd) {
gfs2_glock_put(new_qd->qd_gl);
kmem_cache_free(gfs2_quotad_cachep, new_qd);
@@ -461,12 +456,12 @@ static void qd_unlock(struct gfs2_quota_data *qd)
qd_put(qd);
}
-static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
+static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id,
struct gfs2_quota_data **qdp)
{
int error;
- error = qd_get(sdp, user, id, create, qdp);
+ error = qd_get(sdp, user, id, qdp);
if (error)
return error;
@@ -508,20 +503,20 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
return 0;
- error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, CREATE, qd);
+ error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd);
if (error)
goto out;
al->al_qd_num++;
qd++;
- error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, CREATE, qd);
+ error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd);
if (error)
goto out;
al->al_qd_num++;
qd++;
if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) {
- error = qdsb_get(sdp, QUOTA_USER, uid, CREATE, qd);
+ error = qdsb_get(sdp, QUOTA_USER, uid, qd);
if (error)
goto out;
al->al_qd_num++;
@@ -529,7 +524,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
}
if (gid != NO_QUOTA_CHANGE && gid != ip->i_inode.i_gid) {
- error = qdsb_get(sdp, QUOTA_GROUP, gid, CREATE, qd);
+ error = qdsb_get(sdp, QUOTA_GROUP, gid, qd);
if (error)
goto out;
al->al_qd_num++;
@@ -617,48 +612,36 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
mutex_unlock(&sdp->sd_quota_mutex);
}
-static void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf)
-{
- const struct gfs2_quota *str = buf;
-
- qu->qu_limit = be64_to_cpu(str->qu_limit);
- qu->qu_warn = be64_to_cpu(str->qu_warn);
- qu->qu_value = be64_to_cpu(str->qu_value);
- qu->qu_ll_next = be32_to_cpu(str->qu_ll_next);
-}
-
-static void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf)
-{
- struct gfs2_quota *str = buf;
-
- str->qu_limit = cpu_to_be64(qu->qu_limit);
- str->qu_warn = cpu_to_be64(qu->qu_warn);
- str->qu_value = cpu_to_be64(qu->qu_value);
- str->qu_ll_next = cpu_to_be32(qu->qu_ll_next);
- memset(&str->qu_reserved, 0, sizeof(str->qu_reserved));
-}
-
/**
- * gfs2_adjust_quota
+ * gfs2_adjust_quota - adjust record of current block usage
+ * @ip: The quota inode
+ * @loc: Offset of the entry in the quota file
+ * @change: The amount of usage change to record
+ * @qd: The quota data
+ * @fdq: The updated limits to record
*
* This function was mostly borrowed from gfs2_block_truncate_page which was
* in turn mostly borrowed from ext3
+ *
+ * Returns: 0 or -ve on error
*/
+
static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
- s64 change, struct gfs2_quota_data *qd)
+ s64 change, struct gfs2_quota_data *qd,
+ struct fs_disk_quota *fdq)
{
struct inode *inode = &ip->i_inode;
struct address_space *mapping = inode->i_mapping;
unsigned long index = loc >> PAGE_CACHE_SHIFT;
unsigned offset = loc & (PAGE_CACHE_SIZE - 1);
unsigned blocksize, iblock, pos;
- struct buffer_head *bh;
+ struct buffer_head *bh, *dibh;
struct page *page;
void *kaddr;
- char *ptr;
- struct gfs2_quota_host qp;
+ struct gfs2_quota *qp;
s64 value;
int err = -EIO;
+ u64 size;
if (gfs2_is_stuffed(ip))
gfs2_unstuff_dinode(ip, NULL);
@@ -700,18 +683,38 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
gfs2_trans_add_bh(ip->i_gl, bh, 0);
kaddr = kmap_atomic(page, KM_USER0);
- ptr = kaddr + offset;
- gfs2_quota_in(&qp, ptr);
- qp.qu_value += change;
- value = qp.qu_value;
- gfs2_quota_out(&qp, ptr);
+ qp = kaddr + offset;
+ value = (s64)be64_to_cpu(qp->qu_value) + change;
+ qp->qu_value = cpu_to_be64(value);
+ qd->qd_qb.qb_value = qp->qu_value;
+ if (fdq) {
+ if (fdq->d_fieldmask & FS_DQ_BSOFT) {
+ qp->qu_warn = cpu_to_be64(fdq->d_blk_softlimit);
+ qd->qd_qb.qb_warn = qp->qu_warn;
+ }
+ if (fdq->d_fieldmask & FS_DQ_BHARD) {
+ qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit);
+ qd->qd_qb.qb_limit = qp->qu_limit;
+ }
+ }
flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);
- err = 0;
- qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC);
- qd->qd_qb.qb_value = cpu_to_be64(value);
- ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_magic = cpu_to_be32(GFS2_MAGIC);
- ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_value = cpu_to_be64(value);
+
+ err = gfs2_meta_inode_buffer(ip, &dibh);
+ if (err)
+ goto unlock;
+
+ size = loc + sizeof(struct gfs2_quota);
+ if (size > inode->i_size) {
+ ip->i_disksize = size;
+ i_size_write(inode, size);
+ }
+ inode->i_mtime = inode->i_atime = CURRENT_TIME;
+ gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+ gfs2_dinode_out(ip, dibh->b_data);
+ brelse(dibh);
+ mark_inode_dirty(inode);
+
unlock:
unlock_page(page);
page_cache_release(page);
@@ -739,9 +742,9 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
return -ENOMEM;
sort(qda, num_qd, sizeof(struct gfs2_quota_data *), sort_qd, NULL);
+ mutex_lock_nested(&ip->i_inode.i_mutex, I_MUTEX_QUOTA);
for (qx = 0; qx < num_qd; qx++) {
- error = gfs2_glock_nq_init(qda[qx]->qd_gl,
- LM_ST_EXCLUSIVE,
+ error = gfs2_glock_nq_init(qda[qx]->qd_gl, LM_ST_EXCLUSIVE,
GL_NOCACHE, &ghs[qx]);
if (error)
goto out;
@@ -795,9 +798,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
for (x = 0; x < num_qd; x++) {
qd = qda[x];
offset = qd2offset(qd);
- error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync,
- (struct gfs2_quota_data *)
- qd);
+ error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync, qd, NULL);
if (error)
goto out_end_trans;
@@ -817,21 +818,44 @@ out_gunlock:
out:
while (qx--)
gfs2_glock_dq_uninit(&ghs[qx]);
+ mutex_unlock(&ip->i_inode.i_mutex);
kfree(ghs);
gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
return error;
}
+static int update_qd(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd)
+{
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
+ struct gfs2_quota q;
+ struct gfs2_quota_lvb *qlvb;
+ loff_t pos;
+ int error;
+
+ memset(&q, 0, sizeof(struct gfs2_quota));
+ pos = qd2offset(qd);
+ error = gfs2_internal_read(ip, NULL, (char *)&q, &pos, sizeof(q));
+ if (error < 0)
+ return error;
+
+ qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
+ qlvb->qb_magic = cpu_to_be32(GFS2_MAGIC);
+ qlvb->__pad = 0;
+ qlvb->qb_limit = q.qu_limit;
+ qlvb->qb_warn = q.qu_warn;
+ qlvb->qb_value = q.qu_value;
+ qd->qd_qb = *qlvb;
+
+ return 0;
+}
+
static int do_glock(struct gfs2_quota_data *qd, int force_refresh,
struct gfs2_holder *q_gh)
{
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
struct gfs2_holder i_gh;
- struct gfs2_quota_host q;
- char buf[sizeof(struct gfs2_quota)];
int error;
- struct gfs2_quota_lvb *qlvb;
restart:
error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_SHARED, 0, q_gh);
@@ -841,11 +865,9 @@ restart:
qd->qd_qb = *(struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
if (force_refresh || qd->qd_qb.qb_magic != cpu_to_be32(GFS2_MAGIC)) {
- loff_t pos;
gfs2_glock_dq_uninit(q_gh);
- error = gfs2_glock_nq_init(qd->qd_gl,
- LM_ST_EXCLUSIVE, GL_NOCACHE,
- q_gh);
+ error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE,
+ GL_NOCACHE, q_gh);
if (error)
return error;
@@ -853,29 +875,14 @@ restart:
if (error)
goto fail;
- memset(buf, 0, sizeof(struct gfs2_quota));
- pos = qd2offset(qd);
- error = gfs2_internal_read(ip, NULL, buf, &pos,
- sizeof(struct gfs2_quota));
- if (error < 0)
+ error = update_qd(sdp, qd);
+ if (error)
goto fail_gunlock;
gfs2_glock_dq_uninit(&i_gh);
-
- gfs2_quota_in(&q, buf);
- qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
- qlvb->qb_magic = cpu_to_be32(GFS2_MAGIC);
- qlvb->__pad = 0;
- qlvb->qb_limit = cpu_to_be64(q.qu_limit);
- qlvb->qb_warn = cpu_to_be64(q.qu_warn);
- qlvb->qb_value = cpu_to_be64(q.qu_value);
- qd->qd_qb = *qlvb;
-
- if (gfs2_glock_is_blocking(qd->qd_gl)) {
- gfs2_glock_dq_uninit(q_gh);
- force_refresh = 0;
- goto restart;
- }
+ gfs2_glock_dq_uninit(q_gh);
+ force_refresh = 0;
+ goto restart;
}
return 0;
@@ -995,7 +1002,7 @@ static int print_message(struct gfs2_quota_data *qd, char *type)
{
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
- printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\r\n",
+ printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\n",
sdp->sd_fsname, type,
(test_bit(QDF_USER, &qd->qd_flags)) ? "user" : "group",
qd->qd_id);
@@ -1032,6 +1039,10 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) {
print_message(qd, "exceeded");
+ quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ?
+ USRQUOTA : GRPQUOTA, qd->qd_id,
+ sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN);
+
error = -EDQUOT;
break;
} else if (be64_to_cpu(qd->qd_qb.qb_warn) &&
@@ -1039,6 +1050,9 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
time_after_eq(jiffies, qd->qd_last_warn +
gfs2_tune_get(sdp,
gt_quota_warn_period) * HZ)) {
+ quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ?
+ USRQUOTA : GRPQUOTA, qd->qd_id,
+ sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN);
error = print_message(qd, "warning");
qd->qd_last_warn = jiffies;
}
@@ -1069,8 +1083,9 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
}
}
-int gfs2_quota_sync(struct gfs2_sbd *sdp)
+int gfs2_quota_sync(struct super_block *sb, int type)
{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
struct gfs2_quota_data **qda;
unsigned int max_qd = gfs2_tune_get(sdp, gt_quota_simul_sync);
unsigned int num_qd;
@@ -1118,7 +1133,7 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
struct gfs2_holder q_gh;
int error;
- error = qd_get(sdp, user, id, CREATE, &qd);
+ error = qd_get(sdp, user, id, &qd);
if (error)
return error;
@@ -1127,7 +1142,6 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
gfs2_glock_dq_uninit(&q_gh);
qd_put(qd);
-
return error;
}
@@ -1298,12 +1312,12 @@ static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error)
}
static void quotad_check_timeo(struct gfs2_sbd *sdp, const char *msg,
- int (*fxn)(struct gfs2_sbd *sdp),
+ int (*fxn)(struct super_block *sb, int type),
unsigned long t, unsigned long *timeo,
unsigned int *new_timeo)
{
if (t >= *timeo) {
- int error = fxn(sdp);
+ int error = fxn(sdp->sd_vfs, 0);
quotad_error(sdp, msg, error);
*timeo = gfs2_tune_get_i(&sdp->sd_tune, new_timeo) * HZ;
} else {
@@ -1330,6 +1344,14 @@ static void quotad_check_trunc_list(struct gfs2_sbd *sdp)
}
}
+void gfs2_wake_up_statfs(struct gfs2_sbd *sdp) {
+ if (!sdp->sd_statfs_force_sync) {
+ sdp->sd_statfs_force_sync = 1;
+ wake_up(&sdp->sd_quota_wait);
+ }
+}
+
+
/**
* gfs2_quotad - Write cached quota changes into the quota file
* @sdp: Pointer to GFS2 superblock
@@ -1349,8 +1371,15 @@ int gfs2_quotad(void *data)
while (!kthread_should_stop()) {
/* Update the master statfs file */
- quotad_check_timeo(sdp, "statfs", gfs2_statfs_sync, t,
- &statfs_timeo, &tune->gt_statfs_quantum);
+ if (sdp->sd_statfs_force_sync) {
+ int error = gfs2_statfs_sync(sdp->sd_vfs, 0);
+ quotad_error(sdp, "statfs", error);
+ statfs_timeo = gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
+ }
+ else
+ quotad_check_timeo(sdp, "statfs", gfs2_statfs_sync, t,
+ &statfs_timeo,
+ &tune->gt_statfs_quantum);
/* Update quota file */
quotad_check_timeo(sdp, "sync", gfs2_quota_sync, t,
@@ -1367,7 +1396,7 @@ int gfs2_quotad(void *data)
spin_lock(&sdp->sd_trunc_lock);
empty = list_empty(&sdp->sd_trunc_list);
spin_unlock(&sdp->sd_trunc_lock);
- if (empty)
+ if (empty && !sdp->sd_statfs_force_sync)
t -= schedule_timeout(t);
else
t = 0;
@@ -1377,3 +1406,181 @@ int gfs2_quotad(void *data)
return 0;
}
+static int gfs2_quota_get_xstate(struct super_block *sb,
+ struct fs_quota_stat *fqs)
+{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
+
+ memset(fqs, 0, sizeof(struct fs_quota_stat));
+ fqs->qs_version = FS_QSTAT_VERSION;
+ if (sdp->sd_args.ar_quota == GFS2_QUOTA_ON)
+ fqs->qs_flags = (XFS_QUOTA_UDQ_ENFD | XFS_QUOTA_GDQ_ENFD);
+ else if (sdp->sd_args.ar_quota == GFS2_QUOTA_ACCOUNT)
+ fqs->qs_flags = (XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_GDQ_ACCT);
+ if (sdp->sd_quota_inode) {
+ fqs->qs_uquota.qfs_ino = GFS2_I(sdp->sd_quota_inode)->i_no_addr;
+ fqs->qs_uquota.qfs_nblks = sdp->sd_quota_inode->i_blocks;
+ }
+ fqs->qs_uquota.qfs_nextents = 1; /* unsupported */
+ fqs->qs_gquota = fqs->qs_uquota; /* its the same inode in both cases */
+ fqs->qs_incoredqs = atomic_read(&qd_lru_count);
+ return 0;
+}
+
+static int gfs2_xquota_get(struct super_block *sb, int type, qid_t id,
+ struct fs_disk_quota *fdq)
+{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
+ struct gfs2_quota_lvb *qlvb;
+ struct gfs2_quota_data *qd;
+ struct gfs2_holder q_gh;
+ int error;
+
+ memset(fdq, 0, sizeof(struct fs_disk_quota));
+
+ if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
+ return -ESRCH; /* Crazy XFS error code */
+
+ if (type == USRQUOTA)
+ type = QUOTA_USER;
+ else if (type == GRPQUOTA)
+ type = QUOTA_GROUP;
+ else
+ return -EINVAL;
+
+ error = qd_get(sdp, type, id, &qd);
+ if (error)
+ return error;
+ error = do_glock(qd, FORCE, &q_gh);
+ if (error)
+ goto out;
+
+ qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
+ fdq->d_version = FS_DQUOT_VERSION;
+ fdq->d_flags = (type == QUOTA_USER) ? XFS_USER_QUOTA : XFS_GROUP_QUOTA;
+ fdq->d_id = id;
+ fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit);
+ fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn);
+ fdq->d_bcount = be64_to_cpu(qlvb->qb_value);
+
+ gfs2_glock_dq_uninit(&q_gh);
+out:
+ qd_put(qd);
+ return error;
+}
+
+/* GFS2 only supports a subset of the XFS fields */
+#define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD)
+
+static int gfs2_xquota_set(struct super_block *sb, int type, qid_t id,
+ struct fs_disk_quota *fdq)
+{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
+ struct gfs2_quota_data *qd;
+ struct gfs2_holder q_gh, i_gh;
+ unsigned int data_blocks, ind_blocks;
+ unsigned int blocks = 0;
+ int alloc_required;
+ struct gfs2_alloc *al;
+ loff_t offset;
+ int error;
+
+ if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
+ return -ESRCH; /* Crazy XFS error code */
+
+ switch(type) {
+ case USRQUOTA:
+ type = QUOTA_USER;
+ if (fdq->d_flags != XFS_USER_QUOTA)
+ return -EINVAL;
+ break;
+ case GRPQUOTA:
+ type = QUOTA_GROUP;
+ if (fdq->d_flags != XFS_GROUP_QUOTA)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (fdq->d_fieldmask & ~GFS2_FIELDMASK)
+ return -EINVAL;
+ if (fdq->d_id != id)
+ return -EINVAL;
+
+ error = qd_get(sdp, type, id, &qd);
+ if (error)
+ return error;
+
+ mutex_lock(&ip->i_inode.i_mutex);
+ error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE, 0, &q_gh);
+ if (error)
+ goto out_put;
+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
+ if (error)
+ goto out_q;
+
+ /* Check for existing entry, if none then alloc new blocks */
+ error = update_qd(sdp, qd);
+ if (error)
+ goto out_i;
+
+ /* If nothing has changed, this is a no-op */
+ if ((fdq->d_fieldmask & FS_DQ_BSOFT) &&
+ (fdq->d_blk_softlimit == be64_to_cpu(qd->qd_qb.qb_warn)))
+ fdq->d_fieldmask ^= FS_DQ_BSOFT;
+ if ((fdq->d_fieldmask & FS_DQ_BHARD) &&
+ (fdq->d_blk_hardlimit == be64_to_cpu(qd->qd_qb.qb_limit)))
+ fdq->d_fieldmask ^= FS_DQ_BHARD;
+ if (fdq->d_fieldmask == 0)
+ goto out_i;
+
+ offset = qd2offset(qd);
+ error = gfs2_write_alloc_required(ip, offset, sizeof(struct gfs2_quota),
+ &alloc_required);
+ if (error)
+ goto out_i;
+ if (alloc_required) {
+ al = gfs2_alloc_get(ip);
+ if (al == NULL)
+ goto out_i;
+ gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
+ &data_blocks, &ind_blocks);
+ blocks = al->al_requested = 1 + data_blocks + ind_blocks;
+ error = gfs2_inplace_reserve(ip);
+ if (error)
+ goto out_alloc;
+ }
+
+ error = gfs2_trans_begin(sdp, blocks + RES_DINODE + 1, 0);
+ if (error)
+ goto out_release;
+
+ /* Apply changes */
+ error = gfs2_adjust_quota(ip, offset, 0, qd, fdq);
+
+ gfs2_trans_end(sdp);
+out_release:
+ if (alloc_required) {
+ gfs2_inplace_release(ip);
+out_alloc:
+ gfs2_alloc_put(ip);
+ }
+out_i:
+ gfs2_glock_dq_uninit(&i_gh);
+out_q:
+ gfs2_glock_dq_uninit(&q_gh);
+out_put:
+ mutex_unlock(&ip->i_inode.i_mutex);
+ qd_put(qd);
+ return error;
+}
+
+const struct quotactl_ops gfs2_quotactl_ops = {
+ .quota_sync = gfs2_quota_sync,
+ .get_xstate = gfs2_quota_get_xstate,
+ .get_xquota = gfs2_xquota_get,
+ .set_xquota = gfs2_xquota_set,
+};
+
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index 0fa5fa63d0e8..e271fa07ad02 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -25,13 +25,15 @@ extern int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid);
extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
u32 uid, u32 gid);
-extern int gfs2_quota_sync(struct gfs2_sbd *sdp);
+extern int gfs2_quota_sync(struct super_block *sb, int type);
extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id);
extern int gfs2_quota_init(struct gfs2_sbd *sdp);
extern void gfs2_quota_cleanup(struct gfs2_sbd *sdp);
extern int gfs2_quotad(void *data);
+extern void gfs2_wake_up_statfs(struct gfs2_sbd *sdp);
+
static inline int gfs2_quota_lock_check(struct gfs2_inode *ip)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
@@ -50,5 +52,6 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip)
}
extern int gfs2_shrink_qd_memory(int nr, gfp_t gfp_mask);
+extern const struct quotactl_ops gfs2_quotactl_ops;
#endif /* __QUOTA_DOT_H__ */
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index 59d2695509d3..4b9bece3d437 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -7,6 +7,7 @@
* of the GNU General Public License version 2.
*/
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
@@ -409,7 +410,9 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header_host *hea
memset(lh, 0, sizeof(struct gfs2_log_header));
lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
+ lh->lh_header.__pad0 = cpu_to_be64(0);
lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
+ lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
lh->lh_sequence = cpu_to_be64(head->lh_sequence + 1);
lh->lh_flags = cpu_to_be32(GFS2_LOG_HEAD_UNMOUNT);
lh->lh_blkno = cpu_to_be32(lblock);
@@ -593,6 +596,7 @@ fail:
}
struct slow_work_ops gfs2_recover_ops = {
+ .owner = THIS_MODULE,
.get_ref = gfs2_recover_get_ref,
.put_ref = gfs2_recover_put_ref,
.execute = gfs2_recover_work,
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 8f1cfb02a6cb..0608f490c295 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1710,11 +1710,16 @@ int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type)
{
struct gfs2_rgrpd *rgd;
struct gfs2_holder ri_gh, rgd_gh;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex);
+ int ri_locked = 0;
int error;
- error = gfs2_rindex_hold(sdp, &ri_gh);
- if (error)
- goto fail;
+ if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
+ error = gfs2_rindex_hold(sdp, &ri_gh);
+ if (error)
+ goto fail;
+ ri_locked = 1;
+ }
error = -EINVAL;
rgd = gfs2_blk2rgrpd(sdp, no_addr);
@@ -1730,7 +1735,8 @@ int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type)
gfs2_glock_dq_uninit(&rgd_gh);
fail_rindex:
- gfs2_glock_dq_uninit(&ri_gh);
+ if (ri_locked)
+ gfs2_glock_dq_uninit(&ri_gh);
fail:
return error;
}
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 0ec3ec672de1..c282ad41f3d1 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -70,6 +70,11 @@ enum {
Opt_commit,
Opt_err_withdraw,
Opt_err_panic,
+ Opt_statfs_quantum,
+ Opt_statfs_percent,
+ Opt_quota_quantum,
+ Opt_barrier,
+ Opt_nobarrier,
Opt_error,
};
@@ -101,18 +106,23 @@ static const match_table_t tokens = {
{Opt_commit, "commit=%d"},
{Opt_err_withdraw, "errors=withdraw"},
{Opt_err_panic, "errors=panic"},
+ {Opt_statfs_quantum, "statfs_quantum=%d"},
+ {Opt_statfs_percent, "statfs_percent=%d"},
+ {Opt_quota_quantum, "quota_quantum=%d"},
+ {Opt_barrier, "barrier"},
+ {Opt_nobarrier, "nobarrier"},
{Opt_error, NULL}
};
/**
* gfs2_mount_args - Parse mount options
- * @sdp:
- * @data:
+ * @args: The structure into which the parsed options will be written
+ * @options: The options to parse
*
* Return: errno
*/
-int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
+int gfs2_mount_args(struct gfs2_args *args, char *options)
{
char *o;
int token;
@@ -157,7 +167,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
break;
case Opt_debug:
if (args->ar_errors == GFS2_ERRORS_PANIC) {
- fs_info(sdp, "-o debug and -o errors=panic "
+ printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
"are mutually exclusive.\n");
return -EINVAL;
}
@@ -210,7 +220,29 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
case Opt_commit:
rv = match_int(&tmp[0], &args->ar_commit);
if (rv || args->ar_commit <= 0) {
- fs_info(sdp, "commit mount option requires a positive numeric argument\n");
+ printk(KERN_WARNING "GFS2: commit mount option requires a positive numeric argument\n");
+ return rv ? rv : -EINVAL;
+ }
+ break;
+ case Opt_statfs_quantum:
+ rv = match_int(&tmp[0], &args->ar_statfs_quantum);
+ if (rv || args->ar_statfs_quantum < 0) {
+ printk(KERN_WARNING "GFS2: statfs_quantum mount option requires a non-negative numeric argument\n");
+ return rv ? rv : -EINVAL;
+ }
+ break;
+ case Opt_quota_quantum:
+ rv = match_int(&tmp[0], &args->ar_quota_quantum);
+ if (rv || args->ar_quota_quantum <= 0) {
+ printk(KERN_WARNING "GFS2: quota_quantum mount option requires a positive numeric argument\n");
+ return rv ? rv : -EINVAL;
+ }
+ break;
+ case Opt_statfs_percent:
+ rv = match_int(&tmp[0], &args->ar_statfs_percent);
+ if (rv || args->ar_statfs_percent < 0 ||
+ args->ar_statfs_percent > 100) {
+ printk(KERN_WARNING "statfs_percent mount option requires a numeric argument between 0 and 100\n");
return rv ? rv : -EINVAL;
}
break;
@@ -219,15 +251,21 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
break;
case Opt_err_panic:
if (args->ar_debug) {
- fs_info(sdp, "-o debug and -o errors=panic "
+ printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
"are mutually exclusive.\n");
return -EINVAL;
}
args->ar_errors = GFS2_ERRORS_PANIC;
break;
+ case Opt_barrier:
+ args->ar_nobarrier = 0;
+ break;
+ case Opt_nobarrier:
+ args->ar_nobarrier = 1;
+ break;
case Opt_error:
default:
- fs_info(sdp, "invalid mount option: %s\n", o);
+ printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o);
return -EINVAL;
}
}
@@ -442,7 +480,10 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
{
struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
+ struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
struct buffer_head *l_bh;
+ s64 x, y;
+ int need_sync = 0;
int error;
error = gfs2_meta_inode_buffer(l_ip, &l_bh);
@@ -456,9 +497,17 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
l_sc->sc_free += free;
l_sc->sc_dinodes += dinodes;
gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode));
+ if (sdp->sd_args.ar_statfs_percent) {
+ x = 100 * l_sc->sc_free;
+ y = m_sc->sc_free * sdp->sd_args.ar_statfs_percent;
+ if (x >= y || x <= -y)
+ need_sync = 1;
+ }
spin_unlock(&sdp->sd_statfs_spin);
brelse(l_bh);
+ if (need_sync)
+ gfs2_wake_up_statfs(sdp);
}
void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
@@ -484,8 +533,9 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode));
}
-int gfs2_statfs_sync(struct gfs2_sbd *sdp)
+int gfs2_statfs_sync(struct super_block *sb, int type)
{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
@@ -521,6 +571,7 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp)
goto out_bh2;
update_statfs(sdp, m_bh, l_bh);
+ sdp->sd_statfs_force_sync = 0;
gfs2_trans_end(sdp);
@@ -712,8 +763,8 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
int error;
flush_workqueue(gfs2_delete_workqueue);
- gfs2_quota_sync(sdp);
- gfs2_statfs_sync(sdp);
+ gfs2_quota_sync(sdp->sd_vfs, 0);
+ gfs2_statfs_sync(sdp->sd_vfs, 0);
error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
&t_gh);
@@ -1061,8 +1112,13 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
spin_lock(&gt->gt_spin);
args.ar_commit = gt->gt_log_flush_secs;
+ args.ar_quota_quantum = gt->gt_quota_quantum;
+ if (gt->gt_statfs_slow)
+ args.ar_statfs_quantum = 0;
+ else
+ args.ar_statfs_quantum = gt->gt_statfs_quantum;
spin_unlock(&gt->gt_spin);
- error = gfs2_mount_args(sdp, &args, data);
+ error = gfs2_mount_args(&args, data);
if (error)
return error;
@@ -1097,8 +1153,21 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
sb->s_flags |= MS_POSIXACL;
else
sb->s_flags &= ~MS_POSIXACL;
+ if (sdp->sd_args.ar_nobarrier)
+ set_bit(SDF_NOBARRIERS, &sdp->sd_flags);
+ else
+ clear_bit(SDF_NOBARRIERS, &sdp->sd_flags);
spin_lock(&gt->gt_spin);
gt->gt_log_flush_secs = args.ar_commit;
+ gt->gt_quota_quantum = args.ar_quota_quantum;
+ if (args.ar_statfs_quantum) {
+ gt->gt_statfs_slow = 0;
+ gt->gt_statfs_quantum = args.ar_statfs_quantum;
+ }
+ else {
+ gt->gt_statfs_slow = 1;
+ gt->gt_statfs_quantum = 30;
+ }
spin_unlock(&gt->gt_spin);
gfs2_online_uevent(sdp);
@@ -1179,7 +1248,7 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
{
struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info;
struct gfs2_args *args = &sdp->sd_args;
- int lfsecs;
+ int val;
if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir))
seq_printf(s, ",meta");
@@ -1240,9 +1309,17 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
}
if (args->ar_discard)
seq_printf(s, ",discard");
- lfsecs = sdp->sd_tune.gt_log_flush_secs;
- if (lfsecs != 60)
- seq_printf(s, ",commit=%d", lfsecs);
+ val = sdp->sd_tune.gt_log_flush_secs;
+ if (val != 60)
+ seq_printf(s, ",commit=%d", val);
+ val = sdp->sd_tune.gt_statfs_quantum;
+ if (val != 30)
+ seq_printf(s, ",statfs_quantum=%d", val);
+ val = sdp->sd_tune.gt_quota_quantum;
+ if (val != 60)
+ seq_printf(s, ",quota_quantum=%d", val);
+ if (args->ar_statfs_percent)
+ seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent);
if (args->ar_errors != GFS2_ERRORS_DEFAULT) {
const char *state;
@@ -1259,6 +1336,9 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
}
seq_printf(s, ",errors=%s", state);
}
+ if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags))
+ seq_printf(s, ",nobarrier");
+
return 0;
}
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h
index 235db3682885..3df60f2d84e3 100644
--- a/fs/gfs2/super.h
+++ b/fs/gfs2/super.h
@@ -27,7 +27,7 @@ static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)
extern void gfs2_jindex_free(struct gfs2_sbd *sdp);
-extern int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *data);
+extern int gfs2_mount_args(struct gfs2_args *args, char *data);
extern struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid);
extern int gfs2_jdesc_check(struct gfs2_jdesc *jd);
@@ -44,7 +44,7 @@ extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc,
const void *buf);
extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
struct buffer_head *l_bh);
-extern int gfs2_statfs_sync(struct gfs2_sbd *sdp);
+extern int gfs2_statfs_sync(struct super_block *sb, int type);
extern int gfs2_freeze_fs(struct gfs2_sbd *sdp);
extern void gfs2_unfreeze_fs(struct gfs2_sbd *sdp);
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index 446329728d52..c5dad1eb7b91 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -158,7 +158,7 @@ static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf,
if (simple_strtol(buf, NULL, 0) != 1)
return -EINVAL;
- gfs2_statfs_sync(sdp);
+ gfs2_statfs_sync(sdp->sd_vfs, 0);
return len;
}
@@ -171,13 +171,14 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
if (simple_strtol(buf, NULL, 0) != 1)
return -EINVAL;
- gfs2_quota_sync(sdp);
+ gfs2_quota_sync(sdp->sd_vfs, 0);
return len;
}
static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
size_t len)
{
+ int error;
u32 id;
if (!capable(CAP_SYS_ADMIN))
@@ -185,13 +186,14 @@ static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
id = simple_strtoul(buf, NULL, 0);
- gfs2_quota_refresh(sdp, 1, id);
- return len;
+ error = gfs2_quota_refresh(sdp, 1, id);
+ return error ? error : len;
}
static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
size_t len)
{
+ int error;
u32 id;
if (!capable(CAP_SYS_ADMIN))
@@ -199,8 +201,8 @@ static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
id = simple_strtoul(buf, NULL, 0);
- gfs2_quota_refresh(sdp, 0, id);
- return len;
+ error = gfs2_quota_refresh(sdp, 0, id);
+ return error ? error : len;
}
static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 8a0f8ef6ee27..912f5cbc4740 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -186,8 +186,8 @@ static int ea_find_i(struct gfs2_inode *ip, struct buffer_head *bh,
return 0;
}
-int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
- struct gfs2_ea_location *el)
+static int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
+ struct gfs2_ea_location *el)
{
struct ea_find ef;
int error;
@@ -516,8 +516,8 @@ out:
return error;
}
-int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
- char *data, size_t size)
+static int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
+ char *data, size_t size)
{
int ret;
size_t len = GFS2_EA_DATA_LEN(el->el_ea);
@@ -534,6 +534,36 @@ int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
return len;
}
+int gfs2_xattr_acl_get(struct gfs2_inode *ip, const char *name, char **ppdata)
+{
+ struct gfs2_ea_location el;
+ int error;
+ int len;
+ char *data;
+
+ error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, &el);
+ if (error)
+ return error;
+ if (!el.el_ea)
+ goto out;
+ if (!GFS2_EA_DATA_LEN(el.el_ea))
+ goto out;
+
+ len = GFS2_EA_DATA_LEN(el.el_ea);
+ data = kmalloc(len, GFP_NOFS);
+ error = -ENOMEM;
+ if (data == NULL)
+ goto out;
+
+ error = gfs2_ea_get_copy(ip, &el, data, len);
+ if (error == 0)
+ error = len;
+ *ppdata = data;
+out:
+ brelse(el.el_bh);
+ return error;
+}
+
/**
* gfs2_xattr_get - Get a GFS2 extended attribute
* @inode: The inode
@@ -1259,22 +1289,26 @@ fail:
return error;
}
-int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
- struct iattr *attr, char *data)
+int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
{
+ struct gfs2_ea_location el;
struct buffer_head *dibh;
int error;
- if (GFS2_EA_IS_STUFFED(el->el_ea)) {
+ error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, GFS2_POSIX_ACL_ACCESS, &el);
+ if (error)
+ return error;
+
+ if (GFS2_EA_IS_STUFFED(el.el_ea)) {
error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
if (error)
return error;
- gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
- memcpy(GFS2_EA2DATA(el->el_ea), data,
- GFS2_EA_DATA_LEN(el->el_ea));
+ gfs2_trans_add_bh(ip->i_gl, el.el_bh, 1);
+ memcpy(GFS2_EA2DATA(el.el_ea), data,
+ GFS2_EA_DATA_LEN(el.el_ea));
} else
- error = ea_acl_chmod_unstuffed(ip, el->el_ea, data);
+ error = ea_acl_chmod_unstuffed(ip, el.el_ea, data);
if (error)
return error;
@@ -1507,18 +1541,6 @@ static int gfs2_xattr_user_set(struct inode *inode, const char *name,
return gfs2_xattr_set(inode, GFS2_EATYPE_USR, name, value, size, flags);
}
-static int gfs2_xattr_system_get(struct inode *inode, const char *name,
- void *buffer, size_t size)
-{
- return gfs2_xattr_get(inode, GFS2_EATYPE_SYS, name, buffer, size);
-}
-
-static int gfs2_xattr_system_set(struct inode *inode, const char *name,
- const void *value, size_t size, int flags)
-{
- return gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, flags);
-}
-
static int gfs2_xattr_security_get(struct inode *inode, const char *name,
void *buffer, size_t size)
{
@@ -1543,12 +1565,6 @@ static struct xattr_handler gfs2_xattr_security_handler = {
.set = gfs2_xattr_security_set,
};
-static struct xattr_handler gfs2_xattr_system_handler = {
- .prefix = XATTR_SYSTEM_PREFIX,
- .get = gfs2_xattr_system_get,
- .set = gfs2_xattr_system_set,
-};
-
struct xattr_handler *gfs2_xattr_handlers[] = {
&gfs2_xattr_user_handler,
&gfs2_xattr_security_handler,
diff --git a/fs/gfs2/xattr.h b/fs/gfs2/xattr.h
index cbdfd7743733..8d6ae5813c4d 100644
--- a/fs/gfs2/xattr.h
+++ b/fs/gfs2/xattr.h
@@ -62,11 +62,7 @@ extern int gfs2_ea_dealloc(struct gfs2_inode *ip);
/* Exported to acl.c */
-extern int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
- struct gfs2_ea_location *el);
-extern int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
- char *data, size_t size);
-extern int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
- struct iattr *attr, char *data);
+extern int gfs2_xattr_acl_get(struct gfs2_inode *ip, const char *name, char **data);
+extern int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data);
#endif /* __EATTR_DOT_H__ */
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c
index 9b9d6395bad3..052f214ea6f0 100644
--- a/fs/hfs/btree.c
+++ b/fs/hfs/btree.c
@@ -58,6 +58,11 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
}
unlock_new_inode(tree->inode);
+ if (!HFS_I(tree->inode)->first_blocks) {
+ printk(KERN_ERR "hfs: invalid btree extent records (0 size).\n");
+ goto free_inode;
+ }
+
mapping = tree->inode->i_mapping;
page = read_mapping_page(mapping, 0, NULL);
if (IS_ERR(page))
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
index 175d08eacc86..bed78ac8f6d1 100644
--- a/fs/hfsplus/wrapper.c
+++ b/fs/hfsplus/wrapper.c
@@ -99,6 +99,10 @@ int hfsplus_read_wrapper(struct super_block *sb)
if (hfsplus_get_last_session(sb, &part_start, &part_size))
return -EINVAL;
+ if ((u64)part_start + part_size > 0x100000000ULL) {
+ pr_err("hfs: volumes larger than 2TB are not supported yet\n");
+ return -EINVAL;
+ }
while (1) {
bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr);
if (!bh)
diff --git a/fs/inode.c b/fs/inode.c
index 4d8e3be55976..06c1f02de611 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -18,7 +18,6 @@
#include <linux/hash.h>
#include <linux/swap.h>
#include <linux/security.h>
-#include <linux/ima.h>
#include <linux/pagemap.h>
#include <linux/cdev.h>
#include <linux/bootmem.h>
@@ -157,11 +156,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
if (security_inode_alloc(inode))
goto out;
-
- /* allocate and initialize an i_integrity */
- if (ima_inode_alloc(inode))
- goto out_free_security;
-
spin_lock_init(&inode->i_lock);
lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
@@ -201,9 +195,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
#endif
return 0;
-
-out_free_security:
- security_inode_free(inode);
out:
return -ENOMEM;
}
@@ -235,7 +226,6 @@ static struct inode *alloc_inode(struct super_block *sb)
void __destroy_inode(struct inode *inode)
{
BUG_ON(inode_has_buffers(inode));
- ima_inode_free(inode);
security_inode_free(inode);
fsnotify_inode_delete(inode);
#ifdef CONFIG_FS_POSIX_ACL
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 7b17a14396ff..6c751106c2e5 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -254,7 +254,7 @@ int __generic_block_fiemap(struct inode *inode,
u64 len, get_block_t *get_block)
{
struct buffer_head tmp;
- unsigned int start_blk;
+ unsigned long long start_blk;
long long length = 0, map_len = 0;
u64 logical = 0, phys = 0, size = 0;
u32 flags = FIEMAP_EXTENT_MERGED;
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index bd3c073b485d..4160afad6d00 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -73,6 +73,7 @@ EXPORT_SYMBOL(journal_errno);
EXPORT_SYMBOL(journal_ack_err);
EXPORT_SYMBOL(journal_clear_err);
EXPORT_SYMBOL(log_wait_commit);
+EXPORT_SYMBOL(log_start_commit);
EXPORT_SYMBOL(journal_start_commit);
EXPORT_SYMBOL(journal_force_commit_nested);
EXPORT_SYMBOL(journal_wipe);
@@ -756,6 +757,7 @@ journal_t * journal_init_dev(struct block_device *bdev,
return journal;
out_err:
+ kfree(journal->j_wbuf);
kfree(journal);
return NULL;
}
@@ -820,6 +822,7 @@ journal_t * journal_init_inode (struct inode *inode)
return journal;
out_err:
+ kfree(journal->j_wbuf);
kfree(journal);
return NULL;
}
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index b0ab5219becb..fed85388ee86 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -913,6 +913,7 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev,
return journal;
out_err:
+ kfree(journal->j_wbuf);
jbd2_stats_proc_exit(journal);
kfree(journal);
return NULL;
@@ -986,6 +987,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode)
return journal;
out_err:
+ kfree(journal->j_wbuf);
jbd2_stats_proc_exit(journal);
kfree(journal);
return NULL;
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c
index cfe05c1966a5..3f39be1b0455 100644
--- a/fs/jffs2/read.c
+++ b/fs/jffs2/read.c
@@ -164,12 +164,15 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
/* XXX FIXME: Where a single physical node actually shows up in two
frags, we read it twice. Don't do that. */
- /* Now we're pointing at the first frag which overlaps our page */
+ /* Now we're pointing at the first frag which overlaps our page
+ * (or perhaps is before it, if we've been asked to read off the
+ * end of the file). */
while(offset < end) {
D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end));
- if (unlikely(!frag || frag->ofs > offset)) {
+ if (unlikely(!frag || frag->ofs > offset ||
+ frag->ofs + frag->size <= offset)) {
uint32_t holesize = end - offset;
- if (frag) {
+ if (frag && frag->ofs > offset) {
D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
holesize = min(holesize, frag->ofs - offset);
}
diff --git a/fs/namespace.c b/fs/namespace.c
index bdc3cb4fd222..7d70d63ceb29 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1921,6 +1921,16 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
if (data_page)
((char *)data_page)[PAGE_SIZE - 1] = 0;
+ /* ... and get the mountpoint */
+ retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
+ if (retval)
+ return retval;
+
+ retval = security_sb_mount(dev_name, &path,
+ type_page, flags, data_page);
+ if (retval)
+ goto dput_out;
+
/* Default to relatime unless overriden */
if (!(flags & MS_NOATIME))
mnt_flags |= MNT_RELATIME;
@@ -1945,16 +1955,6 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
MS_STRICTATIME);
- /* ... and get the mountpoint */
- retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
- if (retval)
- return retval;
-
- retval = security_sb_mount(dev_name, &path,
- type_page, flags, data_page);
- if (retval)
- goto dput_out;
-
if (flags & MS_REMOUNT)
retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
data_page);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 32062c33c859..7cb298525eef 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1536,6 +1536,8 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
dentry->d_parent->d_name.name, dentry->d_name.name);
+ nfs_inode_return_delegation(inode);
+
d_drop(dentry);
error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
if (error == 0) {
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 6c3210099d51..e1d415e97849 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -457,6 +457,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
};
struct rpc_task_setup task_setup_data = {
.rpc_client = NFS_CLIENT(inode),
+ .rpc_message = &msg,
.callback_ops = &nfs_write_direct_ops,
.workqueue = nfsiod_workqueue,
.flags = RPC_TASK_ASYNC,
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index 70fad69eb959..fa588006588d 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -359,17 +359,13 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp)
BUG_ON(!cookie);
- if (fscache_check_page_write(cookie, page)) {
- if (!(gfp & __GFP_WAIT))
- return 0;
- fscache_wait_on_page_write(cookie, page);
- }
-
if (PageFsCache(page)) {
dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
cookie, page, nfsi);
- fscache_uncache_page(cookie, page);
+ if (!fscache_maybe_release_page(cookie, page, gfp))
+ return 0;
+
nfs_add_fscache_stats(page->mapping->host,
NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ed7c269e2514..741a562177fc 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -72,12 +72,17 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
/* Prevent leaks of NFSv4 errors into userland */
static int nfs4_map_errors(int err)
{
- if (err < -1000) {
+ if (err >= -1000)
+ return err;
+ switch (err) {
+ case -NFS4ERR_RESOURCE:
+ return -EREMOTEIO;
+ default:
dprintk("%s could not handle NFSv4 error %d\n",
__func__, -err);
- return -EIO;
+ break;
}
- return err;
+ return -EIO;
}
/*
@@ -2762,7 +2767,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
.pages = &page,
.pgbase = 0,
.count = count,
- .bitmask = NFS_SERVER(dentry->d_inode)->cache_consistency_bitmask,
+ .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask,
};
struct nfs4_readdir_res res;
struct rpc_message msg = {
@@ -3060,9 +3065,6 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
if (time_before(clp->cl_last_renewal,timestamp))
clp->cl_last_renewal = timestamp;
spin_unlock(&clp->cl_lock);
- dprintk("%s calling put_rpccred on rpc_cred %p\n", __func__,
- task->tk_msg.rpc_cred);
- put_rpccred(task->tk_msg.rpc_cred);
}
static const struct rpc_call_ops nfs4_renew_ops = {
@@ -4877,7 +4879,6 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp);
dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
- put_rpccred(task->tk_msg.rpc_cred);
kfree(task->tk_msg.rpc_argp);
kfree(task->tk_msg.rpc_resp);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 83ad47cbdd8a..20b4e30e6c82 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -5681,7 +5681,6 @@ static struct {
{ NFS4ERR_SERVERFAULT, -ESERVERFAULT },
{ NFS4ERR_BADTYPE, -EBADTYPE },
{ NFS4ERR_LOCKED, -EAGAIN },
- { NFS4ERR_RESOURCE, -EREMOTEIO },
{ NFS4ERR_SYMLINK, -ELOOP },
{ NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP },
{ NFS4ERR_DEADLOCK, -EDEADLK },
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index a2c18acb8568..90be551b80c1 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1253,6 +1253,7 @@ static int nfs_parse_mount_options(char *raw,
default:
dfprintk(MOUNT, "NFS: unrecognized "
"transport protocol\n");
+ kfree(string);
return 0;
}
break;
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index edf926e1062f..d0a2ce1b4324 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -958,7 +958,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
p1 = encode_entry_baggage(cd, p1, name, namlen, ino);
if (plus)
- p = encode_entryplus_baggage(cd, p1, name, namlen);
+ p1 = encode_entryplus_baggage(cd, p1, name, namlen);
/* determine entry word length and lengths to go in pages */
num_entry_words = p1 - tmp;
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 5941958f1e47..84c25382f8e3 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -87,6 +87,7 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
brelse(bh);
BUG();
}
+ memset(bh->b_data, 0, 1 << inode->i_blkbits);
bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
bh->b_blocknr = blocknr;
set_buffer_mapped(bh);
@@ -276,8 +277,7 @@ void nilfs_btnode_commit_change_key(struct address_space *btnc,
"invalid oldkey %lld (newkey=%lld)",
(unsigned long long)oldkey,
(unsigned long long)newkey);
- if (!test_set_buffer_dirty(obh) && TestSetPageDirty(opage))
- BUG();
+ nilfs_btnode_mark_dirty(obh);
spin_lock_irq(&btnc->tree_lock);
radix_tree_delete(&btnc->page_tree, oldkey);
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index 1c6cfb59128d..3f5d5d06f53c 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -871,7 +871,6 @@ int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode)
* exclusive with a new mount job. Though it doesn't cover
* umount, it's enough for the purpose.
*/
- mutex_lock(&nilfs->ns_mount_mutex);
if (nilfs_checkpoint_is_mounted(nilfs, cno, 1)) {
/* Current implementation does not have to protect
plain read-only mounts since they are exclusive
@@ -880,7 +879,6 @@ int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode)
ret = -EBUSY;
} else
ret = nilfs_cpfile_clear_snapshot(cpfile, cno);
- mutex_unlock(&nilfs->ns_mount_mutex);
return ret;
case NILFS_SNAPSHOT:
return nilfs_cpfile_set_snapshot(cpfile, cno);
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 5040220c3732..2a0a5a3ac134 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -664,7 +664,6 @@ int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode,
int err;
spin_lock(&sbi->s_inode_lock);
- /* Caller of this function MUST lock s_inode_lock */
if (ii->i_bh == NULL) {
spin_unlock(&sbi->s_inode_lock);
err = nilfs_ifile_get_inode_block(sbi->s_ifile, inode->i_ino,
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index 6572ea4bc4df..f6af76042d80 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -99,7 +99,8 @@ static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp)
{
- struct inode *cpfile = NILFS_SB(inode->i_sb)->s_nilfs->ns_cpfile;
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+ struct inode *cpfile = nilfs->ns_cpfile;
struct nilfs_transaction_info ti;
struct nilfs_cpmode cpmode;
int ret;
@@ -109,14 +110,17 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
return -EFAULT;
+ mutex_lock(&nilfs->ns_mount_mutex);
nilfs_transaction_begin(inode->i_sb, &ti, 0);
ret = nilfs_cpfile_change_cpmode(
cpfile, cpmode.cm_cno, cpmode.cm_mode);
if (unlikely(ret < 0)) {
nilfs_transaction_abort(inode->i_sb);
+ mutex_unlock(&nilfs->ns_mount_mutex);
return ret;
}
nilfs_transaction_commit(inode->i_sb); /* never fails */
+ mutex_unlock(&nilfs->ns_mount_mutex);
return ret;
}
@@ -297,7 +301,18 @@ static int nilfs_ioctl_move_inode_block(struct inode *inode,
(unsigned long long)vdesc->vd_vblocknr);
return ret;
}
- bh->b_private = vdesc;
+ if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
+ printk(KERN_CRIT "%s: conflicting %s buffer: ino=%llu, "
+ "cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu\n",
+ __func__, vdesc->vd_flags ? "node" : "data",
+ (unsigned long long)vdesc->vd_ino,
+ (unsigned long long)vdesc->vd_cno,
+ (unsigned long long)vdesc->vd_offset,
+ (unsigned long long)vdesc->vd_blocknr,
+ (unsigned long long)vdesc->vd_vblocknr);
+ brelse(bh);
+ return -EEXIST;
+ }
list_add_tail(&bh->b_assoc_buffers, buffers);
return 0;
}
@@ -335,24 +350,10 @@ static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
ret = nilfs_gccache_wait_and_mark_dirty(bh);
if (unlikely(ret < 0)) {
- if (ret == -EEXIST) {
- vdesc = bh->b_private;
- printk(KERN_CRIT
- "%s: conflicting %s buffer: "
- "ino=%llu, cno=%llu, offset=%llu, "
- "blocknr=%llu, vblocknr=%llu\n",
- __func__,
- vdesc->vd_flags ? "node" : "data",
- (unsigned long long)vdesc->vd_ino,
- (unsigned long long)vdesc->vd_cno,
- (unsigned long long)vdesc->vd_offset,
- (unsigned long long)vdesc->vd_blocknr,
- (unsigned long long)vdesc->vd_vblocknr);
- }
+ WARN_ON(ret == -EEXIST);
goto failed;
}
list_del_init(&bh->b_assoc_buffers);
- bh->b_private = NULL;
brelse(bh);
}
return nmembs;
@@ -360,7 +361,6 @@ static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
failed:
list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
list_del_init(&bh->b_assoc_buffers);
- bh->b_private = NULL;
brelse(bh);
}
return ret;
@@ -471,7 +471,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
return 0;
failed:
- nilfs_remove_all_gcinode(nilfs);
printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n",
msg, ret);
return ret;
@@ -560,6 +559,8 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
else
ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
+ if (ret < 0)
+ nilfs_remove_all_gcinode(nilfs);
clear_nilfs_gc_running(nilfs);
out_free:
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 683df89dbae5..6eff66a070d5 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2468,17 +2468,22 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci,
/* Clear requests (even when the construction failed) */
spin_lock(&sci->sc_state_lock);
- sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
-
if (req->mode == SC_LSEG_SR) {
+ sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
sci->sc_seq_done = req->seq_accepted;
nilfs_segctor_wakeup(sci, req->sc_err ? : req->sb_err);
sci->sc_flush_request = 0;
- } else if (req->mode == SC_FLUSH_FILE)
- sci->sc_flush_request &= ~FLUSH_FILE_BIT;
- else if (req->mode == SC_FLUSH_DAT)
- sci->sc_flush_request &= ~FLUSH_DAT_BIT;
+ } else {
+ if (req->mode == SC_FLUSH_FILE)
+ sci->sc_flush_request &= ~FLUSH_FILE_BIT;
+ else if (req->mode == SC_FLUSH_DAT)
+ sci->sc_flush_request &= ~FLUSH_DAT_BIT;
+ /* re-enable timer if checkpoint creation was not done */
+ if (sci->sc_timer && (sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
+ time_before(jiffies, sci->sc_timer->expires))
+ add_timer(sci->sc_timer);
+ }
spin_unlock(&sci->sc_state_lock);
}
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index 828a889be909..7e54e52964dd 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -91,6 +91,7 @@ static int dnotify_handle_event(struct fsnotify_group *group,
struct dnotify_struct *dn;
struct dnotify_struct **prev;
struct fown_struct *fown;
+ __u32 test_mask = event->mask & ~FS_EVENT_ON_CHILD;
to_tell = event->to_tell;
@@ -106,7 +107,7 @@ static int dnotify_handle_event(struct fsnotify_group *group,
spin_lock(&entry->lock);
prev = &dnentry->dn;
while ((dn = *prev) != NULL) {
- if ((dn->dn_mask & event->mask) == 0) {
+ if ((dn->dn_mask & test_mask) == 0) {
prev = &dn->dn_next;
continue;
}
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index c8a07c65482b..3165d85aada2 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -324,11 +324,11 @@ int fsnotify_add_mark(struct fsnotify_mark_entry *entry,
spin_lock(&group->mark_lock);
spin_lock(&inode->i_lock);
- entry->group = group;
- entry->inode = inode;
-
lentry = fsnotify_find_mark_entry(group, inode);
if (!lentry) {
+ entry->group = group;
+ entry->inode = inode;
+
hlist_add_head(&entry->i_list, &inode->i_fsnotify_mark_entries);
list_add(&entry->g_list, &group->mark_entries);
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index 3816d5750dd5..b8bf53b4c108 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -143,7 +143,7 @@ static bool event_compare(struct fsnotify_event *old, struct fsnotify_event *new
/* remember, after old was put on the wait_q we aren't
* allowed to look at the inode any more, only thing
* left to check was if the file_name is the same */
- if (old->name_len &&
+ if (!old->name_len ||
!strcmp(old->file_name, new->file_name))
return true;
break;
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 89fc8ee1f5a5..de059f490586 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1712,7 +1712,8 @@ int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos,
struct super_block *sb = inode->i_sb;
if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)) ||
- !(OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL))
+ !(OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL) ||
+ OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
return 0;
cpos = pos >> OCFS2_SB(sb)->s_clustersize_bits;
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index eae404602424..d963d8638709 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -35,12 +35,7 @@
#include <linux/kref.h>
#include <linux/mutex.h>
#include <linux/lockdep.h>
-#ifndef CONFIG_OCFS2_COMPAT_JBD
-# include <linux/jbd2.h>
-#else
-# include <linux/jbd.h>
-# include "ocfs2_jbd_compat.h"
-#endif
+#include <linux/jbd2.h>
/* For union ocfs2_dlm_lksb */
#include "stackglue.h"
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 60287fc56bcb..3a0df7a1b810 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -3743,6 +3743,9 @@ static int ocfs2_attach_refcount_tree(struct inode *inode,
goto out;
}
+ if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL)
+ goto attach_xattr;
+
ocfs2_init_dinode_extent_tree(&di_et, INODE_CACHE(inode), di_bh);
size = i_size_read(inode);
@@ -3769,6 +3772,7 @@ static int ocfs2_attach_refcount_tree(struct inode *inode,
cpos += num_clusters;
}
+attach_xattr:
if (oi->ip_dyn_features & OCFS2_HAS_XATTR_FL) {
ret = ocfs2_xattr_attach_refcount_tree(inode, di_bh,
&ref_tree->rf_ci,
@@ -3858,6 +3862,49 @@ out:
return ret;
}
+static int ocfs2_duplicate_inline_data(struct inode *s_inode,
+ struct buffer_head *s_bh,
+ struct inode *t_inode,
+ struct buffer_head *t_bh)
+{
+ int ret;
+ handle_t *handle;
+ struct ocfs2_super *osb = OCFS2_SB(s_inode->i_sb);
+ struct ocfs2_dinode *s_di = (struct ocfs2_dinode *)s_bh->b_data;
+ struct ocfs2_dinode *t_di = (struct ocfs2_dinode *)t_bh->b_data;
+
+ BUG_ON(!(OCFS2_I(s_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL));
+
+ handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ mlog_errno(ret);
+ goto out;
+ }
+
+ ret = ocfs2_journal_access_di(handle, INODE_CACHE(t_inode), t_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ t_di->id2.i_data.id_count = s_di->id2.i_data.id_count;
+ memcpy(t_di->id2.i_data.id_data, s_di->id2.i_data.id_data,
+ le16_to_cpu(s_di->id2.i_data.id_count));
+ spin_lock(&OCFS2_I(t_inode)->ip_lock);
+ OCFS2_I(t_inode)->ip_dyn_features |= OCFS2_INLINE_DATA_FL;
+ t_di->i_dyn_features = cpu_to_le16(OCFS2_I(t_inode)->ip_dyn_features);
+ spin_unlock(&OCFS2_I(t_inode)->ip_lock);
+
+ ocfs2_journal_dirty(handle, t_bh);
+
+out_commit:
+ ocfs2_commit_trans(osb, handle);
+out:
+ return ret;
+}
+
static int ocfs2_duplicate_extent_list(struct inode *s_inode,
struct inode *t_inode,
struct buffer_head *t_bh,
@@ -3997,6 +4044,14 @@ static int ocfs2_create_reflink_node(struct inode *s_inode,
goto out;
}
+ if (OCFS2_I(s_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+ ret = ocfs2_duplicate_inline_data(s_inode, s_bh,
+ t_inode, t_bh);
+ if (ret)
+ mlog_errno(ret);
+ goto out;
+ }
+
ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc),
1, &ref_tree, &ref_root_bh);
if (ret) {
@@ -4013,10 +4068,6 @@ static int ocfs2_create_reflink_node(struct inode *s_inode,
goto out_unlock_refcount;
}
- ret = ocfs2_complete_reflink(s_inode, s_bh, t_inode, t_bh, preserve);
- if (ret)
- mlog_errno(ret);
-
out_unlock_refcount:
ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
brelse(ref_root_bh);
@@ -4068,9 +4119,17 @@ static int __ocfs2_reflink(struct dentry *old_dentry,
ret = ocfs2_reflink_xattrs(inode, old_bh,
new_inode, new_bh,
preserve);
- if (ret)
+ if (ret) {
mlog_errno(ret);
+ goto inode_unlock;
+ }
}
+
+ ret = ocfs2_complete_reflink(inode, old_bh,
+ new_inode, new_bh, preserve);
+ if (ret)
+ mlog_errno(ret);
+
inode_unlock:
ocfs2_inode_unlock(new_inode, 1);
brelse(new_bh);
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index c0e48aeebb1c..14f47d2bfe02 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -773,18 +773,20 @@ static int ocfs2_sb_probe(struct super_block *sb,
if (tmpstat < 0) {
status = tmpstat;
mlog_errno(status);
- goto bail;
+ break;
}
di = (struct ocfs2_dinode *) (*bh)->b_data;
memset(stats, 0, sizeof(struct ocfs2_blockcheck_stats));
spin_lock_init(&stats->b_lock);
- status = ocfs2_verify_volume(di, *bh, blksize, stats);
- if (status >= 0)
- goto bail;
- brelse(*bh);
- *bh = NULL;
- if (status != -EAGAIN)
+ tmpstat = ocfs2_verify_volume(di, *bh, blksize, stats);
+ if (tmpstat < 0) {
+ brelse(*bh);
+ *bh = NULL;
+ }
+ if (tmpstat != -EAGAIN) {
+ status = tmpstat;
break;
+ }
}
bail:
@@ -1645,6 +1647,10 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_bavail = buf->f_bfree;
buf->f_files = numbits;
buf->f_ffree = freebits;
+ buf->f_fsid.val[0] = crc32_le(0, osb->uuid_str, OCFS2_VOL_UUID_LEN)
+ & 0xFFFFFFFFUL;
+ buf->f_fsid.val[1] = crc32_le(0, osb->uuid_str + OCFS2_VOL_UUID_LEN,
+ OCFS2_VOL_UUID_LEN) & 0xFFFFFFFFUL;
brelse(bh);
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c
index b6284f235d2f..c61369342a27 100644
--- a/fs/ocfs2/uptodate.c
+++ b/fs/ocfs2/uptodate.c
@@ -53,11 +53,6 @@
#include <linux/highmem.h>
#include <linux/buffer_head.h>
#include <linux/rbtree.h>
-#ifndef CONFIG_OCFS2_COMPAT_JBD
-# include <linux/jbd2.h>
-#else
-# include <linux/jbd.h>
-#endif
#define MLOG_MASK_PREFIX ML_UPTODATE
diff --git a/fs/open.c b/fs/open.c
index 4f01e06227c6..b4b31d277f3a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -587,6 +587,9 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
error = -EPERM;
if (!capable(CAP_SYS_CHROOT))
goto dput_and_out;
+ error = security_path_chroot(&path);
+ if (error)
+ goto dput_and_out;
set_fs_root(current->fs, &path);
error = 0;
@@ -617,11 +620,15 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
if (err)
goto out_putf;
mutex_lock(&inode->i_mutex);
+ err = security_path_chmod(dentry, file->f_vfsmnt, mode);
+ if (err)
+ goto out_unlock;
if (mode == (mode_t) -1)
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
err = notify_change(dentry, &newattrs);
+out_unlock:
mutex_unlock(&inode->i_mutex);
mnt_drop_write(file->f_path.mnt);
out_putf:
@@ -646,11 +653,15 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
if (error)
goto dput_and_out;
mutex_lock(&inode->i_mutex);
+ error = security_path_chmod(path.dentry, path.mnt, mode);
+ if (error)
+ goto out_unlock;
if (mode == (mode_t) -1)
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
error = notify_change(path.dentry, &newattrs);
+out_unlock:
mutex_unlock(&inode->i_mutex);
mnt_drop_write(path.mnt);
dput_and_out:
@@ -664,9 +675,9 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode)
return sys_fchmodat(AT_FDCWD, filename, mode);
}
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
+static int chown_common(struct path *path, uid_t user, gid_t group)
{
- struct inode *inode = dentry->d_inode;
+ struct inode *inode = path->dentry->d_inode;
int error;
struct iattr newattrs;
@@ -683,7 +694,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
newattrs.ia_valid |=
ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
mutex_lock(&inode->i_mutex);
- error = notify_change(dentry, &newattrs);
+ error = security_path_chown(path, user, group);
+ if (!error)
+ error = notify_change(path->dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
return error;
@@ -700,7 +713,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
error = mnt_want_write(path.mnt);
if (error)
goto out_release;
- error = chown_common(path.dentry, user, group);
+ error = chown_common(&path, user, group);
mnt_drop_write(path.mnt);
out_release:
path_put(&path);
@@ -725,7 +738,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
error = mnt_want_write(path.mnt);
if (error)
goto out_release;
- error = chown_common(path.dentry, user, group);
+ error = chown_common(&path, user, group);
mnt_drop_write(path.mnt);
out_release:
path_put(&path);
@@ -744,7 +757,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group
error = mnt_want_write(path.mnt);
if (error)
goto out_release;
- error = chown_common(path.dentry, user, group);
+ error = chown_common(&path, user, group);
mnt_drop_write(path.mnt);
out_release:
path_put(&path);
@@ -767,7 +780,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
goto out_fput;
dentry = file->f_path.dentry;
audit_inode(NULL, dentry);
- error = chown_common(dentry, user, group);
+ error = chown_common(&file->f_path, user, group);
mnt_drop_write(file->f_path.mnt);
out_fput:
fput(file);
diff --git a/fs/pipe.c b/fs/pipe.c
index 52c415114838..ae17d026aaa3 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -777,36 +777,55 @@ pipe_rdwr_release(struct inode *inode, struct file *filp)
static int
pipe_read_open(struct inode *inode, struct file *filp)
{
- /* We could have perhaps used atomic_t, but this and friends
- below are the only places. So it doesn't seem worthwhile. */
+ int ret = -ENOENT;
+
mutex_lock(&inode->i_mutex);
- inode->i_pipe->readers++;
+
+ if (inode->i_pipe) {
+ ret = 0;
+ inode->i_pipe->readers++;
+ }
+
mutex_unlock(&inode->i_mutex);
- return 0;
+ return ret;
}
static int
pipe_write_open(struct inode *inode, struct file *filp)
{
+ int ret = -ENOENT;
+
mutex_lock(&inode->i_mutex);
- inode->i_pipe->writers++;
+
+ if (inode->i_pipe) {
+ ret = 0;
+ inode->i_pipe->writers++;
+ }
+
mutex_unlock(&inode->i_mutex);
- return 0;
+ return ret;
}
static int
pipe_rdwr_open(struct inode *inode, struct file *filp)
{
+ int ret = -ENOENT;
+
mutex_lock(&inode->i_mutex);
- if (filp->f_mode & FMODE_READ)
- inode->i_pipe->readers++;
- if (filp->f_mode & FMODE_WRITE)
- inode->i_pipe->writers++;
+
+ if (inode->i_pipe) {
+ ret = 0;
+ if (filp->f_mode & FMODE_READ)
+ inode->i_pipe->readers++;
+ if (filp->f_mode & FMODE_WRITE)
+ inode->i_pipe->writers++;
+ }
+
mutex_unlock(&inode->i_mutex);
- return 0;
+ return ret;
}
/*
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 07f77a7945c3..4badde179b18 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -410,6 +410,16 @@ static void task_show_stack_usage(struct seq_file *m, struct task_struct *task)
}
#endif /* CONFIG_MMU */
+static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
+{
+ seq_printf(m, "Cpus_allowed:\t");
+ seq_cpumask(m, &task->cpus_allowed);
+ seq_printf(m, "\n");
+ seq_printf(m, "Cpus_allowed_list:\t");
+ seq_cpumask_list(m, &task->cpus_allowed);
+ seq_printf(m, "\n");
+}
+
int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{
@@ -424,6 +434,7 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
}
task_sig(m, task);
task_cap(m, task);
+ task_cpus_allowed(m, task);
cpuset_task_status_allowed(m, task);
#if defined(CONFIG_S390)
task_show_regs(m, task);
@@ -495,20 +506,17 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
/* add up live thread stats at the group level */
if (whole) {
- struct task_cputime cputime;
struct task_struct *t = task;
do {
min_flt += t->min_flt;
maj_flt += t->maj_flt;
- gtime = cputime_add(gtime, task_gtime(t));
+ gtime = cputime_add(gtime, t->gtime);
t = next_thread(t);
} while (t != task);
min_flt += sig->min_flt;
maj_flt += sig->maj_flt;
- thread_group_cputime(task, &cputime);
- utime = cputime.utime;
- stime = cputime.stime;
+ thread_group_times(task, &utime, &stime);
gtime = cputime_add(gtime, sig->gtime);
}
@@ -524,9 +532,8 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
if (!whole) {
min_flt = task->min_flt;
maj_flt = task->maj_flt;
- utime = task_utime(task);
- stime = task_stime(task);
- gtime = task_gtime(task);
+ task_times(task, &utime, &stime);
+ gtime = task->gtime;
}
/* scale priority and nice values from timeslices to -20..20 */
@@ -571,7 +578,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
rsslim,
mm ? mm->start_code : 0,
mm ? mm->end_code : 0,
- (permitted) ? task->stack_start : 0,
+ (permitted && mm) ? task->stack_start : 0,
esp,
eip,
/* The signal information here is obsolete.
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 837469a96598..af643b5aefe8 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2597,8 +2597,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
name.len = snprintf(buf, sizeof(buf), "%d", pid);
dentry = d_hash_and_lookup(mnt->mnt_root, &name);
if (dentry) {
- if (!(current->flags & PF_EXITING))
- shrink_dcache_parent(dentry);
+ shrink_dcache_parent(dentry);
d_drop(dentry);
dput(dentry);
}
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index c7bff4f603ff..a65239cfd97e 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -99,7 +99,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
"VmallocUsed: %8lu kB\n"
"VmallocChunk: %8lu kB\n"
#ifdef CONFIG_MEMORY_FAILURE
- "HardwareCorrupted: %8lu kB\n"
+ "HardwareCorrupted: %5lu kB\n"
#endif
,
K(i.totalram),
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
index 7cc726c6d70a..b9b7aad2003d 100644
--- a/fs/proc/stat.c
+++ b/fs/proc/stat.c
@@ -27,7 +27,7 @@ static int show_stat(struct seq_file *p, void *v)
int i, j;
unsigned long jif;
cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
- cputime64_t guest;
+ cputime64_t guest, guest_nice;
u64 sum = 0;
u64 sum_softirq = 0;
unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
@@ -36,7 +36,7 @@ static int show_stat(struct seq_file *p, void *v)
user = nice = system = idle = iowait =
irq = softirq = steal = cputime64_zero;
- guest = cputime64_zero;
+ guest = guest_nice = cputime64_zero;
getboottime(&boottime);
jif = boottime.tv_sec;
@@ -51,6 +51,8 @@ static int show_stat(struct seq_file *p, void *v)
softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
+ guest_nice = cputime64_add(guest_nice,
+ kstat_cpu(i).cpustat.guest_nice);
for_each_irq_nr(j) {
sum += kstat_irqs_cpu(j, i);
}
@@ -65,7 +67,8 @@ static int show_stat(struct seq_file *p, void *v)
}
sum += arch_irq_stat();
- seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
+ seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu "
+ "%llu\n",
(unsigned long long)cputime64_to_clock_t(user),
(unsigned long long)cputime64_to_clock_t(nice),
(unsigned long long)cputime64_to_clock_t(system),
@@ -74,7 +77,8 @@ static int show_stat(struct seq_file *p, void *v)
(unsigned long long)cputime64_to_clock_t(irq),
(unsigned long long)cputime64_to_clock_t(softirq),
(unsigned long long)cputime64_to_clock_t(steal),
- (unsigned long long)cputime64_to_clock_t(guest));
+ (unsigned long long)cputime64_to_clock_t(guest),
+ (unsigned long long)cputime64_to_clock_t(guest_nice));
for_each_online_cpu(i) {
/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
@@ -88,8 +92,10 @@ static int show_stat(struct seq_file *p, void *v)
softirq = kstat_cpu(i).cpustat.softirq;
steal = kstat_cpu(i).cpustat.steal;
guest = kstat_cpu(i).cpustat.guest;
+ guest_nice = kstat_cpu(i).cpustat.guest_nice;
seq_printf(p,
- "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
+ "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu "
+ "%llu\n",
i,
(unsigned long long)cputime64_to_clock_t(user),
(unsigned long long)cputime64_to_clock_t(nice),
@@ -99,7 +105,8 @@ static int show_stat(struct seq_file *p, void *v)
(unsigned long long)cputime64_to_clock_t(irq),
(unsigned long long)cputime64_to_clock_t(softirq),
(unsigned long long)cputime64_to_clock_t(steal),
- (unsigned long long)cputime64_to_clock_t(guest));
+ (unsigned long long)cputime64_to_clock_t(guest),
+ (unsigned long long)cputime64_to_clock_t(guest_nice));
}
seq_printf(p, "intr %llu", (unsigned long long)sum);
diff --git a/fs/quota/Kconfig b/fs/quota/Kconfig
index 8047e01ef46b..353e78a9ebee 100644
--- a/fs/quota/Kconfig
+++ b/fs/quota/Kconfig
@@ -17,7 +17,7 @@ config QUOTA
config QUOTA_NETLINK_INTERFACE
bool "Report quota messages through netlink interface"
- depends on QUOTA && NET
+ depends on QUOTACTL && NET
help
If you say Y here, quota warnings (about exceeding softlimit, reaching
hardlimit, etc.) will be reported through netlink interface. If unsure,
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 39b49c42a7ed..9b6ad908dcb2 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -77,10 +77,6 @@
#include <linux/capability.h>
#include <linux/quotaops.h>
#include <linux/writeback.h> /* for inode_lock, oddly enough.. */
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-#include <net/netlink.h>
-#include <net/genetlink.h>
-#endif
#include <asm/uaccess.h>
@@ -1071,73 +1067,6 @@ static void print_warning(struct dquot *dquot, const int warntype)
}
#endif
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-
-/* Netlink family structure for quota */
-static struct genl_family quota_genl_family = {
- .id = GENL_ID_GENERATE,
- .hdrsize = 0,
- .name = "VFS_DQUOT",
- .version = 1,
- .maxattr = QUOTA_NL_A_MAX,
-};
-
-/* Send warning to userspace about user which exceeded quota */
-static void send_warning(const struct dquot *dquot, const char warntype)
-{
- static atomic_t seq;
- struct sk_buff *skb;
- void *msg_head;
- int ret;
- int msg_size = 4 * nla_total_size(sizeof(u32)) +
- 2 * nla_total_size(sizeof(u64));
-
- /* We have to allocate using GFP_NOFS as we are called from a
- * filesystem performing write and thus further recursion into
- * the fs to free some data could cause deadlocks. */
- skb = genlmsg_new(msg_size, GFP_NOFS);
- if (!skb) {
- printk(KERN_ERR
- "VFS: Not enough memory to send quota warning.\n");
- return;
- }
- msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
- &quota_genl_family, 0, QUOTA_NL_C_WARNING);
- if (!msg_head) {
- printk(KERN_ERR
- "VFS: Cannot store netlink header in quota warning.\n");
- goto err_out;
- }
- ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, dquot->dq_type);
- if (ret)
- goto attr_err_out;
- ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, dquot->dq_id);
- if (ret)
- goto attr_err_out;
- ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
- if (ret)
- goto attr_err_out;
- ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR,
- MAJOR(dquot->dq_sb->s_dev));
- if (ret)
- goto attr_err_out;
- ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR,
- MINOR(dquot->dq_sb->s_dev));
- if (ret)
- goto attr_err_out;
- ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
- if (ret)
- goto attr_err_out;
- genlmsg_end(skb, msg_head);
-
- genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
- return;
-attr_err_out:
- printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
-err_out:
- kfree_skb(skb);
-}
-#endif
/*
* Write warnings to the console and send warning messages over netlink.
*
@@ -1145,18 +1074,20 @@ err_out:
*/
static void flush_warnings(struct dquot *const *dquots, char *warntype)
{
+ struct dquot *dq;
int i;
- for (i = 0; i < MAXQUOTAS; i++)
- if (dquots[i] && warntype[i] != QUOTA_NL_NOWARN &&
- !warning_issued(dquots[i], warntype[i])) {
+ for (i = 0; i < MAXQUOTAS; i++) {
+ dq = dquots[i];
+ if (dq && warntype[i] != QUOTA_NL_NOWARN &&
+ !warning_issued(dq, warntype[i])) {
#ifdef CONFIG_PRINT_QUOTA_WARNING
- print_warning(dquots[i], warntype[i]);
-#endif
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
- send_warning(dquots[i], warntype[i]);
+ print_warning(dq, warntype[i]);
#endif
+ quota_send_warning(dq->dq_type, dq->dq_id,
+ dq->dq_sb->s_dev, warntype[i]);
}
+ }
}
static int ignore_hardlimit(struct dquot *dquot)
@@ -2607,12 +2538,6 @@ static int __init dquot_init(void)
register_shrinker(&dqcache_shrinker);
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
- if (genl_register_family(&quota_genl_family) != 0)
- printk(KERN_ERR
- "VFS: Failed to create quota netlink interface.\n");
-#endif
-
return 0;
}
module_init(dquot_init);
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 95c5b42384b2..ee91e2756950 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -18,6 +18,8 @@
#include <linux/capability.h>
#include <linux/quotaops.h>
#include <linux/types.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
/* Check validity of generic quotactl commands */
static int generic_quotactl_valid(struct super_block *sb, int type, int cmd,
@@ -525,3 +527,94 @@ asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
return ret;
}
#endif
+
+
+#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
+
+/* Netlink family structure for quota */
+static struct genl_family quota_genl_family = {
+ .id = GENL_ID_GENERATE,
+ .hdrsize = 0,
+ .name = "VFS_DQUOT",
+ .version = 1,
+ .maxattr = QUOTA_NL_A_MAX,
+};
+
+/**
+ * quota_send_warning - Send warning to userspace about exceeded quota
+ * @type: The quota type: USRQQUOTA, GRPQUOTA,...
+ * @id: The user or group id of the quota that was exceeded
+ * @dev: The device on which the fs is mounted (sb->s_dev)
+ * @warntype: The type of the warning: QUOTA_NL_...
+ *
+ * This can be used by filesystems (including those which don't use
+ * dquot) to send a message to userspace relating to quota limits.
+ *
+ */
+
+void quota_send_warning(short type, unsigned int id, dev_t dev,
+ const char warntype)
+{
+ static atomic_t seq;
+ struct sk_buff *skb;
+ void *msg_head;
+ int ret;
+ int msg_size = 4 * nla_total_size(sizeof(u32)) +
+ 2 * nla_total_size(sizeof(u64));
+
+ /* We have to allocate using GFP_NOFS as we are called from a
+ * filesystem performing write and thus further recursion into
+ * the fs to free some data could cause deadlocks. */
+ skb = genlmsg_new(msg_size, GFP_NOFS);
+ if (!skb) {
+ printk(KERN_ERR
+ "VFS: Not enough memory to send quota warning.\n");
+ return;
+ }
+ msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
+ &quota_genl_family, 0, QUOTA_NL_C_WARNING);
+ if (!msg_head) {
+ printk(KERN_ERR
+ "VFS: Cannot store netlink header in quota warning.\n");
+ goto err_out;
+ }
+ ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, type);
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, id);
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR, MAJOR(dev));
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR, MINOR(dev));
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
+ if (ret)
+ goto attr_err_out;
+ genlmsg_end(skb, msg_head);
+
+ genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
+ return;
+attr_err_out:
+ printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
+err_out:
+ kfree_skb(skb);
+}
+EXPORT_SYMBOL(quota_send_warning);
+
+static int __init quota_init(void)
+{
+ if (genl_register_family(&quota_genl_family) != 0)
+ printk(KERN_ERR
+ "VFS: Failed to create quota netlink interface.\n");
+ return 0;
+};
+
+module_init(quota_init);
+#endif
+
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 0050fc40e8c9..e0201837d244 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -21,6 +21,7 @@
#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include "sysfs.h"
DEFINE_MUTEX(sysfs_mutex);
@@ -285,6 +286,9 @@ void release_sysfs_dirent(struct sysfs_dirent * sd)
sysfs_put(sd->s_symlink.target_sd);
if (sysfs_type(sd) & SYSFS_COPY_NAME)
kfree(sd->s_name);
+ if (sd->s_iattr && sd->s_iattr->ia_secdata)
+ security_release_secctx(sd->s_iattr->ia_secdata,
+ sd->s_iattr->ia_secdata_len);
kfree(sd->s_iattr);
sysfs_free_ino(sd->s_ino);
kmem_cache_free(sysfs_dir_cachep, sd);
@@ -894,7 +898,8 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
mutex_lock(&sysfs_rename_mutex);
BUG_ON(!sd->s_parent);
- new_parent_sd = new_parent_kobj->sd ? new_parent_kobj->sd : &sysfs_root;
+ new_parent_sd = (new_parent_kobj && new_parent_kobj->sd) ?
+ new_parent_kobj->sd : &sysfs_root;
error = 0;
if (sd->s_parent == new_parent_sd)
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 561a9c050cef..f5ea4680f15f 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -268,7 +268,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
struct sysfs_open_dirent *od, *new_od = NULL;
retry:
- spin_lock(&sysfs_open_dirent_lock);
+ spin_lock_irq(&sysfs_open_dirent_lock);
if (!sd->s_attr.open && new_od) {
sd->s_attr.open = new_od;
@@ -281,7 +281,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
list_add_tail(&buffer->list, &od->buffers);
}
- spin_unlock(&sysfs_open_dirent_lock);
+ spin_unlock_irq(&sysfs_open_dirent_lock);
if (od) {
kfree(new_od);
@@ -315,8 +315,9 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
struct sysfs_buffer *buffer)
{
struct sysfs_open_dirent *od = sd->s_attr.open;
+ unsigned long flags;
- spin_lock(&sysfs_open_dirent_lock);
+ spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
list_del(&buffer->list);
if (atomic_dec_and_test(&od->refcnt))
@@ -324,7 +325,7 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
else
od = NULL;
- spin_unlock(&sysfs_open_dirent_lock);
+ spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
kfree(od);
}
@@ -456,8 +457,9 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
void sysfs_notify_dirent(struct sysfs_dirent *sd)
{
struct sysfs_open_dirent *od;
+ unsigned long flags;
- spin_lock(&sysfs_open_dirent_lock);
+ spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
od = sd->s_attr.open;
if (od) {
@@ -465,7 +467,7 @@ void sysfs_notify_dirent(struct sysfs_dirent *sd)
wake_up_interruptible(&od->poll);
}
- spin_unlock(&sysfs_open_dirent_lock);
+ spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
}
EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
diff --git a/fs/xattr_acl.c b/fs/xattr_acl.c
index c6ad7c7e3ee9..05ac0fe9c4d3 100644
--- a/fs/xattr_acl.c
+++ b/fs/xattr_acl.c
@@ -36,7 +36,7 @@ posix_acl_from_xattr(const void *value, size_t size)
if (count == 0)
return NULL;
- acl = posix_acl_alloc(count, GFP_KERNEL);
+ acl = posix_acl_alloc(count, GFP_NOFS);
if (!acl)
return ERR_PTR(-ENOMEM);
acl_e = acl->a_entries;
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c
index 9e41f91aa269..3d4a0c84d634 100644
--- a/fs/xfs/linux-2.6/xfs_quotaops.c
+++ b/fs/xfs/linux-2.6/xfs_quotaops.c
@@ -80,7 +80,7 @@ xfs_fs_set_xstate(
if (sb->s_flags & MS_RDONLY)
return -EROFS;
- if (!XFS_IS_QUOTA_RUNNING(mp))
+ if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp))
return -ENOSYS;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 4e4276b956e8..5d1a3b98a6e6 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -876,7 +876,6 @@ xfs_dqrele_inode(
ip->i_gdquot = NULL;
}
xfs_iput(ip, XFS_ILOCK_EXCL);
- IRELE(ip);
return 0;
}
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index ab64f3efb43b..0785797db828 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -880,6 +880,7 @@ nextag:
* Not in range - save last search
* location and allocate a new inode
*/
+ xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
pag->pagl_leftrec = trec.ir_startino;
pag->pagl_rightrec = rec.ir_startino;
pag->pagl_pagino = pagino;
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 1099395d7d6c..fb17f8226b09 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1980,7 +1980,7 @@ xlog_recover_do_reg_buffer(
"XFS: NULL dquot in %s.", __func__);
goto next;
}
- if (item->ri_buf[i].i_len < sizeof(xfs_dqblk_t)) {
+ if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) {
cmn_err(CE_ALERT,
"XFS: dquot too small (%d) in %s.",
item->ri_buf[i].i_len, __func__);
@@ -2635,7 +2635,7 @@ xlog_recover_do_dquot_trans(
"XFS: NULL dquot in %s.", __func__);
return XFS_ERROR(EIO);
}
- if (item->ri_buf[1].i_len < sizeof(xfs_dqblk_t)) {
+ if (item->ri_buf[1].i_len < sizeof(xfs_disk_dquot_t)) {
cmn_err(CE_ALERT,
"XFS: dquot too small (%d) in %s.",
item->ri_buf[1].i_len, __func__);
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index f31271c30de9..2ffc570679be 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -467,6 +467,7 @@ xfs_trans_ail_update(
{
xfs_log_item_t *dlip = NULL;
xfs_log_item_t *mlip; /* ptr to minimum lip */
+ xfs_lsn_t tail_lsn;
mlip = xfs_ail_min(ailp);
@@ -483,8 +484,16 @@ xfs_trans_ail_update(
if (mlip == dlip) {
mlip = xfs_ail_min(ailp);
+ /*
+ * It is not safe to access mlip after the AIL lock is
+ * dropped, so we must get a copy of li_lsn before we do
+ * so. This is especially important on 32-bit platforms
+ * where accessing and updating 64-bit values like li_lsn
+ * is not atomic.
+ */
+ tail_lsn = mlip->li_lsn;
spin_unlock(&ailp->xa_lock);
- xfs_log_move_tail(ailp->xa_mount, mlip->li_lsn);
+ xfs_log_move_tail(ailp->xa_mount, tail_lsn);
} else {
spin_unlock(&ailp->xa_lock);
}
@@ -514,6 +523,7 @@ xfs_trans_ail_delete(
{
xfs_log_item_t *dlip;
xfs_log_item_t *mlip;
+ xfs_lsn_t tail_lsn;
if (lip->li_flags & XFS_LI_IN_AIL) {
mlip = xfs_ail_min(ailp);
@@ -527,9 +537,16 @@ xfs_trans_ail_delete(
if (mlip == dlip) {
mlip = xfs_ail_min(ailp);
+ /*
+ * It is not safe to access mlip after the AIL lock
+ * is dropped, so we must get a copy of li_lsn
+ * before we do so. This is especially important
+ * on 32-bit platforms where accessing and updating
+ * 64-bit values like li_lsn is not atomic.
+ */
+ tail_lsn = mlip ? mlip->li_lsn : 0;
spin_unlock(&ailp->xa_lock);
- xfs_log_move_tail(ailp->xa_mount,
- (mlip ? mlip->li_lsn : 0));
+ xfs_log_move_tail(ailp->xa_mount, tail_lsn);
} else {
spin_unlock(&ailp->xa_lock);
}
diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h
index 0c3dd8603927..495dc8af4044 100644
--- a/include/asm-generic/fcntl.h
+++ b/include/asm-generic/fcntl.h
@@ -73,14 +73,23 @@
#define F_SETSIG 10 /* for sockets. */
#define F_GETSIG 11 /* for sockets. */
#endif
+
+#ifndef CONFIG_64BIT
+#ifndef F_GETLK64
+#define F_GETLK64 12 /* using 'struct flock64' */
+#define F_SETLK64 13
+#define F_SETLKW64 14
+#endif
+#endif
+
#ifndef F_SETOWN_EX
-#define F_SETOWN_EX 12
-#define F_GETOWN_EX 13
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
#endif
#define F_OWNER_TID 0
#define F_OWNER_PID 1
-#define F_OWNER_GID 2
+#define F_OWNER_PGRP 2
struct f_owner_ex {
int type;
@@ -139,12 +148,6 @@ struct flock {
#ifndef CONFIG_64BIT
-#ifndef F_GETLK64
-#define F_GETLK64 12 /* using 'struct flock64' */
-#define F_SETLK64 13
-#define F_SETLKW64 14
-#endif
-
#ifndef HAVE_ARCH_STRUCT_FLOCK64
#ifndef __ARCH_FLOCK64_PAD
#define __ARCH_FLOCK64_PAD
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 3f384d4b163a..5a5385749e16 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -330,6 +330,7 @@ unifdef-y += scc.h
unifdef-y += sched.h
unifdef-y += screen_info.h
unifdef-y += sdla.h
+unifdef-y += securebits.h
unifdef-y += selinux_netlink.h
unifdef-y += sem.h
unifdef-y += serial_core.h
@@ -364,6 +365,7 @@ unifdef-y += utsname.h
unifdef-y += videodev2.h
unifdef-y += videodev.h
unifdef-y += virtio_config.h
+unifdef-y += virtio_ids.h
unifdef-y += virtio_blk.h
unifdef-y += virtio_net.h
unifdef-y += virtio_9p.h
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index dd97fb8408a8..b10ec49ee2dd 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -53,6 +53,7 @@ extern void free_bootmem_node(pg_data_t *pgdat,
unsigned long addr,
unsigned long size);
extern void free_bootmem(unsigned long addr, unsigned long size);
+extern void free_bootmem_late(unsigned long addr, unsigned long size);
/*
* Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE,
diff --git a/include/linux/capability.h b/include/linux/capability.h
index c8f2a5f70ed5..39e5ff512fbe 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -92,9 +92,7 @@ struct vfs_cap_data {
#define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3
#define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
extern int file_caps_enabled;
-#endif
typedef struct kernel_cap_struct {
__u32 cap[_KERNEL_CAPABILITY_U32S];
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index a3ed7cb8ca34..73dcf804bc94 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -79,6 +79,7 @@
#define noinline __attribute__((noinline))
#define __attribute_const__ __attribute__((__const__))
#define __maybe_unused __attribute__((unused))
+#define __always_unused __attribute__((unused))
#define __gcc_header(x) #x
#define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 450fa597c94d..94dea3ffbfa1 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -36,4 +36,26 @@
the kernel context */
#define __cold __attribute__((__cold__))
+
+#if __GNUC_MINOR__ >= 5
+/*
+ * Mark a position in code as unreachable. This can be used to
+ * suppress control flow warnings after asm blocks that transfer
+ * control elsewhere.
+ *
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
+ * this in the preprocessor, but we can live with this because they're
+ * unreleased. Really, we need to have autoconf for the kernel.
+ */
+#define unreachable() __builtin_unreachable()
+#endif
+
+#endif
+
+#if __GNUC_MINOR__ > 0
+#define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
+#endif
+#if __GNUC_MINOR__ >= 4
+#define __compiletime_warning(message) __attribute__((warning(message)))
+#define __compiletime_error(message) __attribute__((error(message)))
#endif
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 04fb5135b4e1..5be3dab4a695 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -144,6 +144,11 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
# define barrier() __memory_barrier()
#endif
+/* Unreachable code */
+#ifndef unreachable
+# define unreachable() do { } while (1)
+#endif
+
#ifndef RELOC_HIDE
# define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
@@ -213,6 +218,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
# define __maybe_unused /* unimplemented */
#endif
+#ifndef __always_unused
+# define __always_unused /* unimplemented */
+#endif
+
#ifndef noinline
#define noinline
#endif
@@ -266,6 +275,17 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#endif
+/* Compile time object size, -1 for unknown */
+#ifndef __compiletime_object_size
+# define __compiletime_object_size(obj) -1
+#endif
+#ifndef __compiletime_warning
+# define __compiletime_warning(message)
+#endif
+#ifndef __compiletime_error
+# define __compiletime_error(message)
+#endif
+
/*
* Prevent the compiler from merging or refetching accesses. The compiler
* is also forbidden from reordering successive instances of ACCESS_ONCE(),
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 44717eb47639..79a2340d83cd 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -291,8 +291,15 @@ struct global_attr {
int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
int cpufreq_update_policy(unsigned int cpu);
+#ifdef CONFIG_CPU_FREQ
/* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
unsigned int cpufreq_get(unsigned int cpu);
+#else
+static inline unsigned int cpufreq_get(unsigned int cpu)
+{
+ return 0;
+}
+#endif
/* query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it */
#ifdef CONFIG_CPU_FREQ
diff --git a/include/linux/device.h b/include/linux/device.h
index aca31bf7d8ed..2ea3e4921812 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -124,7 +124,9 @@ struct device_driver {
struct bus_type *bus;
struct module *owner;
- const char *mod_name; /* used for built-in modules */
+ const char *mod_name; /* used for built-in modules */
+
+ bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 4a2b162c256a..5de4c9e5856d 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -208,16 +208,9 @@ struct dmar_atsr_unit {
u8 include_all:1; /* include all ports */
};
-/* Intel DMAR initialization functions */
extern int intel_iommu_init(void);
-#else
-static inline int intel_iommu_init(void)
-{
-#ifdef CONFIG_INTR_REMAP
- return dmar_dev_scope_init();
-#else
- return -ENODEV;
-#endif
-}
-#endif /* !CONFIG_DMAR */
+#else /* !CONFIG_DMAR: */
+static inline int intel_iommu_init(void) { return -ENODEV; }
+#endif /* CONFIG_DMAR */
+
#endif /* __DMAR_H__ */
diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h
index ca1bfe90004f..93e7428156ba 100644
--- a/include/linux/ext3_fs_i.h
+++ b/include/linux/ext3_fs_i.h
@@ -137,6 +137,14 @@ struct ext3_inode_info {
* by other means, so we have truncate_mutex.
*/
struct mutex truncate_mutex;
+
+ /*
+ * Transactions that contain inode's metadata needed to complete
+ * fsync and fdatasync, respectively.
+ */
+ atomic_t i_sync_tid;
+ atomic_t i_datasync_tid;
+
struct inode vfs_inode;
};
diff --git a/include/linux/fb.h b/include/linux/fb.h
index a34bdf5a9d23..de9c722e7b90 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -669,12 +669,6 @@ struct fb_ops {
/* perform fb specific mmap */
int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
- /* save current hardware state */
- void (*fb_save_state)(struct fb_info *info);
-
- /* restore saved state */
- void (*fb_restore_state)(struct fb_info *info);
-
/* get capability given var */
void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
struct fb_var_screeninfo *var);
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 84d3532dd3ea..7be0c6fbe880 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -91,6 +91,8 @@ struct fscache_operation {
#define FSCACHE_OP_WAITING 4 /* cleared when op is woken */
#define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */
#define FSCACHE_OP_DEAD 6 /* op is now dead */
+#define FSCACHE_OP_DEC_READ_CNT 7 /* decrement object->n_reads on destruction */
+#define FSCACHE_OP_KEEP_FLAGS 0xc0 /* flags to keep when repurposing an op */
atomic_t usage;
unsigned debug_id; /* debugging ID */
@@ -102,6 +104,16 @@ struct fscache_operation {
/* operation releaser */
fscache_operation_release_t release;
+
+#ifdef CONFIG_SLOW_WORK_PROC
+ const char *name; /* operation name */
+ const char *state; /* operation state */
+#define fscache_set_op_name(OP, N) do { (OP)->name = (N); } while(0)
+#define fscache_set_op_state(OP, S) do { (OP)->state = (S); } while(0)
+#else
+#define fscache_set_op_name(OP, N) do { } while(0)
+#define fscache_set_op_state(OP, S) do { } while(0)
+#endif
};
extern atomic_t fscache_op_debug_id;
@@ -125,6 +137,7 @@ static inline void fscache_operation_init(struct fscache_operation *op,
op->debug_id = atomic_inc_return(&fscache_op_debug_id);
op->release = release;
INIT_LIST_HEAD(&op->pend_link);
+ fscache_set_op_state(op, "Init");
}
/**
@@ -221,8 +234,10 @@ struct fscache_cache_ops {
struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
struct fscache_cookie *cookie);
- /* look up the object for a cookie */
- void (*lookup_object)(struct fscache_object *object);
+ /* look up the object for a cookie
+ * - return -ETIMEDOUT to be requeued
+ */
+ int (*lookup_object)(struct fscache_object *object);
/* finished looking up */
void (*lookup_complete)(struct fscache_object *object);
@@ -297,12 +312,14 @@ struct fscache_cookie {
atomic_t usage; /* number of users of this cookie */
atomic_t n_children; /* number of children of this cookie */
spinlock_t lock;
+ spinlock_t stores_lock; /* lock on page store tree */
struct hlist_head backing_objects; /* object(s) backing this file/index */
const struct fscache_cookie_def *def; /* definition */
struct fscache_cookie *parent; /* parent of this entry */
void *netfs_data; /* back pointer to netfs */
struct radix_tree_root stores; /* pages to be stored on this cookie */
#define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */
+#define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */
unsigned long flags;
#define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */
@@ -337,6 +354,7 @@ struct fscache_object {
FSCACHE_OBJECT_RECYCLING, /* retiring object */
FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */
FSCACHE_OBJECT_DEAD, /* object is now dead */
+ FSCACHE_OBJECT__NSTATES
} state;
int debug_id; /* debugging ID */
@@ -345,6 +363,7 @@ struct fscache_object {
int n_obj_ops; /* number of object ops outstanding on object */
int n_in_progress; /* number of ops in progress */
int n_exclusive; /* number of exclusive ops queued */
+ atomic_t n_reads; /* number of read ops in progress */
spinlock_t lock; /* state and operations lock */
unsigned long lookup_jif; /* time at which lookup started */
@@ -358,6 +377,7 @@ struct fscache_object {
#define FSCACHE_OBJECT_EV_RELEASE 4 /* T if netfs requested object release */
#define FSCACHE_OBJECT_EV_RETIRE 5 /* T if netfs requested object retirement */
#define FSCACHE_OBJECT_EV_WITHDRAW 6 /* T if cache requested object withdrawal */
+#define FSCACHE_OBJECT_EVENTS_MASK 0x7f /* mask of all events*/
unsigned long flags;
#define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */
@@ -373,7 +393,11 @@ struct fscache_object {
struct list_head dependents; /* FIFO of dependent objects */
struct list_head dep_link; /* link in parent's dependents list */
struct list_head pending_ops; /* unstarted operations on this object */
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+ struct rb_node objlist_link; /* link in global object list */
+#endif
pgoff_t store_limit; /* current storage limit */
+ loff_t store_limit_l; /* current storage limit */
};
extern const char *fscache_object_states[];
@@ -383,6 +407,10 @@ extern const char *fscache_object_states[];
(obj)->state >= FSCACHE_OBJECT_AVAILABLE && \
(obj)->state < FSCACHE_OBJECT_DYING)
+#define fscache_object_is_dead(obj) \
+ (test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) && \
+ (obj)->state >= FSCACHE_OBJECT_DYING)
+
extern const struct slow_work_ops fscache_object_slow_work_ops;
/**
@@ -414,6 +442,7 @@ void fscache_object_init(struct fscache_object *object,
object->events = object->event_mask = 0;
object->flags = 0;
object->store_limit = 0;
+ object->store_limit_l = 0;
object->cache = cache;
object->cookie = cookie;
object->parent = NULL;
@@ -422,6 +451,12 @@ void fscache_object_init(struct fscache_object *object,
extern void fscache_object_lookup_negative(struct fscache_object *object);
extern void fscache_obtained_object(struct fscache_object *object);
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+extern void fscache_object_destroy(struct fscache_object *object);
+#else
+#define fscache_object_destroy(object) do {} while(0)
+#endif
+
/**
* fscache_object_destroyed - Note destruction of an object in a cache
* @cache: The cache from which the object came
@@ -460,6 +495,7 @@ static inline void fscache_object_lookup_error(struct fscache_object *object)
static inline
void fscache_set_store_limit(struct fscache_object *object, loff_t i_size)
{
+ object->store_limit_l = i_size;
object->store_limit = i_size >> PAGE_SHIFT;
if (i_size & ~PAGE_MASK)
object->store_limit++;
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index 6d8ee466e0a0..595ce49288b7 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -202,6 +202,8 @@ extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t);
extern void __fscache_uncache_page(struct fscache_cookie *, struct page *);
extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *);
extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *);
+extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *,
+ gfp_t);
/**
* fscache_register_netfs - Register a filesystem as desiring caching services
@@ -615,4 +617,29 @@ void fscache_wait_on_page_write(struct fscache_cookie *cookie,
__fscache_wait_on_page_write(cookie, page);
}
+/**
+ * fscache_maybe_release_page - Consider releasing a page, cancelling a store
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page that is being cached.
+ * @gfp: The gfp flags passed to releasepage()
+ *
+ * Consider releasing a page for the vmscan algorithm, on behalf of the netfs's
+ * releasepage() call. A storage request on the page may cancelled if it is
+ * not currently being processed.
+ *
+ * The function returns true if the page no longer has a storage request on it,
+ * and false if a storage request is left in place. If true is returned, the
+ * page will have been passed to fscache_uncache_page(). If false is returned
+ * the page cannot be freed yet.
+ */
+static inline
+bool fscache_maybe_release_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp)
+{
+ if (fscache_cookie_valid(cookie) && PageFsCache(page))
+ return __fscache_maybe_release_page(cookie, page, gfp);
+ return false;
+}
+
#endif /* _LINUX_FSCACHE_H */
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 4ec5e67e18cf..47bbdf9c38d0 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -117,12 +117,12 @@ struct ftrace_event_call {
struct dentry *dir;
struct trace_event *event;
int enabled;
- int (*regfunc)(void *);
- void (*unregfunc)(void *);
+ int (*regfunc)(struct ftrace_event_call *);
+ void (*unregfunc)(struct ftrace_event_call *);
int id;
- int (*raw_init)(void);
- int (*show_format)(struct ftrace_event_call *call,
- struct trace_seq *s);
+ int (*raw_init)(struct ftrace_event_call *);
+ int (*show_format)(struct ftrace_event_call *,
+ struct trace_seq *);
int (*define_fields)(struct ftrace_event_call *);
struct list_head fields;
int filter_active;
@@ -131,20 +131,20 @@ struct ftrace_event_call {
void *data;
atomic_t profile_count;
- int (*profile_enable)(void);
- void (*profile_disable)(void);
+ int (*profile_enable)(struct ftrace_event_call *);
+ void (*profile_disable)(struct ftrace_event_call *);
};
#define FTRACE_MAX_PROFILE_SIZE 2048
-extern char *trace_profile_buf;
-extern char *trace_profile_buf_nmi;
+extern char *perf_trace_buf;
+extern char *perf_trace_buf_nmi;
#define MAX_FILTER_PRED 32
#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */
extern void destroy_preds(struct ftrace_event_call *call);
-extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
+extern int filter_match_preds(struct event_filter *filter, void *rec);
extern int filter_current_check_discard(struct ring_buffer *buffer,
struct ftrace_event_call *call,
void *rec,
@@ -157,11 +157,12 @@ enum {
FILTER_PTR_STRING,
};
-extern int trace_define_field(struct ftrace_event_call *call,
- const char *type, const char *name,
- int offset, int size, int is_signed,
- int filter_type);
extern int trace_define_common_fields(struct ftrace_event_call *call);
+extern int trace_define_field(struct ftrace_event_call *call, const char *type,
+ const char *name, int offset, int size,
+ int is_signed, int filter_type);
+extern int trace_add_event_call(struct ftrace_event_call *call);
+extern void trace_remove_event_call(struct ftrace_event_call *call);
#define is_signed_type(type) (((type)(-1)) < 0)
@@ -186,4 +187,13 @@ do { \
__trace_printk(ip, fmt, ##args); \
} while (0)
+#ifdef CONFIG_EVENT_PROFILE
+struct perf_event;
+extern int ftrace_profile_enable(int event_id);
+extern void ftrace_profile_disable(int event_id);
+extern int ftrace_profile_set_filter(struct perf_event *event, int event_id,
+ char *filter_str);
+extern void ftrace_profile_free_filter(struct perf_event *event);
+#endif
+
#endif /* _LINUX_FTRACE_EVENT_H */
diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
index b80c88dedbbb..81f90a59cda6 100644
--- a/include/linux/gfs2_ondisk.h
+++ b/include/linux/gfs2_ondisk.h
@@ -81,7 +81,11 @@ struct gfs2_meta_header {
__be32 mh_type;
__be64 __pad0; /* Was generation number in gfs1 */
__be32 mh_format;
- __be32 __pad1; /* Was incarnation number in gfs1 */
+ /* This union is to keep userspace happy */
+ union {
+ __be32 mh_jid; /* Was incarnation number in gfs1 */
+ __be32 __pad1;
+ };
};
/*
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 6d527ee82b2b..d5b387669dab 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -139,10 +139,34 @@ static inline void account_system_vtime(struct task_struct *tsk)
#endif
#if defined(CONFIG_NO_HZ)
+#if defined(CONFIG_TINY_RCU)
+extern void rcu_enter_nohz(void);
+extern void rcu_exit_nohz(void);
+
+static inline void rcu_irq_enter(void)
+{
+ rcu_exit_nohz();
+}
+
+static inline void rcu_irq_exit(void)
+{
+ rcu_enter_nohz();
+}
+
+static inline void rcu_nmi_enter(void)
+{
+}
+
+static inline void rcu_nmi_exit(void)
+{
+}
+
+#else
extern void rcu_irq_enter(void);
extern void rcu_irq_exit(void);
extern void rcu_nmi_enter(void);
extern void rcu_nmi_exit(void);
+#endif
#else
# define rcu_irq_enter() do { } while (0)
# define rcu_irq_exit() do { } while (0)
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 10f628416740..87093652dda8 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -312,6 +312,7 @@ struct hid_item {
#define HID_QUIRK_MULTI_INPUT 0x00000040
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
+#define HID_QUIRK_NO_INIT_REPORTS 0x20000000
/*
* This is the global environment of the parser. This information is
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h
new file mode 100644
index 000000000000..a03daed08c59
--- /dev/null
+++ b/include/linux/hw_breakpoint.h
@@ -0,0 +1,131 @@
+#ifndef _LINUX_HW_BREAKPOINT_H
+#define _LINUX_HW_BREAKPOINT_H
+
+enum {
+ HW_BREAKPOINT_LEN_1 = 1,
+ HW_BREAKPOINT_LEN_2 = 2,
+ HW_BREAKPOINT_LEN_4 = 4,
+ HW_BREAKPOINT_LEN_8 = 8,
+};
+
+enum {
+ HW_BREAKPOINT_R = 1,
+ HW_BREAKPOINT_W = 2,
+ HW_BREAKPOINT_X = 4,
+};
+
+#ifdef __KERNEL__
+
+#include <linux/perf_event.h>
+
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+/* As it's for in-kernel or ptrace use, we want it to be pinned */
+#define DEFINE_BREAKPOINT_ATTR(name) \
+struct perf_event_attr name = { \
+ .type = PERF_TYPE_BREAKPOINT, \
+ .size = sizeof(name), \
+ .pinned = 1, \
+};
+
+static inline void hw_breakpoint_init(struct perf_event_attr *attr)
+{
+ attr->type = PERF_TYPE_BREAKPOINT;
+ attr->size = sizeof(*attr);
+ attr->pinned = 1;
+}
+
+static inline unsigned long hw_breakpoint_addr(struct perf_event *bp)
+{
+ return bp->attr.bp_addr;
+}
+
+static inline int hw_breakpoint_type(struct perf_event *bp)
+{
+ return bp->attr.bp_type;
+}
+
+static inline int hw_breakpoint_len(struct perf_event *bp)
+{
+ return bp->attr.bp_len;
+}
+
+extern struct perf_event *
+register_user_hw_breakpoint(struct perf_event_attr *attr,
+ perf_callback_t triggered,
+ struct task_struct *tsk);
+
+/* FIXME: only change from the attr, and don't unregister */
+extern struct perf_event *
+modify_user_hw_breakpoint(struct perf_event *bp,
+ struct perf_event_attr *attr,
+ perf_callback_t triggered,
+ struct task_struct *tsk);
+
+/*
+ * Kernel breakpoints are not associated with any particular thread.
+ */
+extern struct perf_event *
+register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
+ perf_callback_t triggered,
+ int cpu);
+
+extern struct perf_event **
+register_wide_hw_breakpoint(struct perf_event_attr *attr,
+ perf_callback_t triggered);
+
+extern int register_perf_hw_breakpoint(struct perf_event *bp);
+extern int __register_perf_hw_breakpoint(struct perf_event *bp);
+extern void unregister_hw_breakpoint(struct perf_event *bp);
+extern void unregister_wide_hw_breakpoint(struct perf_event **cpu_events);
+
+extern int reserve_bp_slot(struct perf_event *bp);
+extern void release_bp_slot(struct perf_event *bp);
+
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
+{
+ return &bp->hw.info;
+}
+
+#else /* !CONFIG_HAVE_HW_BREAKPOINT */
+
+static inline struct perf_event *
+register_user_hw_breakpoint(struct perf_event_attr *attr,
+ perf_callback_t triggered,
+ struct task_struct *tsk) { return NULL; }
+static inline struct perf_event *
+modify_user_hw_breakpoint(struct perf_event *bp,
+ struct perf_event_attr *attr,
+ perf_callback_t triggered,
+ struct task_struct *tsk) { return NULL; }
+static inline struct perf_event *
+register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
+ perf_callback_t triggered,
+ int cpu) { return NULL; }
+static inline struct perf_event **
+register_wide_hw_breakpoint(struct perf_event_attr *attr,
+ perf_callback_t triggered) { return NULL; }
+static inline int
+register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
+static inline int
+__register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
+static inline void unregister_hw_breakpoint(struct perf_event *bp) { }
+static inline void
+unregister_wide_hw_breakpoint(struct perf_event **cpu_events) { }
+static inline int
+reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; }
+static inline void release_bp_slot(struct perf_event *bp) { }
+
+static inline void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { }
+
+static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_HW_BREAKPOINT_H */
diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h
index f13255e06406..9eb07bbc6522 100644
--- a/include/linux/i2c-pnx.h
+++ b/include/linux/i2c-pnx.h
@@ -21,7 +21,7 @@ struct i2c_pnx_mif {
int mode; /* Interface mode */
struct completion complete; /* I/O completion */
struct timer_list timer; /* Timeout */
- char * buf; /* Data buffer */
+ u8 * buf; /* Data buffer */
int len; /* Length of data buffer */
};
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 57d41b0abce2..7b40cda57a70 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -361,6 +361,24 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data)
dev_set_drvdata(&dev->dev, data);
}
+/**
+ * i2c_lock_adapter - Prevent access to an I2C bus segment
+ * @adapter: Target I2C bus segment
+ */
+static inline void i2c_lock_adapter(struct i2c_adapter *adapter)
+{
+ mutex_lock(&adapter->bus_lock);
+}
+
+/**
+ * i2c_unlock_adapter - Reauthorize access to an I2C bus segment
+ * @adapter: Target I2C bus segment
+ */
+static inline void i2c_unlock_adapter(struct i2c_adapter *adapter)
+{
+ mutex_unlock(&adapter->bus_lock);
+}
+
/*flags for the client struct: */
#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */
#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 21a6f5d9af22..8d10aa7fd4c9 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -83,16 +83,12 @@ extern struct group_info init_groups;
#define INIT_IDS
#endif
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
/*
* Because of the reduced scope of CAP_SETPCAP when filesystem
* capabilities are in effect, it is safe to allow CAP_SETPCAP to
* be available in the default configuration.
*/
# define CAP_INIT_BSET CAP_FULL_SET
-#else
-# define CAP_INIT_BSET CAP_INIT_EFF_SET
-#endif
#ifdef CONFIG_TREE_PREEMPT_RCU
#define INIT_TASK_RCU_PREEMPT(tsk) \
diff --git a/include/linux/input.h b/include/linux/input.h
index 0ccfc30cd40f..c2b1a7d244d9 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1377,6 +1377,10 @@ extern struct class input_class;
* methods; erase() is optional. set_gain() and set_autocenter() need
* only be implemented if driver sets up FF_GAIN and FF_AUTOCENTER
* bits.
+ *
+ * Note that playback(), set_gain() and set_autocenter() are called with
+ * dev->event_lock spinlock held and interrupts off and thus may not
+ * sleep.
*/
struct ff_device {
int (*upload)(struct input_dev *dev, struct ff_effect *effect,
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 7ca72b74eec7..75f3f00ac1e5 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -603,12 +603,6 @@ static inline void init_irq_proc(void)
}
#endif
-#if defined(CONFIG_GENERIC_HARDIRQS) && defined(CONFIG_DEBUG_SHIRQ)
-extern void debug_poll_all_shared_irqs(void);
-#else
-static inline void debug_poll_all_shared_irqs(void) { }
-#endif
-
struct seq_file;
int show_interrupts(struct seq_file *p, void *v);
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index b02a3f1d46a0..006bf45eae30 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -124,6 +124,6 @@
typecheck(unsigned long, flags); \
raw_irqs_disabled_flags(flags); \
})
-#endif /* CONFIG_X86 */
+#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */
#endif
diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h
index 4c218ee7587a..8687a7dc0632 100644
--- a/include/linux/isdn_ppp.h
+++ b/include/linux/isdn_ppp.h
@@ -157,7 +157,7 @@ typedef struct {
typedef struct {
int mp_mrru; /* unused */
- struct sk_buff_head frags; /* fragments sl list */
+ struct sk_buff * frags; /* fragments sl list -- use skb->next */
long frames; /* number of frames in the frame list */
unsigned int seq; /* last processed packet seq #: any packets
* with smaller seq # will be dropped
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 1a9cf78bfce5..6811f4bfc6e7 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -307,6 +307,7 @@ extern clock_t jiffies_to_clock_t(long x);
extern unsigned long clock_t_to_jiffies(unsigned long x);
extern u64 jiffies_64_to_clock_t(u64 x);
extern u64 nsec_to_clock_t(u64 x);
+extern unsigned long nsecs_to_jiffies(u64 n);
#define TIMESTAMP_SIZE 30
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f4e3184fa054..3fa4c590cf12 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -15,7 +15,6 @@
#include <linux/bitops.h>
#include <linux/log2.h>
#include <linux/typecheck.h>
-#include <linux/ratelimit.h>
#include <linux/dynamic_debug.h>
#include <asm/byteorder.h>
#include <asm/bug.h>
@@ -241,8 +240,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
asmlinkage int printk(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2))) __cold;
-extern struct ratelimit_state printk_ratelimit_state;
-extern int printk_ratelimit(void);
+extern int __printk_ratelimit(const char *func);
+#define printk_ratelimit() __printk_ratelimit(__func__)
extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
unsigned int interval_msec);
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 348fa8874b52..c059044bc6dc 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -25,6 +25,7 @@ struct cpu_usage_stat {
cputime64_t iowait;
cputime64_t steal;
cputime64_t guest;
+ cputime64_t guest_nice;
};
struct kernel_stat {
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 3a46b7b7abb2..1b672f74a32f 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -296,6 +296,8 @@ void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
int disable_kprobe(struct kprobe *kp);
int enable_kprobe(struct kprobe *kp);
+void dump_kprobe(struct kprobe *kp);
+
#else /* !CONFIG_KPROBES: */
static inline int kprobes_built_in(void)
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 190c37854870..f78f83d7663f 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -26,14 +26,15 @@
/* Auxiliary data to use in generating the audit record. */
struct common_audit_data {
- char type;
-#define LSM_AUDIT_DATA_FS 1
-#define LSM_AUDIT_DATA_NET 2
-#define LSM_AUDIT_DATA_CAP 3
-#define LSM_AUDIT_DATA_IPC 4
-#define LSM_AUDIT_DATA_TASK 5
-#define LSM_AUDIT_DATA_KEY 6
-#define LSM_AUDIT_NO_AUDIT 7
+ char type;
+#define LSM_AUDIT_DATA_FS 1
+#define LSM_AUDIT_DATA_NET 2
+#define LSM_AUDIT_DATA_CAP 3
+#define LSM_AUDIT_DATA_IPC 4
+#define LSM_AUDIT_DATA_TASK 5
+#define LSM_AUDIT_DATA_KEY 6
+#define LSM_AUDIT_NO_AUDIT 7
+#define LSM_AUDIT_DATA_KMOD 8
struct task_struct *tsk;
union {
struct {
@@ -66,6 +67,7 @@ struct common_audit_data {
char *key_desc;
} key_struct;
#endif
+ char *kmod_name;
} u;
/* this union contains LSM specific data */
union {
diff --git a/include/linux/mfd/wm831x/regulator.h b/include/linux/mfd/wm831x/regulator.h
index f95466343fb2..955d30fc6a27 100644
--- a/include/linux/mfd/wm831x/regulator.h
+++ b/include/linux/mfd/wm831x/regulator.h
@@ -1212,7 +1212,7 @@
#define WM831X_LDO1_OK_SHIFT 0 /* LDO1_OK */
#define WM831X_LDO1_OK_WIDTH 1 /* LDO1_OK */
-#define WM831X_ISINK_MAX_ISEL 56
-extern int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL];
+#define WM831X_ISINK_MAX_ISEL 55
+extern int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1];
#endif
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 6547c3cdbc4c..82a9124f7d75 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -37,7 +37,6 @@ typedef int (*param_set_fn)(const char *val, struct kernel_param *kp);
typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp);
/* Flag bits for kernel_param.flags */
-#define KPARAM_KMALLOCED 1
#define KPARAM_ISBOOL 2
struct kernel_param {
diff --git a/include/linux/net.h b/include/linux/net.h
index 529a0931711d..d7e26e30c8c2 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -358,6 +358,7 @@ static const struct proto_ops name##_ops = { \
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
+#include <linux/ratelimit.h>
extern struct ratelimit_state net_ratelimit_state;
#endif
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 94958c109761..812a5f3c2abe 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -557,7 +557,7 @@ struct netdev_queue {
* Callback uses when the transmitter has not made any progress
* for dev->watchdog ticks.
*
- * struct net_device_stats* (*get_stats)(struct net_device *dev);
+ * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
* Called when a user wants to get the network device usage
* statistics. If not defined, the counters in dev->stats will
* be used.
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
index 79fec6af3f9f..ce520402e840 100644
--- a/include/linux/nilfs2_fs.h
+++ b/include/linux/nilfs2_fs.h
@@ -425,15 +425,6 @@ struct nilfs_dat_entry {
};
/**
- * struct nilfs_dat_group_desc - block group descriptor
- * @dg_nfrees: number of free virtual block numbers in block group
- */
-struct nilfs_dat_group_desc {
- __le32 dg_nfrees;
-};
-
-
-/**
* struct nilfs_snapshot_list - snapshot list
* @ssl_next: next checkpoint number on snapshot list
* @ssl_prev: previous checkpoint number on snapshot list
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f490e7a7307a..daecca3c8300 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -379,9 +379,6 @@
#define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c
#define PCI_DEVICE_ID_ATI_IXP700_SATA 0x4390
#define PCI_DEVICE_ID_ATI_IXP700_IDE 0x439c
-/* AMD SB Chipset */
-#define PCI_DEVICE_ID_AMD_SB900_IDE 0x780c
-#define PCI_DEVICE_ID_AMD_SB900_SATA_IDE 0x7800
#define PCI_VENDOR_ID_VLSI 0x1004
#define PCI_DEVICE_ID_VLSI_82C592 0x0005
@@ -485,6 +482,9 @@
#define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE 0x0361
#define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252
+#define PCI_SUBVENDOR_ID_IBM 0x1014
+#define PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT 0x03d4
+
#define PCI_VENDOR_ID_UNISYS 0x1018
#define PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR 0x001C
@@ -543,7 +543,7 @@
#define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450
#define PCI_DEVICE_ID_AMD_8131_APIC 0x7451
#define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458
-#define PCI_DEVICE_ID_AMD_SB900_SMBUS 0x780b
+#define PCI_DEVICE_ID_AMD_HUDSON2_SMBUS 0x780b
#define PCI_DEVICE_ID_AMD_CS5535_IDE 0x208F
#define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090
#define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091
@@ -553,9 +553,10 @@
#define PCI_DEVICE_ID_AMD_CS5536_UDC 0x2096
#define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097
#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A
-
#define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081
#define PCI_DEVICE_ID_AMD_LX_AES 0x2082
+#define PCI_DEVICE_ID_AMD_HUDSON2_IDE 0x780c
+#define PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE 0x7800
#define PCI_VENDOR_ID_TRIDENT 0x1023
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
@@ -1632,6 +1633,8 @@
#define PCI_DEVICE_ID_O2_6730 0x673a
#define PCI_DEVICE_ID_O2_6832 0x6832
#define PCI_DEVICE_ID_O2_6836 0x6836
+#define PCI_DEVICE_ID_O2_6812 0x6872
+#define PCI_DEVICE_ID_O2_6933 0x6933
#define PCI_VENDOR_ID_3DFX 0x121a
#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001
@@ -1955,6 +1958,8 @@
#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */
#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */
#define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */
+#define PCI_DEVICE_ID_LAVA_QUATTRO_A 0x0120 /* 2x 16550A, half of 4 port */
+#define PCI_DEVICE_ID_LAVA_QUATTRO_B 0x0121 /* 2x 16550A, half of 4 port */
#define PCI_DEVICE_ID_LAVA_OCTO_A 0x0180 /* 4x 16550A, half of 8 port */
#define PCI_DEVICE_ID_LAVA_OCTO_B 0x0181 /* 4x 16550A, half of 8 port */
#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */
@@ -2162,6 +2167,10 @@
#define PCI_DEVICE_ID_ADDIDATA_APCI7420_3 0x700D
#define PCI_DEVICE_ID_ADDIDATA_APCI7300_3 0x700E
#define PCI_DEVICE_ID_ADDIDATA_APCI7800_3 0x700F
+#define PCI_DEVICE_ID_ADDIDATA_APCIe7300 0x7010
+#define PCI_DEVICE_ID_ADDIDATA_APCIe7420 0x7011
+#define PCI_DEVICE_ID_ADDIDATA_APCIe7500 0x7012
+#define PCI_DEVICE_ID_ADDIDATA_APCIe7800 0x7013
#define PCI_VENDOR_ID_PDC 0x15e9
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index 7b7fbf433cff..e3fb25606706 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -106,6 +106,8 @@ enum perf_sw_ids {
PERF_COUNT_SW_CPU_MIGRATIONS = 4,
PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
+ PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
+ PERF_COUNT_SW_EMULATION_FAULTS = 8,
PERF_COUNT_SW_MAX, /* non-ABI */
};
@@ -225,6 +227,7 @@ struct perf_counter_attr {
#define PERF_COUNTER_IOC_RESET _IO ('$', 3)
#define PERF_COUNTER_IOC_PERIOD _IOW('$', 4, u64)
#define PERF_COUNTER_IOC_SET_OUTPUT _IO ('$', 5)
+#define PERF_COUNTER_IOC_SET_FILTER _IOW('$', 6, char *)
enum perf_counter_ioc_flags {
PERF_IOC_FLAG_GROUP = 1U << 0,
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2e6d95f97419..43adbd7f0010 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -18,6 +18,10 @@
#include <linux/ioctl.h>
#include <asm/byteorder.h>
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+#include <asm/hw_breakpoint.h>
+#endif
+
/*
* User-space ABI bits:
*/
@@ -31,6 +35,7 @@ enum perf_type_id {
PERF_TYPE_TRACEPOINT = 2,
PERF_TYPE_HW_CACHE = 3,
PERF_TYPE_RAW = 4,
+ PERF_TYPE_BREAKPOINT = 5,
PERF_TYPE_MAX, /* non-ABI */
};
@@ -102,6 +107,8 @@ enum perf_sw_ids {
PERF_COUNT_SW_CPU_MIGRATIONS = 4,
PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
+ PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
+ PERF_COUNT_SW_EMULATION_FAULTS = 8,
PERF_COUNT_SW_MAX, /* non-ABI */
};
@@ -207,6 +214,15 @@ struct perf_event_attr {
__u32 wakeup_events; /* wakeup every n events */
__u32 wakeup_watermark; /* bytes before wakeup */
};
+
+ union {
+ struct { /* Hardware breakpoint info */
+ __u64 bp_addr;
+ __u32 bp_type;
+ __u32 bp_len;
+ };
+ };
+
__u32 __reserved_2;
__u64 __reserved_3;
@@ -219,8 +235,9 @@ struct perf_event_attr {
#define PERF_EVENT_IOC_DISABLE _IO ('$', 1)
#define PERF_EVENT_IOC_REFRESH _IO ('$', 2)
#define PERF_EVENT_IOC_RESET _IO ('$', 3)
-#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, u64)
+#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64)
#define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5)
+#define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *)
enum perf_event_ioc_flags {
PERF_IOC_FLAG_GROUP = 1U << 0,
@@ -471,10 +488,15 @@ struct hw_perf_event {
unsigned long event_base;
int idx;
};
- union { /* software */
- atomic64_t count;
+ struct { /* software */
+ s64 remaining;
struct hrtimer hrtimer;
};
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ union { /* breakpoint */
+ struct arch_hw_breakpoint info;
+ };
+#endif
};
atomic64_t prev_count;
u64 sample_period;
@@ -543,6 +565,10 @@ struct perf_pending_entry {
void (*func)(struct perf_pending_entry *);
};
+typedef void (*perf_callback_t)(struct perf_event *, void *);
+
+struct perf_sample_data;
+
/**
* struct perf_event - performance event kernel representation:
*/
@@ -585,7 +611,7 @@ struct perf_event {
u64 tstamp_running;
u64 tstamp_stopped;
- struct perf_event_attr attr;
+ struct perf_event_attr attr;
struct hw_perf_event hw;
struct perf_event_context *ctx;
@@ -633,7 +659,20 @@ struct perf_event {
struct pid_namespace *ns;
u64 id;
+
+ void (*overflow_handler)(struct perf_event *event,
+ int nmi, struct perf_sample_data *data,
+ struct pt_regs *regs);
+
+#ifdef CONFIG_EVENT_PROFILE
+ struct event_filter *filter;
#endif
+
+ perf_callback_t callback;
+
+ perf_callback_t event_callback;
+
+#endif /* CONFIG_PERF_EVENTS */
};
/**
@@ -706,7 +745,6 @@ struct perf_output_handle {
int nmi;
int sample;
int locked;
- unsigned long flags;
};
#ifdef CONFIG_PERF_EVENTS
@@ -738,6 +776,14 @@ extern int hw_perf_group_sched_in(struct perf_event *group_leader,
struct perf_cpu_context *cpuctx,
struct perf_event_context *ctx, int cpu);
extern void perf_event_update_userpage(struct perf_event *event);
+extern int perf_event_release_kernel(struct perf_event *event);
+extern struct perf_event *
+perf_event_create_kernel_counter(struct perf_event_attr *attr,
+ int cpu,
+ pid_t pid,
+ perf_callback_t callback);
+extern u64 perf_event_read_value(struct perf_event *event,
+ u64 *enabled, u64 *running);
struct perf_sample_data {
u64 type;
@@ -814,6 +860,7 @@ extern int sysctl_perf_event_sample_rate;
extern void perf_event_init(void);
extern void perf_tp_event(int event_id, u64 addr, u64 count,
void *record, int entry_size);
+extern void perf_bp_event(struct perf_event *event, void *data);
#ifndef perf_misc_flags
#define perf_misc_flags(regs) (user_mode(regs) ? PERF_RECORD_MISC_USER : \
@@ -827,6 +874,8 @@ extern int perf_output_begin(struct perf_output_handle *handle,
extern void perf_output_end(struct perf_output_handle *handle);
extern void perf_output_copy(struct perf_output_handle *handle,
const void *buf, unsigned int len);
+extern int perf_swevent_get_recursion_context(void);
+extern void perf_swevent_put_recursion_context(int rctx);
#else
static inline void
perf_event_task_sched_in(struct task_struct *task, int cpu) { }
@@ -848,11 +897,15 @@ static inline int perf_event_task_enable(void) { return -EINVAL; }
static inline void
perf_sw_event(u32 event_id, u64 nr, int nmi,
struct pt_regs *regs, u64 addr) { }
+static inline void
+perf_bp_event(struct perf_event *event, void *data) { }
static inline void perf_event_mmap(struct vm_area_struct *vma) { }
static inline void perf_event_comm(struct task_struct *tsk) { }
static inline void perf_event_fork(struct task_struct *tsk) { }
static inline void perf_event_init(void) { }
+static inline int perf_swevent_get_recursion_context(void) { return -1; }
+static inline void perf_swevent_put_recursion_context(int rctx) { }
#endif
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 065a3652a3ea..67608161df6b 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -147,6 +147,20 @@ static inline void forget_cached_acl(struct inode *inode, int type)
if (old != ACL_NOT_CACHED)
posix_acl_release(old);
}
+
+static inline void forget_all_cached_acls(struct inode *inode)
+{
+ struct posix_acl *old_access, *old_default;
+ spin_lock(&inode->i_lock);
+ old_access = inode->i_acl;
+ old_default = inode->i_default_acl;
+ inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
+ spin_unlock(&inode->i_lock);
+ if (old_access != ACL_NOT_CACHED)
+ posix_acl_release(old_access);
+ if (old_default != ACL_NOT_CACHED)
+ posix_acl_release(old_default);
+}
#endif
static inline void cache_no_acl(struct inode *inode)
diff --git a/include/linux/prctl.h b/include/linux/prctl.h
index 931150566ade..a3baeb2c2161 100644
--- a/include/linux/prctl.h
+++ b/include/linux/prctl.h
@@ -88,6 +88,18 @@
#define PR_TASK_PERF_EVENTS_DISABLE 31
#define PR_TASK_PERF_EVENTS_ENABLE 32
+/*
+ * Set early/late kill mode for hwpoison memory corruption.
+ * This influences when the process gets killed on a memory corruption.
+ */
#define PR_MCE_KILL 33
+# define PR_MCE_KILL_CLEAR 0
+# define PR_MCE_KILL_SET 1
+
+# define PR_MCE_KILL_LATE 0
+# define PR_MCE_KILL_EARLY 1
+# define PR_MCE_KILL_DEFAULT 2
+
+#define PR_MCE_KILL_GET 34
#endif /* _LINUX_PRCTL_H */
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 72b1a10a59b6..2e681d9555bd 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -105,6 +105,11 @@ struct preempt_notifier;
* @sched_out: we've just been preempted
* notifier: struct preempt_notifier for the task being preempted
* next: the task that's kicking us out
+ *
+ * Please note that sched_in and out are called under different
+ * contexts. sched_out is called with rq lock held and irq disabled
+ * while sched_in is called without rq lock and irq enabled. This
+ * difference is intentional and depended upon by its users.
*/
struct preempt_ops {
void (*sched_in)(struct preempt_notifier *notifier, int cpu);
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 78c48895b12a..ce9a9b2e5cd4 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -376,6 +376,17 @@ static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
return flags >> _DQUOT_STATE_FLAGS;
}
+#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
+extern void quota_send_warning(short type, unsigned int id, dev_t dev,
+ const char warntype);
+#else
+static inline void quota_send_warning(short type, unsigned int id, dev_t dev,
+ const char warntype)
+{
+ return;
+}
+#endif /* CONFIG_QUOTA_NETLINK_INTERFACE */
+
struct quota_info {
unsigned int flags; /* Flags for diskquotas on this device */
struct mutex dqio_mutex; /* lock device while I/O in progress */
diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h
index 00044b856453..668cf1bef030 100644
--- a/include/linux/ratelimit.h
+++ b/include/linux/ratelimit.h
@@ -1,20 +1,31 @@
#ifndef _LINUX_RATELIMIT_H
#define _LINUX_RATELIMIT_H
+
#include <linux/param.h>
+#include <linux/spinlock_types.h>
-#define DEFAULT_RATELIMIT_INTERVAL (5 * HZ)
-#define DEFAULT_RATELIMIT_BURST 10
+#define DEFAULT_RATELIMIT_INTERVAL (5 * HZ)
+#define DEFAULT_RATELIMIT_BURST 10
struct ratelimit_state {
- int interval;
- int burst;
- int printed;
- int missed;
- unsigned long begin;
+ spinlock_t lock; /* protect the state */
+
+ int interval;
+ int burst;
+ int printed;
+ int missed;
+ unsigned long begin;
};
-#define DEFINE_RATELIMIT_STATE(name, interval, burst) \
- struct ratelimit_state name = {interval, burst,}
+#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) \
+ \
+ struct ratelimit_state name = { \
+ .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
+ .interval = interval_init, \
+ .burst = burst_init, \
+ }
+
+extern int ___ratelimit(struct ratelimit_state *rs, const char *func);
+#define __ratelimit(state) ___ratelimit(state, __func__)
-extern int __ratelimit(struct ratelimit_state *rs);
-#endif
+#endif /* _LINUX_RATELIMIT_H */
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 3ebd0b7bcb08..24440f4bf476 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -52,11 +52,6 @@ struct rcu_head {
};
/* Exported common interfaces */
-#ifdef CONFIG_TREE_PREEMPT_RCU
-extern void synchronize_rcu(void);
-#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
-#define synchronize_rcu synchronize_sched
-#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
extern void synchronize_rcu_bh(void);
extern void synchronize_sched(void);
extern void rcu_barrier(void);
@@ -67,12 +62,11 @@ extern int sched_expedited_torture_stats(char *page);
/* Internal to kernel */
extern void rcu_init(void);
-extern void rcu_scheduler_starting(void);
-extern int rcu_needs_cpu(int cpu);
-extern int rcu_scheduler_active;
#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
#include <linux/rcutree.h>
+#elif defined(CONFIG_TINY_RCU)
+#include <linux/rcutiny.h>
#else
#error "Unknown RCU implementation specified to kernel configuration"
#endif
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
new file mode 100644
index 000000000000..c4ba9a78721e
--- /dev/null
+++ b/include/linux/rcutiny.h
@@ -0,0 +1,104 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion, the Bloatwatch edition.
+ *
+ * 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.
+ *
+ * Copyright IBM Corporation, 2008
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ * Documentation/RCU
+ */
+#ifndef __LINUX_TINY_H
+#define __LINUX_TINY_H
+
+#include <linux/cache.h>
+
+void rcu_sched_qs(int cpu);
+void rcu_bh_qs(int cpu);
+
+#define __rcu_read_lock() preempt_disable()
+#define __rcu_read_unlock() preempt_enable()
+#define __rcu_read_lock_bh() local_bh_disable()
+#define __rcu_read_unlock_bh() local_bh_enable()
+#define call_rcu_sched call_rcu
+
+#define rcu_init_sched() do { } while (0)
+extern void rcu_check_callbacks(int cpu, int user);
+
+static inline int rcu_needs_cpu(int cpu)
+{
+ return 0;
+}
+
+/*
+ * Return the number of grace periods.
+ */
+static inline long rcu_batches_completed(void)
+{
+ return 0;
+}
+
+/*
+ * Return the number of bottom-half grace periods.
+ */
+static inline long rcu_batches_completed_bh(void)
+{
+ return 0;
+}
+
+extern int rcu_expedited_torture_stats(char *page);
+
+#define synchronize_rcu synchronize_sched
+
+static inline void synchronize_rcu_expedited(void)
+{
+ synchronize_sched();
+}
+
+static inline void synchronize_rcu_bh_expedited(void)
+{
+ synchronize_sched();
+}
+
+struct notifier_block;
+
+#ifdef CONFIG_NO_HZ
+
+extern void rcu_enter_nohz(void);
+extern void rcu_exit_nohz(void);
+
+#else /* #ifdef CONFIG_NO_HZ */
+
+static inline void rcu_enter_nohz(void)
+{
+}
+
+static inline void rcu_exit_nohz(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_NO_HZ */
+
+static inline void rcu_scheduler_starting(void)
+{
+}
+
+static inline void exit_rcu(void)
+{
+}
+
+#endif /* __LINUX_RCUTINY_H */
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index 46e9ab3ee6e1..c93eee5911b0 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -34,15 +34,15 @@ struct notifier_block;
extern void rcu_sched_qs(int cpu);
extern void rcu_bh_qs(int cpu);
-extern int rcu_cpu_notify(struct notifier_block *self,
- unsigned long action, void *hcpu);
extern int rcu_needs_cpu(int cpu);
+extern void rcu_scheduler_starting(void);
extern int rcu_expedited_torture_stats(char *page);
#ifdef CONFIG_TREE_PREEMPT_RCU
extern void __rcu_read_lock(void);
extern void __rcu_read_unlock(void);
+extern void synchronize_rcu(void);
extern void exit_rcu(void);
#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
@@ -57,7 +57,7 @@ static inline void __rcu_read_unlock(void)
preempt_enable();
}
-#define __synchronize_sched() synchronize_rcu()
+#define synchronize_rcu synchronize_sched
static inline void exit_rcu(void)
{
@@ -76,18 +76,13 @@ static inline void __rcu_read_unlock_bh(void)
extern void call_rcu_sched(struct rcu_head *head,
void (*func)(struct rcu_head *rcu));
-
-static inline void synchronize_rcu_expedited(void)
-{
- synchronize_sched_expedited();
-}
+extern void synchronize_rcu_expedited(void);
static inline void synchronize_rcu_bh_expedited(void)
{
synchronize_sched_expedited();
}
-extern void __rcu_init(void);
extern void rcu_check_callbacks(int cpu, int user);
extern long rcu_batches_completed(void);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 75e6e60bf583..89115ec7d43f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -145,7 +145,6 @@ extern unsigned long this_cpu_load(void);
extern void calc_global_load(void);
-extern u64 cpu_nr_migrations(int cpu);
extern unsigned long get_parent_ip(unsigned long addr);
@@ -171,8 +170,6 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
}
#endif
-extern unsigned long long time_sync_thresh;
-
/*
* Task state bitmask. NOTE! These bits are also
* encoded in fs/proc/array.c: get_task_state().
@@ -349,7 +346,6 @@ extern signed long schedule_timeout(signed long timeout);
extern signed long schedule_timeout_interruptible(signed long timeout);
extern signed long schedule_timeout_killable(signed long timeout);
extern signed long schedule_timeout_uninterruptible(signed long timeout);
-asmlinkage void __schedule(void);
asmlinkage void schedule(void);
extern int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner);
@@ -628,6 +624,9 @@ struct signal_struct {
cputime_t utime, stime, cutime, cstime;
cputime_t gtime;
cputime_t cgtime;
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+ cputime_t prev_utime, prev_stime;
+#endif
unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
unsigned long inblock, oublock, cinblock, coublock;
@@ -1013,9 +1012,13 @@ static inline struct cpumask *sched_domain_span(struct sched_domain *sd)
return to_cpumask(sd->span);
}
-extern void partition_sched_domains(int ndoms_new, struct cpumask *doms_new,
+extern void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
struct sched_domain_attr *dattr_new);
+/* Allocate an array of sched domains, for partition_sched_domains(). */
+cpumask_var_t *alloc_sched_domains(unsigned int ndoms);
+void free_sched_domains(cpumask_var_t doms[], unsigned int ndoms);
+
/* Test a flag in parent sched domain */
static inline int test_sd_parent(struct sched_domain *sd, int flag)
{
@@ -1033,7 +1036,7 @@ unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu);
struct sched_domain_attr;
static inline void
-partition_sched_domains(int ndoms_new, struct cpumask *doms_new,
+partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
struct sched_domain_attr *dattr_new)
{
}
@@ -1331,7 +1334,9 @@ struct task_struct {
cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
cputime_t prev_utime, prev_stime;
+#endif
unsigned long nvcsw, nivcsw; /* context switch counts */
struct timespec start_time; /* monotonic time */
struct timespec real_start_time; /* boot based time */
@@ -1421,17 +1426,17 @@ struct task_struct {
#endif
#ifdef CONFIG_TRACE_IRQFLAGS
unsigned int irq_events;
- int hardirqs_enabled;
unsigned long hardirq_enable_ip;
- unsigned int hardirq_enable_event;
unsigned long hardirq_disable_ip;
+ unsigned int hardirq_enable_event;
unsigned int hardirq_disable_event;
- int softirqs_enabled;
+ int hardirqs_enabled;
+ int hardirq_context;
unsigned long softirq_disable_ip;
- unsigned int softirq_disable_event;
unsigned long softirq_enable_ip;
+ unsigned int softirq_disable_event;
unsigned int softirq_enable_event;
- int hardirq_context;
+ int softirqs_enabled;
int softirq_context;
#endif
#ifdef CONFIG_LOCKDEP
@@ -1720,9 +1725,8 @@ static inline void put_task_struct(struct task_struct *t)
__put_task_struct(t);
}
-extern cputime_t task_utime(struct task_struct *p);
-extern cputime_t task_stime(struct task_struct *p);
-extern cputime_t task_gtime(struct task_struct *p);
+extern void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st);
+extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st);
/*
* Per process flags
@@ -2086,11 +2090,18 @@ static inline int is_si_special(const struct siginfo *info)
return info <= SEND_SIG_FORCED;
}
-/* True if we are on the alternate signal stack. */
-
+/*
+ * True if we are on the alternate signal stack.
+ */
static inline int on_sig_stack(unsigned long sp)
{
- return (sp - current->sas_ss_sp < current->sas_ss_size);
+#ifdef CONFIG_STACK_GROWSUP
+ return sp >= current->sas_ss_sp &&
+ sp - current->sas_ss_sp < current->sas_ss_size;
+#else
+ return sp > current->sas_ss_sp &&
+ sp - current->sas_ss_sp <= current->sas_ss_size;
+#endif
}
static inline int sas_ss_flags(unsigned long sp)
diff --git a/include/linux/securebits.h b/include/linux/securebits.h
index d2c5ed845bcc..33406174cbe8 100644
--- a/include/linux/securebits.h
+++ b/include/linux/securebits.h
@@ -1,6 +1,15 @@
#ifndef _LINUX_SECUREBITS_H
#define _LINUX_SECUREBITS_H 1
+/* Each securesetting is implemented using two bits. One bit specifies
+ whether the setting is on or off. The other bit specify whether the
+ setting is locked or not. A setting which is locked cannot be
+ changed from user-level. */
+#define issecure_mask(X) (1 << (X))
+#ifdef __KERNEL__
+#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits))
+#endif
+
#define SECUREBITS_DEFAULT 0x00000000
/* When set UID 0 has no special privileges. When unset, we support
@@ -12,6 +21,9 @@
#define SECURE_NOROOT 0
#define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */
+#define SECBIT_NOROOT (issecure_mask(SECURE_NOROOT))
+#define SECBIT_NOROOT_LOCKED (issecure_mask(SECURE_NOROOT_LOCKED))
+
/* When set, setuid to/from uid 0 does not trigger capability-"fixup".
When unset, to provide compatiblility with old programs relying on
set*uid to gain/lose privilege, transitions to/from uid 0 cause
@@ -19,6 +31,10 @@
#define SECURE_NO_SETUID_FIXUP 2
#define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */
+#define SECBIT_NO_SETUID_FIXUP (issecure_mask(SECURE_NO_SETUID_FIXUP))
+#define SECBIT_NO_SETUID_FIXUP_LOCKED \
+ (issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED))
+
/* When set, a process can retain its capabilities even after
transitioning to a non-root user (the set-uid fixup suppressed by
bit 2). Bit-4 is cleared when a process calls exec(); setting both
@@ -27,12 +43,8 @@
#define SECURE_KEEP_CAPS 4
#define SECURE_KEEP_CAPS_LOCKED 5 /* make bit-4 immutable */
-/* Each securesetting is implemented using two bits. One bit specifies
- whether the setting is on or off. The other bit specify whether the
- setting is locked or not. A setting which is locked cannot be
- changed from user-level. */
-#define issecure_mask(X) (1 << (X))
-#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits))
+#define SECBIT_KEEP_CAPS (issecure_mask(SECURE_KEEP_CAPS))
+#define SECBIT_KEEP_CAPS_LOCKED (issecure_mask(SECURE_KEEP_CAPS_LOCKED))
#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \
issecure_mask(SECURE_NO_SETUID_FIXUP) | \
diff --git a/include/linux/security.h b/include/linux/security.h
index 239e40d0450b..466cbadbd1ef 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -447,6 +447,22 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @new_dir contains the path structure for parent of the new link.
* @new_dentry contains the dentry structure of the new link.
* Return 0 if permission is granted.
+ * @path_chmod:
+ * Check for permission to change DAC's permission of a file or directory.
+ * @dentry contains the dentry structure.
+ * @mnt contains the vfsmnt structure.
+ * @mode contains DAC's mode.
+ * Return 0 if permission is granted.
+ * @path_chown:
+ * Check for permission to change owner/group of a file or directory.
+ * @path contains the path structure.
+ * @uid contains new owner's ID.
+ * @gid contains new group's ID.
+ * Return 0 if permission is granted.
+ * @path_chroot:
+ * Check for permission to change root directory.
+ * @path contains the path structure.
+ * Return 0 if permission is granted.
* @inode_readlink:
* Check the permission to read the symbolic link.
* @dentry contains the dentry structure for the file link.
@@ -690,6 +706,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @kernel_module_request:
* Ability to trigger the kernel to automatically upcall to userspace for
* userspace to load a kernel module with the given name.
+ * @kmod_name name of the module requested by the kernel
* Return 0 if successful.
* @task_setuid:
* Check permission before setting one or more of the user identity
@@ -1488,6 +1505,10 @@ struct security_operations {
struct dentry *new_dentry);
int (*path_rename) (struct path *old_dir, struct dentry *old_dentry,
struct path *new_dir, struct dentry *new_dentry);
+ int (*path_chmod) (struct dentry *dentry, struct vfsmount *mnt,
+ mode_t mode);
+ int (*path_chown) (struct path *path, uid_t uid, gid_t gid);
+ int (*path_chroot) (struct path *path);
#endif
int (*inode_alloc_security) (struct inode *inode);
@@ -1557,7 +1578,7 @@ struct security_operations {
void (*cred_transfer)(struct cred *new, const struct cred *old);
int (*kernel_act_as)(struct cred *new, u32 secid);
int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
- int (*kernel_module_request)(void);
+ int (*kernel_module_request)(char *kmod_name);
int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
int (*task_fix_setuid) (struct cred *new, const struct cred *old,
int flags);
@@ -1822,7 +1843,7 @@ void security_commit_creds(struct cred *new, const struct cred *old);
void security_transfer_creds(struct cred *new, const struct cred *old);
int security_kernel_act_as(struct cred *new, u32 secid);
int security_kernel_create_files_as(struct cred *new, struct inode *inode);
-int security_kernel_module_request(void);
+int security_kernel_module_request(char *kmod_name);
int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
int security_task_fix_setuid(struct cred *new, const struct cred *old,
int flags);
@@ -2387,7 +2408,7 @@ static inline int security_kernel_create_files_as(struct cred *cred,
return 0;
}
-static inline int security_kernel_module_request(void)
+static inline int security_kernel_module_request(char *kmod_name)
{
return 0;
}
@@ -2952,6 +2973,10 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
struct dentry *new_dentry);
int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
struct path *new_dir, struct dentry *new_dentry);
+int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
+ mode_t mode);
+int security_path_chown(struct path *path, uid_t uid, gid_t gid);
+int security_path_chroot(struct path *path);
#else /* CONFIG_SECURITY_PATH */
static inline int security_path_unlink(struct path *dir, struct dentry *dentry)
{
@@ -3001,6 +3026,23 @@ static inline int security_path_rename(struct path *old_dir,
{
return 0;
}
+
+static inline int security_path_chmod(struct dentry *dentry,
+ struct vfsmount *mnt,
+ mode_t mode)
+{
+ return 0;
+}
+
+static inline int security_path_chown(struct path *path, uid_t uid, gid_t gid)
+{
+ return 0;
+}
+
+static inline int security_path_chroot(struct path *path)
+{
+ return 0;
+}
#endif /* CONFIG_SECURITY_PATH */
#ifdef CONFIG_KEYS
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index df7b23ac66e6..bcdd6606f468 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -354,8 +354,8 @@ struct sk_buff {
ipvs_property:1,
peeked:1,
nf_trace:1;
+ __be16 protocol:16;
kmemcheck_bitfield_end(flags1);
- __be16 protocol;
void (*destructor)(struct sk_buff *skb);
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
@@ -367,7 +367,6 @@ struct sk_buff {
#endif
int iif;
- __u16 queue_mapping;
#ifdef CONFIG_NET_SCHED
__u16 tc_index; /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
@@ -376,6 +375,7 @@ struct sk_buff {
#endif
kmemcheck_bitfield_begin(flags2);
+ __u16 queue_mapping:16;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2;
#endif
@@ -1757,6 +1757,8 @@ extern int skb_copy_datagram_const_iovec(const struct sk_buff *from,
int to_offset,
int size);
extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
+extern void skb_free_datagram_locked(struct sock *sk,
+ struct sk_buff *skb);
extern int skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
unsigned int flags);
extern __wsum skb_checksum(const struct sk_buff *skb, int offset,
diff --git a/include/linux/slow-work.h b/include/linux/slow-work.h
index b65c8881f07a..13337bf6c3f5 100644
--- a/include/linux/slow-work.h
+++ b/include/linux/slow-work.h
@@ -17,13 +17,20 @@
#ifdef CONFIG_SLOW_WORK
#include <linux/sysctl.h>
+#include <linux/timer.h>
struct slow_work;
+#ifdef CONFIG_SLOW_WORK_DEBUG
+struct seq_file;
+#endif
/*
* The operations used to support slow work items
*/
struct slow_work_ops {
+ /* owner */
+ struct module *owner;
+
/* get a ref on a work item
* - return 0 if successful, -ve if not
*/
@@ -34,6 +41,11 @@ struct slow_work_ops {
/* execute a work item */
void (*execute)(struct slow_work *work);
+
+#ifdef CONFIG_SLOW_WORK_DEBUG
+ /* describe a work item for debugfs */
+ void (*desc)(struct slow_work *work, struct seq_file *m);
+#endif
};
/*
@@ -42,13 +54,24 @@ struct slow_work_ops {
* queued
*/
struct slow_work {
+ struct module *owner; /* the owning module */
unsigned long flags;
#define SLOW_WORK_PENDING 0 /* item pending (further) execution */
#define SLOW_WORK_EXECUTING 1 /* item currently executing */
#define SLOW_WORK_ENQ_DEFERRED 2 /* item enqueue deferred */
#define SLOW_WORK_VERY_SLOW 3 /* item is very slow */
+#define SLOW_WORK_CANCELLING 4 /* item is being cancelled, don't enqueue */
+#define SLOW_WORK_DELAYED 5 /* item is struct delayed_slow_work with active timer */
const struct slow_work_ops *ops; /* operations table for this item */
struct list_head link; /* link in queue */
+#ifdef CONFIG_SLOW_WORK_DEBUG
+ struct timespec mark; /* jiffies at which queued or exec begun */
+#endif
+};
+
+struct delayed_slow_work {
+ struct slow_work work;
+ struct timer_list timer;
};
/**
@@ -67,6 +90,20 @@ static inline void slow_work_init(struct slow_work *work,
}
/**
+ * slow_work_init - Initialise a delayed slow work item
+ * @work: The work item to initialise
+ * @ops: The operations to use to handle the slow work item
+ *
+ * Initialise a delayed slow work item.
+ */
+static inline void delayed_slow_work_init(struct delayed_slow_work *dwork,
+ const struct slow_work_ops *ops)
+{
+ init_timer(&dwork->timer);
+ slow_work_init(&dwork->work, ops);
+}
+
+/**
* vslow_work_init - Initialise a very slow work item
* @work: The work item to initialise
* @ops: The operations to use to handle the slow work item
@@ -83,9 +120,40 @@ static inline void vslow_work_init(struct slow_work *work,
INIT_LIST_HEAD(&work->link);
}
+/**
+ * slow_work_is_queued - Determine if a slow work item is on the work queue
+ * work: The work item to test
+ *
+ * Determine if the specified slow-work item is on the work queue. This
+ * returns true if it is actually on the queue.
+ *
+ * If the item is executing and has been marked for requeue when execution
+ * finishes, then false will be returned.
+ *
+ * Anyone wishing to wait for completion of execution can wait on the
+ * SLOW_WORK_EXECUTING bit.
+ */
+static inline bool slow_work_is_queued(struct slow_work *work)
+{
+ unsigned long flags = work->flags;
+ return flags & SLOW_WORK_PENDING && !(flags & SLOW_WORK_EXECUTING);
+}
+
extern int slow_work_enqueue(struct slow_work *work);
-extern int slow_work_register_user(void);
-extern void slow_work_unregister_user(void);
+extern void slow_work_cancel(struct slow_work *work);
+extern int slow_work_register_user(struct module *owner);
+extern void slow_work_unregister_user(struct module *owner);
+
+extern int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
+ unsigned long delay);
+
+static inline void delayed_slow_work_cancel(struct delayed_slow_work *dwork)
+{
+ slow_work_cancel(&dwork->work);
+}
+
+extern bool slow_work_sleep_till_thread_needed(struct slow_work *work,
+ signed long *_timeout);
#ifdef CONFIG_SYSCTL
extern ctl_table slow_work_sysctls[];
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 39c64bae776d..7a0570e6a596 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -76,6 +76,9 @@ void smp_call_function_many(const struct cpumask *mask,
void __smp_call_function_single(int cpuid, struct call_single_data *data,
int wait);
+int smp_call_function_any(const struct cpumask *mask,
+ void (*func)(void *info), void *info, int wait);
+
/*
* Generic and arch helpers
*/
@@ -137,9 +140,15 @@ static inline void smp_send_reschedule(int cpu) { }
#define smp_prepare_boot_cpu() do {} while (0)
#define smp_call_function_many(mask, func, info, wait) \
(up_smp_call_function(func, info))
-static inline void init_call_single_data(void)
+static inline void init_call_single_data(void) { }
+
+static inline int
+smp_call_function_any(const struct cpumask *mask, void (*func)(void *info),
+ void *info, int wait)
{
+ return smp_call_function_single(0, func, info, wait);
}
+
#endif /* !SMP */
/*
diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h
index 813be59bf345..2ea1dd1ba21c 100644
--- a/include/linux/smp_lock.h
+++ b/include/linux/smp_lock.h
@@ -24,8 +24,21 @@ static inline int reacquire_kernel_lock(struct task_struct *task)
return 0;
}
-extern void __lockfunc lock_kernel(void) __acquires(kernel_lock);
-extern void __lockfunc unlock_kernel(void) __releases(kernel_lock);
+extern void __lockfunc
+_lock_kernel(const char *func, const char *file, int line)
+__acquires(kernel_lock);
+
+extern void __lockfunc
+_unlock_kernel(const char *func, const char *file, int line)
+__releases(kernel_lock);
+
+#define lock_kernel() do { \
+ _lock_kernel(__func__, __FILE__, __LINE__); \
+} while (0)
+
+#define unlock_kernel() do { \
+ _unlock_kernel(__func__, __FILE__, __LINE__); \
+} while (0)
/*
* Various legacy drivers don't really need the BKL in a specific
@@ -41,8 +54,8 @@ static inline void cycle_kernel_lock(void)
#else
-#define lock_kernel() do { } while(0)
-#define unlock_kernel() do { } while(0)
+#define lock_kernel()
+#define unlock_kernel()
#define release_kernel_lock(task) do { } while(0)
#define cycle_kernel_lock() do { } while(0)
#define reacquire_kernel_lock(task) 0
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index f0ca7a7a1757..71dccfeb0d88 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -79,8 +79,6 @@
*/
#include <linux/spinlock_types.h>
-extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
-
/*
* Pull the __raw*() functions/declarations (UP-nondebug doesnt need them):
*/
@@ -102,7 +100,7 @@ do { \
#else
# define spin_lock_init(lock) \
- do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0)
+ do { *(lock) = __SPIN_LOCK_UNLOCKED(lock); } while (0)
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
@@ -116,7 +114,7 @@ do { \
} while (0)
#else
# define rwlock_init(lock) \
- do { *(lock) = RW_LOCK_UNLOCKED; } while (0)
+ do { *(lock) = __RW_LOCK_UNLOCKED(lock); } while (0)
#endif
#define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock)
diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h
index 7a7e18fc2415..8264a7f459bc 100644
--- a/include/linux/spinlock_api_smp.h
+++ b/include/linux/spinlock_api_smp.h
@@ -60,137 +60,118 @@ void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
__releases(lock);
-/*
- * We inline the unlock functions in the nondebug case:
- */
-#if !defined(CONFIG_DEBUG_SPINLOCK) && !defined(CONFIG_PREEMPT)
-#define __always_inline__spin_unlock
-#define __always_inline__read_unlock
-#define __always_inline__write_unlock
-#define __always_inline__spin_unlock_irq
-#define __always_inline__read_unlock_irq
-#define __always_inline__write_unlock_irq
-#endif
-
-#ifndef CONFIG_DEBUG_SPINLOCK
-#ifndef CONFIG_GENERIC_LOCKBREAK
-
-#ifdef __always_inline__spin_lock
+#ifdef CONFIG_INLINE_SPIN_LOCK
#define _spin_lock(lock) __spin_lock(lock)
#endif
-#ifdef __always_inline__read_lock
+#ifdef CONFIG_INLINE_READ_LOCK
#define _read_lock(lock) __read_lock(lock)
#endif
-#ifdef __always_inline__write_lock
+#ifdef CONFIG_INLINE_WRITE_LOCK
#define _write_lock(lock) __write_lock(lock)
#endif
-#ifdef __always_inline__spin_lock_bh
+#ifdef CONFIG_INLINE_SPIN_LOCK_BH
#define _spin_lock_bh(lock) __spin_lock_bh(lock)
#endif
-#ifdef __always_inline__read_lock_bh
+#ifdef CONFIG_INLINE_READ_LOCK_BH
#define _read_lock_bh(lock) __read_lock_bh(lock)
#endif
-#ifdef __always_inline__write_lock_bh
+#ifdef CONFIG_INLINE_WRITE_LOCK_BH
#define _write_lock_bh(lock) __write_lock_bh(lock)
#endif
-#ifdef __always_inline__spin_lock_irq
+#ifdef CONFIG_INLINE_SPIN_LOCK_IRQ
#define _spin_lock_irq(lock) __spin_lock_irq(lock)
#endif
-#ifdef __always_inline__read_lock_irq
+#ifdef CONFIG_INLINE_READ_LOCK_IRQ
#define _read_lock_irq(lock) __read_lock_irq(lock)
#endif
-#ifdef __always_inline__write_lock_irq
+#ifdef CONFIG_INLINE_WRITE_LOCK_IRQ
#define _write_lock_irq(lock) __write_lock_irq(lock)
#endif
-#ifdef __always_inline__spin_lock_irqsave
+#ifdef CONFIG_INLINE_SPIN_LOCK_IRQSAVE
#define _spin_lock_irqsave(lock) __spin_lock_irqsave(lock)
#endif
-#ifdef __always_inline__read_lock_irqsave
+#ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE
#define _read_lock_irqsave(lock) __read_lock_irqsave(lock)
#endif
-#ifdef __always_inline__write_lock_irqsave
+#ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE
#define _write_lock_irqsave(lock) __write_lock_irqsave(lock)
#endif
-#endif /* !CONFIG_GENERIC_LOCKBREAK */
-
-#ifdef __always_inline__spin_trylock
+#ifdef CONFIG_INLINE_SPIN_TRYLOCK
#define _spin_trylock(lock) __spin_trylock(lock)
#endif
-#ifdef __always_inline__read_trylock
+#ifdef CONFIG_INLINE_READ_TRYLOCK
#define _read_trylock(lock) __read_trylock(lock)
#endif
-#ifdef __always_inline__write_trylock
+#ifdef CONFIG_INLINE_WRITE_TRYLOCK
#define _write_trylock(lock) __write_trylock(lock)
#endif
-#ifdef __always_inline__spin_trylock_bh
+#ifdef CONFIG_INLINE_SPIN_TRYLOCK_BH
#define _spin_trylock_bh(lock) __spin_trylock_bh(lock)
#endif
-#ifdef __always_inline__spin_unlock
+#ifdef CONFIG_INLINE_SPIN_UNLOCK
#define _spin_unlock(lock) __spin_unlock(lock)
#endif
-#ifdef __always_inline__read_unlock
+#ifdef CONFIG_INLINE_READ_UNLOCK
#define _read_unlock(lock) __read_unlock(lock)
#endif
-#ifdef __always_inline__write_unlock
+#ifdef CONFIG_INLINE_WRITE_UNLOCK
#define _write_unlock(lock) __write_unlock(lock)
#endif
-#ifdef __always_inline__spin_unlock_bh
+#ifdef CONFIG_INLINE_SPIN_UNLOCK_BH
#define _spin_unlock_bh(lock) __spin_unlock_bh(lock)
#endif
-#ifdef __always_inline__read_unlock_bh
+#ifdef CONFIG_INLINE_READ_UNLOCK_BH
#define _read_unlock_bh(lock) __read_unlock_bh(lock)
#endif
-#ifdef __always_inline__write_unlock_bh
+#ifdef CONFIG_INLINE_WRITE_UNLOCK_BH
#define _write_unlock_bh(lock) __write_unlock_bh(lock)
#endif
-#ifdef __always_inline__spin_unlock_irq
+#ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQ
#define _spin_unlock_irq(lock) __spin_unlock_irq(lock)
#endif
-#ifdef __always_inline__read_unlock_irq
+#ifdef CONFIG_INLINE_READ_UNLOCK_IRQ
#define _read_unlock_irq(lock) __read_unlock_irq(lock)
#endif
-#ifdef __always_inline__write_unlock_irq
+#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ
#define _write_unlock_irq(lock) __write_unlock_irq(lock)
#endif
-#ifdef __always_inline__spin_unlock_irqrestore
+#ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE
#define _spin_unlock_irqrestore(lock, flags) __spin_unlock_irqrestore(lock, flags)
#endif
-#ifdef __always_inline__read_unlock_irqrestore
+#ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE
#define _read_unlock_irqrestore(lock, flags) __read_unlock_irqrestore(lock, flags)
#endif
-#ifdef __always_inline__write_unlock_irqrestore
+#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE
#define _write_unlock_irqrestore(lock, flags) __write_unlock_irqrestore(lock, flags)
#endif
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
static inline int __spin_trylock(spinlock_t *lock)
{
preempt_disable();
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index aca0eee53930..4765d97dcafb 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -48,6 +48,7 @@ void cleanup_srcu_struct(struct srcu_struct *sp);
int srcu_read_lock(struct srcu_struct *sp) __acquires(sp);
void srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp);
void synchronize_srcu(struct srcu_struct *sp);
+void synchronize_srcu_expedited(struct srcu_struct *sp);
long srcu_batches_completed(struct srcu_struct *sp);
#endif
diff --git a/include/linux/string.h b/include/linux/string.h
index 489019ef1694..b8508868d5ad 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -62,7 +62,7 @@ extern char * strnchr(const char *, size_t, int);
#ifndef __HAVE_ARCH_STRRCHR
extern char * strrchr(const char *,int);
#endif
-extern char * strstrip(char *);
+extern char * __must_check strstrip(char *);
#ifndef __HAVE_ARCH_STRSTR
extern char * strstr(const char *,const char *);
#endif
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index cd15df6c63cd..5e781d824e6d 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -301,6 +301,8 @@ static inline int unregister_pm_notifier(struct notifier_block *nb)
#define pm_notifier(fn, pri) do { (void)(fn); } while (0)
#endif /* !CONFIG_PM_SLEEP */
+extern struct mutex pm_mutex;
+
#ifndef CONFIG_HIBERNATION
static inline void register_nosave_region(unsigned long b, unsigned long e)
{
@@ -308,8 +310,23 @@ static inline void register_nosave_region(unsigned long b, unsigned long e)
static inline void register_nosave_region_late(unsigned long b, unsigned long e)
{
}
-#endif
-extern struct mutex pm_mutex;
+static inline void lock_system_sleep(void) {}
+static inline void unlock_system_sleep(void) {}
+
+#else
+
+/* Let some subsystems like memory hotadd exclude hibernation */
+
+static inline void lock_system_sleep(void)
+{
+ mutex_lock(&pm_mutex);
+}
+
+static inline void unlock_system_sleep(void)
+{
+ mutex_unlock(&pm_mutex);
+}
+#endif
#endif /* _LINUX_SUSPEND_H */
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 73b1f1cec423..febedcf67c7e 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -7,6 +7,8 @@ struct device;
struct dma_attrs;
struct scatterlist;
+extern int swiotlb_force;
+
/*
* Maximum allowable number of contiguous slabs to map,
* must be a power of 2. What is the appropriate value ?
@@ -20,8 +22,7 @@ struct scatterlist;
*/
#define IO_TLB_SHIFT 11
-extern void
-swiotlb_init(void);
+extern void swiotlb_init(int verbose);
extern void
*swiotlb_alloc_coherent(struct device *hwdev, size_t size,
@@ -88,4 +89,11 @@ swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr);
extern int
swiotlb_dma_supported(struct device *hwdev, u64 mask);
+#ifdef CONFIG_SWIOTLB
+extern void __init swiotlb_free(void);
+#else
+static inline void swiotlb_free(void) { }
+#endif
+
+extern void swiotlb_print_info(void);
#endif /* __LINUX_SWIOTLB_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a990ace1a838..e79e2f3ccc51 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -99,37 +99,16 @@ struct perf_event_attr;
#define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__)
#ifdef CONFIG_EVENT_PROFILE
-#define TRACE_SYS_ENTER_PROFILE(sname) \
-static int prof_sysenter_enable_##sname(void) \
-{ \
- return reg_prof_syscall_enter("sys"#sname); \
-} \
- \
-static void prof_sysenter_disable_##sname(void) \
-{ \
- unreg_prof_syscall_enter("sys"#sname); \
-}
-
-#define TRACE_SYS_EXIT_PROFILE(sname) \
-static int prof_sysexit_enable_##sname(void) \
-{ \
- return reg_prof_syscall_exit("sys"#sname); \
-} \
- \
-static void prof_sysexit_disable_##sname(void) \
-{ \
- unreg_prof_syscall_exit("sys"#sname); \
-}
#define TRACE_SYS_ENTER_PROFILE_INIT(sname) \
.profile_count = ATOMIC_INIT(-1), \
- .profile_enable = prof_sysenter_enable_##sname, \
- .profile_disable = prof_sysenter_disable_##sname,
+ .profile_enable = prof_sysenter_enable, \
+ .profile_disable = prof_sysenter_disable,
#define TRACE_SYS_EXIT_PROFILE_INIT(sname) \
.profile_count = ATOMIC_INIT(-1), \
- .profile_enable = prof_sysexit_enable_##sname, \
- .profile_disable = prof_sysexit_disable_##sname,
+ .profile_enable = prof_sysexit_enable, \
+ .profile_disable = prof_sysexit_disable,
#else
#define TRACE_SYS_ENTER_PROFILE(sname)
#define TRACE_SYS_ENTER_PROFILE_INIT(sname)
@@ -153,74 +132,46 @@ static void prof_sysexit_disable_##sname(void) \
#define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__)
#define SYSCALL_TRACE_ENTER_EVENT(sname) \
+ static const struct syscall_metadata __syscall_meta_##sname; \
static struct ftrace_event_call event_enter_##sname; \
- struct trace_event enter_syscall_print_##sname = { \
+ static struct trace_event enter_syscall_print_##sname = { \
.trace = print_syscall_enter, \
}; \
- static int init_enter_##sname(void) \
- { \
- int num, id; \
- num = syscall_name_to_nr("sys"#sname); \
- if (num < 0) \
- return -ENOSYS; \
- id = register_ftrace_event(&enter_syscall_print_##sname);\
- if (!id) \
- return -ENODEV; \
- event_enter_##sname.id = id; \
- set_syscall_enter_id(num, id); \
- INIT_LIST_HEAD(&event_enter_##sname.fields); \
- return 0; \
- } \
- TRACE_SYS_ENTER_PROFILE(sname); \
static struct ftrace_event_call __used \
__attribute__((__aligned__(4))) \
__attribute__((section("_ftrace_events"))) \
event_enter_##sname = { \
.name = "sys_enter"#sname, \
.system = "syscalls", \
- .event = &event_syscall_enter, \
- .raw_init = init_enter_##sname, \
+ .event = &enter_syscall_print_##sname, \
+ .raw_init = init_syscall_trace, \
.show_format = syscall_enter_format, \
.define_fields = syscall_enter_define_fields, \
.regfunc = reg_event_syscall_enter, \
.unregfunc = unreg_event_syscall_enter, \
- .data = "sys"#sname, \
+ .data = (void *)&__syscall_meta_##sname,\
TRACE_SYS_ENTER_PROFILE_INIT(sname) \
}
#define SYSCALL_TRACE_EXIT_EVENT(sname) \
+ static const struct syscall_metadata __syscall_meta_##sname; \
static struct ftrace_event_call event_exit_##sname; \
- struct trace_event exit_syscall_print_##sname = { \
+ static struct trace_event exit_syscall_print_##sname = { \
.trace = print_syscall_exit, \
}; \
- static int init_exit_##sname(void) \
- { \
- int num, id; \
- num = syscall_name_to_nr("sys"#sname); \
- if (num < 0) \
- return -ENOSYS; \
- id = register_ftrace_event(&exit_syscall_print_##sname);\
- if (!id) \
- return -ENODEV; \
- event_exit_##sname.id = id; \
- set_syscall_exit_id(num, id); \
- INIT_LIST_HEAD(&event_exit_##sname.fields); \
- return 0; \
- } \
- TRACE_SYS_EXIT_PROFILE(sname); \
static struct ftrace_event_call __used \
__attribute__((__aligned__(4))) \
__attribute__((section("_ftrace_events"))) \
event_exit_##sname = { \
.name = "sys_exit"#sname, \
.system = "syscalls", \
- .event = &event_syscall_exit, \
- .raw_init = init_exit_##sname, \
+ .event = &exit_syscall_print_##sname, \
+ .raw_init = init_syscall_trace, \
.show_format = syscall_exit_format, \
.define_fields = syscall_exit_define_fields, \
.regfunc = reg_event_syscall_exit, \
.unregfunc = unreg_event_syscall_exit, \
- .data = "sys"#sname, \
+ .data = (void *)&__syscall_meta_##sname,\
TRACE_SYS_EXIT_PROFILE_INIT(sname) \
}
diff --git a/include/linux/topology.h b/include/linux/topology.h
index fc0bf3edeb67..57e63579bfdd 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -129,7 +129,7 @@ int arch_update_cpu_topology(void);
| 1*SD_BALANCE_FORK \
| 0*SD_BALANCE_WAKE \
| 1*SD_WAKE_AFFINE \
- | 1*SD_PREFER_LOCAL \
+ | 0*SD_PREFER_LOCAL \
| 0*SD_SHARE_CPUPOWER \
| 1*SD_SHARE_PKG_RESOURCES \
| 0*SD_SERIALIZE \
@@ -162,7 +162,7 @@ int arch_update_cpu_topology(void);
| 1*SD_BALANCE_FORK \
| 0*SD_BALANCE_WAKE \
| 1*SD_WAKE_AFFINE \
- | 1*SD_PREFER_LOCAL \
+ | 0*SD_PREFER_LOCAL \
| 0*SD_SHARE_CPUPOWER \
| 0*SD_SHARE_PKG_RESOURCES \
| 0*SD_SERIALIZE \
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 3338b3f5c21a..ac5d1c1285d9 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -27,9 +27,16 @@
*/
#define TPM_ANY_NUM 0xFFFF
-#if defined(CONFIG_TCG_TPM)
+#if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf);
extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash);
+#else
+static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) {
+ return -ENODEV;
+}
+static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) {
+ return -ENODEV;
+}
#endif
#endif
diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h
index c134dd1fe6b6..09077f6ed128 100644
--- a/include/linux/trace_seq.h
+++ b/include/linux/trace_seq.h
@@ -7,7 +7,7 @@
/*
* Trace sequences are used to allow a function to call several other functions
- * to create a string of data to use (up to a max of PAGE_SIZE.
+ * to create a string of data to use (up to a max of PAGE_SIZE).
*/
struct trace_seq {
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 2aac8a83e89b..f59604ed0ec6 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -280,6 +280,12 @@ static inline void tracepoint_synchronize_unregister(void)
* TRACE_EVENT_FN to perform any (un)registration work.
*/
+#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
+#define DEFINE_EVENT(template, name, proto, args) \
+ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+
#define TRACE_EVENT(name, proto, args, struct, assign, print) \
DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
#define TRACE_EVENT_FN(name, proto, args, struct, \
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h
index ea7226a45acb..095e10d148b4 100644
--- a/include/linux/virtio_9p.h
+++ b/include/linux/virtio_9p.h
@@ -2,6 +2,7 @@
#define _LINUX_VIRTIO_9P_H
/* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers. */
+#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
/* Maximum number of virtio channels per partition (1 for now) */
diff --git a/include/linux/virtio_balloon.h b/include/linux/virtio_balloon.h
index 09d730085060..1418f048cb34 100644
--- a/include/linux/virtio_balloon.h
+++ b/include/linux/virtio_balloon.h
@@ -2,6 +2,7 @@
#define _LINUX_VIRTIO_BALLOON_H
/* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers. */
+#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
/* The feature bitmap for virtio balloon */
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
index 15cb666581d7..fd294c56d571 100644
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -3,6 +3,7 @@
/* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers. */
#include <linux/types.h>
+#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
/* Feature bits */
@@ -13,11 +14,8 @@
#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/
#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
-#define VIRTIO_BLK_F_IDENTIFY 8 /* ATA IDENTIFY supported */
#define VIRTIO_BLK_F_FLUSH 9 /* Cache flush command support */
-#define VIRTIO_BLK_ID_BYTES (sizeof(__u16[256])) /* IDENTIFY DATA */
-
struct virtio_blk_config {
/* The capacity (in 512-byte sectors). */
__u64 capacity;
@@ -33,7 +31,6 @@ struct virtio_blk_config {
} geometry;
/* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
__u32 blk_size;
- __u8 identify[VIRTIO_BLK_ID_BYTES];
} __attribute__((packed));
/*
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h
index b5f519806014..fe885174cc1f 100644
--- a/include/linux/virtio_console.h
+++ b/include/linux/virtio_console.h
@@ -1,6 +1,7 @@
#ifndef _LINUX_VIRTIO_CONSOLE_H
#define _LINUX_VIRTIO_CONSOLE_H
#include <linux/types.h>
+#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
/* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
* anyone can use the definitions to implement compatible drivers/servers. */
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index 1f41734bbb77..085e42298ce5 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -3,6 +3,7 @@
/* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers. */
#include <linux/types.h>
+#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
#include <linux/if_ether.h>
diff --git a/include/linux/virtio_rng.h b/include/linux/virtio_rng.h
index 48121c3c434b..c4d5de896f0c 100644
--- a/include/linux/virtio_rng.h
+++ b/include/linux/virtio_rng.h
@@ -2,6 +2,7 @@
#define _LINUX_VIRTIO_RNG_H
/* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers. */
+#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
#endif /* _LINUX_VIRTIO_RNG_H */
diff --git a/include/linux/vt.h b/include/linux/vt.h
index 7afca0d72139..7ffa11f06232 100644
--- a/include/linux/vt.h
+++ b/include/linux/vt.h
@@ -70,8 +70,8 @@ struct vt_event {
#define VT_EVENT_UNBLANK 0x0004 /* Screen unblank */
#define VT_EVENT_RESIZE 0x0008 /* Resize display */
#define VT_MAX_EVENT 0x000F
- unsigned int old; /* Old console */
- unsigned int new; /* New console (if changing) */
+ unsigned int oldev; /* Old console */
+ unsigned int newev; /* New console (if changing) */
unsigned int pad[4]; /* Padding for expansion */
};
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 7ef0c7b94f31..cf24c20de9e4 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -207,6 +207,7 @@ extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
extern void flush_workqueue(struct workqueue_struct *wq);
extern void flush_scheduled_work(void);
+extern void flush_delayed_work(struct delayed_work *work);
extern int schedule_work(struct work_struct *work);
extern int schedule_work_on(int cpu, struct work_struct *work);
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index e26812274b75..fb00b329f0d3 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -159,8 +159,7 @@ struct p9_client {
* @qid: the &p9_qid server identifier this handle points to
* @iounit: the server reported maximum transaction size for this file
* @uid: the numeric uid of the local user who owns this handle
- * @aux: transport specific information (unused?)
- * @rdir_fpos: tracks offset of file position when reading directory contents
+ * @rdir: readdir accounting structure (allocated on demand)
* @flist: per-client-instance fid tracking
* @dlist: per-dentry fid tracking
*
@@ -174,9 +173,9 @@ struct p9_fid {
struct p9_qid qid;
u32 iounit;
uid_t uid;
- void *aux;
- int rdir_fpos;
+ void *rdir;
+
struct list_head flist;
struct list_head dlist; /* list of all fids attached to a dentry */
};
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index b63b80fac567..f93ad90a601b 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -130,11 +130,11 @@ struct inet_timewait_sock {
__u16 tw_num;
kmemcheck_bitfield_begin(flags);
/* And these are ours. */
- __u8 tw_ipv6only:1,
- tw_transparent:1;
- /* 14 bits hole, try to pack */
+ unsigned int tw_ipv6only : 1,
+ tw_transparent : 1,
+ tw_pad : 14, /* 14 bits hole */
+ tw_ipv6_offset : 16;
kmemcheck_bitfield_end(flags);
- __u16 tw_ipv6_offset;
unsigned long tw_ttd;
struct inet_bind_bucket *tw_tb;
struct hlist_node tw_death_node;
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index ef91fe924ba4..4d22fabc7719 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -210,7 +210,8 @@ extern struct fib_table *fib_get_table(struct net *net, u32 id);
extern const struct nla_policy rtm_ipv4_policy[];
extern void ip_fib_init(void);
extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
- struct net_device *dev, __be32 *spec_dst, u32 *itag);
+ struct net_device *dev, __be32 *spec_dst,
+ u32 *itag, u32 mark);
extern void fib_select_default(struct net *net, const struct flowi *flp,
struct fib_result *res);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 466859b285e1..998c30fc8981 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1283,6 +1283,12 @@ enum ieee80211_filter_flags {
*
* These flags are used with the ampdu_action() callback in
* &struct ieee80211_ops to indicate which action is needed.
+ *
+ * Note that drivers MUST be able to deal with a TX aggregation
+ * session being stopped even before they OK'ed starting it by
+ * calling ieee80211_start_tx_ba_cb(_irqsafe), because the peer
+ * might receive the addBA frame and send a delBA right away!
+ *
* @IEEE80211_AMPDU_RX_START: start Rx aggregation
* @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation
* @IEEE80211_AMPDU_TX_START: start Tx aggregation
@@ -1669,6 +1675,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw);
* to this function and ieee80211_rx_irqsafe() may not be mixed for a
* single hardware.
*
+ * Note that right now, this function must be called with softirqs disabled.
+ *
* @hw: the hardware this frame came in on
* @skb: the buffer to receive, owned by mac80211 after this call
*/
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index cbdd6284996d..5cf7270e3ffc 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -255,11 +255,9 @@ static inline bool nf_ct_kill(struct nf_conn *ct)
}
/* These are for NAT. Icky. */
-/* Update TCP window tracking data when NAT mangles the packet */
-extern void nf_conntrack_tcp_update(const struct sk_buff *skb,
- unsigned int dataoff,
- struct nf_conn *ct, int dir,
- s16 offset);
+extern s16 (*nf_ct_nat_offset)(const struct nf_conn *ct,
+ enum ip_conntrack_dir dir,
+ u32 seq);
/* Fake conntrack entry for untracked connections */
extern struct nf_conn nf_conntrack_untracked;
diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h
index 237a961f40e1..4222220920a5 100644
--- a/include/net/netfilter/nf_nat_helper.h
+++ b/include/net/netfilter/nf_nat_helper.h
@@ -32,4 +32,8 @@ extern int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
* to port ct->master->saved_proto. */
extern void nf_nat_follow_master(struct nf_conn *ct,
struct nf_conntrack_expect *this);
+
+extern s16 nf_nat_get_offset(const struct nf_conn *ct,
+ enum ip_conntrack_dir dir,
+ u32 seq);
#endif
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 6e5f0e0c7967..0a474568b003 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -893,7 +893,6 @@ struct sctp_transport {
*/
/* RTO : The current retransmission timeout value. */
unsigned long rto;
- unsigned long last_rto;
__u32 rtt; /* This is the most recent RTT. */
@@ -1980,7 +1979,7 @@ void sctp_assoc_set_primary(struct sctp_association *,
void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
struct sctp_transport *);
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
- gfp_t);
+ sctp_scope_t, gfp_t);
int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
struct sctp_cookie*,
gfp_t gfp);
diff --git a/include/net/sock.h b/include/net/sock.h
index 1621935aad5b..9f96394f694e 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -226,12 +226,12 @@ struct sock {
#define sk_prot __sk_common.skc_prot
#define sk_net __sk_common.skc_net
kmemcheck_bitfield_begin(flags);
- unsigned char sk_shutdown : 2,
- sk_no_check : 2,
- sk_userlocks : 4;
+ unsigned int sk_shutdown : 2,
+ sk_no_check : 2,
+ sk_userlocks : 4,
+ sk_protocol : 8,
+ sk_type : 16;
kmemcheck_bitfield_end(flags);
- unsigned char sk_protocol;
- unsigned short sk_type;
int sk_rcvbuf;
socket_lock_t sk_lock;
/*
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
index 904468a191ef..afc2bfb9e917 100644
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -15,6 +15,10 @@
#ifndef _LINUX_CS_H
#define _LINUX_CS_H
+#ifdef __KERNEL__
+#include <linux/interrupt.h>
+#endif
+
/* For AccessConfigurationRegister */
typedef struct conf_reg_t {
u_char Function;
@@ -111,11 +115,9 @@ typedef struct io_req_t {
/* For RequestIRQ and ReleaseIRQ */
typedef struct irq_req_t {
- u_int Attributes;
- u_int AssignedIRQ;
- u_int IRQInfo1, IRQInfo2; /* IRQInfo2 is ignored */
- void *Handler;
- void *Instance;
+ u_int Attributes;
+ u_int AssignedIRQ;
+ irq_handler_t Handler;
} irq_req_t;
/* Attributes for RequestIRQ and ReleaseIRQ */
@@ -125,7 +127,7 @@ typedef struct irq_req_t {
#define IRQ_TYPE_DYNAMIC_SHARING 0x02
#define IRQ_FORCED_PULSE 0x04
#define IRQ_FIRST_SHARED 0x08
-#define IRQ_HANDLE_PRESENT 0x10
+//#define IRQ_HANDLE_PRESENT 0x10
#define IRQ_PULSE_ALLOCATED 0x100
/* Bits in IRQInfo1 field */
diff --git a/include/pcmcia/cs_types.h b/include/pcmcia/cs_types.h
index 315965a37930..f5e3b8386c8f 100644
--- a/include/pcmcia/cs_types.h
+++ b/include/pcmcia/cs_types.h
@@ -26,8 +26,7 @@ typedef u_int event_t;
typedef u_char cisdata_t;
typedef u_short page_t;
-struct window_t;
-typedef struct window_t *window_handle_t;
+typedef unsigned long window_handle_t;
struct region_t;
typedef struct region_t *memory_handle_t;
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index a2be80b9a095..d403c12f7978 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -34,6 +34,7 @@
struct pcmcia_socket;
struct pcmcia_device;
struct config_t;
+struct net_device;
/* dynamic device IDs for PCMCIA device drivers. See
* Documentation/pcmcia/driver.txt for details.
@@ -137,65 +138,39 @@ struct pcmcia_device {
#define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
#define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
-/* deprecated -- don't use! */
-#define handle_to_dev(handle) (handle->dev)
-
-/* (deprecated) error reporting by PCMCIA devices. Use dev_printk()
- * or dev_dbg() directly in the driver, without referring to pcmcia_error_func()
- * and/or pcmcia_error_ret() for those functions will go away soon.
- */
-enum service {
- AccessConfigurationRegister, AddSocketServices,
- AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory,
- DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo,
- GetClientInfo, GetConfigurationInfo, GetEventMask,
- GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple,
- GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple,
- GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage,
- MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow,
- OpenMemory, ParseTuple, ReadMemory, RegisterClient,
- RegisterEraseQueue, RegisterMTD, RegisterTimer,
- ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ,
- ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices,
- RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ,
- RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry,
- SetEventMask, SetRegion, ValidateCIS, VendorSpecific,
- WriteMemory, BindDevice, BindMTD, ReportError,
- SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS,
- GetFirstWindow, GetNextWindow, GetMemPage
-};
-const char *pcmcia_error_func(int func);
-const char *pcmcia_error_ret(int ret);
-
-#define cs_error(p_dev, func, ret) \
- { \
- dev_printk(KERN_NOTICE, &p_dev->dev, \
- "%s : %s\n", \
- pcmcia_error_func(func), \
- pcmcia_error_ret(ret)); \
- }
-
-/* CIS access.
- * Use the pcmcia_* versions in PCMCIA drivers
+/*
+ * CIS access.
+ *
+ * Please use the following functions to access CIS tuples:
+ * - pcmcia_get_tuple()
+ * - pcmcia_loop_tuple()
+ * - pcmcia_get_mac_from_cis()
+ *
+ * To parse a tuple_t, pcmcia_parse_tuple() exists. Its interface
+ * might change in future.
*/
-int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse);
-int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
- tuple_t *tuple);
-#define pcmcia_get_first_tuple(p_dev, tuple) \
- pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple)
+/* get the very first CIS entry of type @code. Note that buf is pointer
+ * to u8 *buf; and that you need to kfree(buf) afterwards. */
+size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+ u8 **buf);
-int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
- tuple_t *tuple);
-#define pcmcia_get_next_tuple(p_dev, tuple) \
- pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple)
+/* loop over CIS entries */
+int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+ int (*loop_tuple) (struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv_data),
+ void *priv_data);
-int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
-#define pcmcia_get_tuple_data(p_dev, tuple) \
- pccard_get_tuple_data(p_dev->socket, tuple)
+/* get the MAC address from CISTPL_FUNCE */
+int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev,
+ struct net_device *dev);
+/* parse a tuple_t */
+int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse);
+
/* loop CIS entries for valid configuration */
int pcmcia_loop_config(struct pcmcia_device *p_dev,
int (*conf_check) (struct pcmcia_device *p_dev,
@@ -221,12 +196,11 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
int pcmcia_request_configuration(struct pcmcia_device *p_dev,
config_req_t *req);
-int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req,
+int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req,
window_handle_t *wh);
-int pcmcia_release_window(window_handle_t win);
-
-int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
-int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
+int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t win);
+int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t win,
+ memreq_t *req);
int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
void pcmcia_disable_device(struct pcmcia_device *p_dev);
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index d696a692d94a..7c23be706f12 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -107,15 +107,6 @@ typedef struct io_window_t {
struct resource *res;
} io_window_t;
-#define WINDOW_MAGIC 0xB35C
-typedef struct window_t {
- u_short magic;
- u_short index;
- struct pcmcia_device *handle;
- struct pcmcia_socket *sock;
- pccard_mem_map ctl;
-} window_t;
-
/* Maximum number of IO windows per socket */
#define MAX_IO_WIN 2
@@ -155,7 +146,7 @@ struct pcmcia_socket {
u_int Config;
} irq;
io_window_t io[MAX_IO_WIN];
- window_t win[MAX_WIN];
+ pccard_mem_map win[MAX_WIN];
struct list_head cis_cache;
size_t fake_cis_len;
u8 *fake_cis;
@@ -172,7 +163,7 @@ struct pcmcia_socket {
u_int irq_mask;
u_int map_size;
u_int io_offset;
- u_char pci_irq;
+ u_int pci_irq;
struct pci_dev * cb_dev;
@@ -262,6 +253,8 @@ struct pcmcia_socket {
struct device dev;
/* data internal to the socket driver */
void *driver_data;
+ /* status of the card during resume from a system sleep state */
+ int resume_status;
};
@@ -280,6 +273,8 @@ extern struct pccard_resource_ops pccard_nonstatic_ops;
/* socket drivers are expected to use these callbacks in their .drv struct */
extern int pcmcia_socket_dev_suspend(struct device *dev);
+extern void pcmcia_socket_dev_early_resume(struct device *dev);
+extern void pcmcia_socket_dev_late_resume(struct device *dev);
extern int pcmcia_socket_dev_resume(struct device *dev);
/* socket drivers use this callback in their IRQ handler */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 9af48cbf0036..f097ae340bc1 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -145,6 +145,7 @@ struct scsi_device {
unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */
unsigned last_sector_bug:1; /* do not use multisector accesses on
SD_LAST_BUGGY_SECTORS */
+ unsigned is_visible:1; /* is the device visible in sysfs */
DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
struct list_head event_list; /* asserted events */
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 6e728b176904..47941fc5aba7 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -797,30 +797,23 @@ static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost)
static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type)
{
- switch (target_type) {
- case 1:
- if (shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION)
- return target_type;
- case 2:
- if (shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION)
- return target_type;
- case 3:
- if (shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION)
- return target_type;
- }
+ static unsigned char cap[] = { 0,
+ SHOST_DIF_TYPE1_PROTECTION,
+ SHOST_DIF_TYPE2_PROTECTION,
+ SHOST_DIF_TYPE3_PROTECTION };
- return 0;
+ return shost->prot_capabilities & cap[target_type] ? target_type : 0;
}
static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type)
{
#if defined(CONFIG_BLK_DEV_INTEGRITY)
- switch (target_type) {
- case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION;
- case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION;
- case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION;
- case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION;
- }
+ static unsigned char cap[] = { SHOST_DIX_TYPE0_PROTECTION,
+ SHOST_DIX_TYPE1_PROTECTION,
+ SHOST_DIX_TYPE2_PROTECTION,
+ SHOST_DIX_TYPE3_PROTECTION };
+
+ return shost->prot_capabilities & cap[target_type];
#endif
return 0;
}
diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h
index 2a4b3bf74033..5acfb1eb4df9 100644
--- a/include/trace/define_trace.h
+++ b/include/trace/define_trace.h
@@ -31,6 +31,14 @@
assign, print, reg, unreg) \
DEFINE_TRACE_FN(name, reg, unreg)
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, name, proto, args) \
+ DEFINE_TRACE(name)
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+ DEFINE_TRACE(name)
+
#undef DECLARE_TRACE
#define DECLARE_TRACE(name, proto, args) \
DEFINE_TRACE(name)
@@ -63,6 +71,9 @@
#undef TRACE_EVENT
#undef TRACE_EVENT_FN
+#undef DECLARE_EVENT_CLASS
+#undef DEFINE_EVENT
+#undef DEFINE_EVENT_PRINT
#undef TRACE_HEADER_MULTI_READ
/* Only undef what we defined in this file */
diff --git a/include/trace/events/bkl.h b/include/trace/events/bkl.h
new file mode 100644
index 000000000000..1af72dc24278
--- /dev/null
+++ b/include/trace/events/bkl.h
@@ -0,0 +1,61 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM bkl
+
+#if !defined(_TRACE_BKL_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_BKL_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(lock_kernel,
+
+ TP_PROTO(const char *func, const char *file, int line),
+
+ TP_ARGS(func, file, line),
+
+ TP_STRUCT__entry(
+ __field( int, depth )
+ __field_ext( const char *, func, FILTER_PTR_STRING )
+ __field_ext( const char *, file, FILTER_PTR_STRING )
+ __field( int, line )
+ ),
+
+ TP_fast_assign(
+ /* We want to record the lock_depth after lock is acquired */
+ __entry->depth = current->lock_depth + 1;
+ __entry->func = func;
+ __entry->file = file;
+ __entry->line = line;
+ ),
+
+ TP_printk("depth=%d file:line=%s:%d func=%s()", __entry->depth,
+ __entry->file, __entry->line, __entry->func)
+);
+
+TRACE_EVENT(unlock_kernel,
+
+ TP_PROTO(const char *func, const char *file, int line),
+
+ TP_ARGS(func, file, line),
+
+ TP_STRUCT__entry(
+ __field(int, depth )
+ __field(const char *, func )
+ __field(const char *, file )
+ __field(int, line )
+ ),
+
+ TP_fast_assign(
+ __entry->depth = current->lock_depth;
+ __entry->func = func;
+ __entry->file = file;
+ __entry->line = line;
+ ),
+
+ TP_printk("depth=%d file:line=%s:%d func=%s()", __entry->depth,
+ __entry->file, __entry->line, __entry->func)
+);
+
+#endif /* _TRACE_BKL_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index 00405b5f624a..5fb72733331e 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -8,7 +8,7 @@
#include <linux/blkdev.h>
#include <linux/tracepoint.h>
-TRACE_EVENT(block_rq_abort,
+DECLARE_EVENT_CLASS(block_rq_with_error,
TP_PROTO(struct request_queue *q, struct request *rq),
@@ -40,41 +40,28 @@ TRACE_EVENT(block_rq_abort,
__entry->nr_sector, __entry->errors)
);
-TRACE_EVENT(block_rq_insert,
+DEFINE_EVENT(block_rq_with_error, block_rq_abort,
TP_PROTO(struct request_queue *q, struct request *rq),
- TP_ARGS(q, rq),
+ TP_ARGS(q, rq)
+);
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( sector_t, sector )
- __field( unsigned int, nr_sector )
- __field( unsigned int, bytes )
- __array( char, rwbs, 6 )
- __array( char, comm, TASK_COMM_LEN )
- __dynamic_array( char, cmd, blk_cmd_buf_len(rq) )
- ),
+DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
- TP_fast_assign(
- __entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
- __entry->sector = blk_pc_request(rq) ? 0 : blk_rq_pos(rq);
- __entry->nr_sector = blk_pc_request(rq) ? 0 : blk_rq_sectors(rq);
- __entry->bytes = blk_pc_request(rq) ? blk_rq_bytes(rq) : 0;
+ TP_PROTO(struct request_queue *q, struct request *rq),
- blk_fill_rwbs_rq(__entry->rwbs, rq);
- blk_dump_cmd(__get_str(cmd), rq);
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
- ),
+ TP_ARGS(q, rq)
+);
- TP_printk("%d,%d %s %u (%s) %llu + %u [%s]",
- MAJOR(__entry->dev), MINOR(__entry->dev),
- __entry->rwbs, __entry->bytes, __get_str(cmd),
- (unsigned long long)__entry->sector,
- __entry->nr_sector, __entry->comm)
+DEFINE_EVENT(block_rq_with_error, block_rq_complete,
+
+ TP_PROTO(struct request_queue *q, struct request *rq),
+
+ TP_ARGS(q, rq)
);
-TRACE_EVENT(block_rq_issue,
+DECLARE_EVENT_CLASS(block_rq,
TP_PROTO(struct request_queue *q, struct request *rq),
@@ -86,7 +73,7 @@ TRACE_EVENT(block_rq_issue,
__field( unsigned int, nr_sector )
__field( unsigned int, bytes )
__array( char, rwbs, 6 )
- __array( char, comm, TASK_COMM_LEN )
+ __array( char, comm, TASK_COMM_LEN )
__dynamic_array( char, cmd, blk_cmd_buf_len(rq) )
),
@@ -108,68 +95,18 @@ TRACE_EVENT(block_rq_issue,
__entry->nr_sector, __entry->comm)
);
-TRACE_EVENT(block_rq_requeue,
+DEFINE_EVENT(block_rq, block_rq_insert,
TP_PROTO(struct request_queue *q, struct request *rq),
- TP_ARGS(q, rq),
-
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( sector_t, sector )
- __field( unsigned int, nr_sector )
- __field( int, errors )
- __array( char, rwbs, 6 )
- __dynamic_array( char, cmd, blk_cmd_buf_len(rq) )
- ),
-
- TP_fast_assign(
- __entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
- __entry->sector = blk_pc_request(rq) ? 0 : blk_rq_pos(rq);
- __entry->nr_sector = blk_pc_request(rq) ? 0 : blk_rq_sectors(rq);
- __entry->errors = rq->errors;
-
- blk_fill_rwbs_rq(__entry->rwbs, rq);
- blk_dump_cmd(__get_str(cmd), rq);
- ),
-
- TP_printk("%d,%d %s (%s) %llu + %u [%d]",
- MAJOR(__entry->dev), MINOR(__entry->dev),
- __entry->rwbs, __get_str(cmd),
- (unsigned long long)__entry->sector,
- __entry->nr_sector, __entry->errors)
+ TP_ARGS(q, rq)
);
-TRACE_EVENT(block_rq_complete,
+DEFINE_EVENT(block_rq, block_rq_issue,
TP_PROTO(struct request_queue *q, struct request *rq),
- TP_ARGS(q, rq),
-
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( sector_t, sector )
- __field( unsigned int, nr_sector )
- __field( int, errors )
- __array( char, rwbs, 6 )
- __dynamic_array( char, cmd, blk_cmd_buf_len(rq) )
- ),
-
- TP_fast_assign(
- __entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
- __entry->sector = blk_pc_request(rq) ? 0 : blk_rq_pos(rq);
- __entry->nr_sector = blk_pc_request(rq) ? 0 : blk_rq_sectors(rq);
- __entry->errors = rq->errors;
-
- blk_fill_rwbs_rq(__entry->rwbs, rq);
- blk_dump_cmd(__get_str(cmd), rq);
- ),
-
- TP_printk("%d,%d %s (%s) %llu + %u [%d]",
- MAJOR(__entry->dev), MINOR(__entry->dev),
- __entry->rwbs, __get_str(cmd),
- (unsigned long long)__entry->sector,
- __entry->nr_sector, __entry->errors)
+ TP_ARGS(q, rq)
);
TRACE_EVENT(block_bio_bounce,
@@ -228,7 +165,7 @@ TRACE_EVENT(block_bio_complete,
__entry->nr_sector, __entry->error)
);
-TRACE_EVENT(block_bio_backmerge,
+DECLARE_EVENT_CLASS(block_bio,
TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -256,63 +193,28 @@ TRACE_EVENT(block_bio_backmerge,
__entry->nr_sector, __entry->comm)
);
-TRACE_EVENT(block_bio_frontmerge,
+DEFINE_EVENT(block_bio, block_bio_backmerge,
TP_PROTO(struct request_queue *q, struct bio *bio),
- TP_ARGS(q, bio),
-
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( sector_t, sector )
- __field( unsigned, nr_sector )
- __array( char, rwbs, 6 )
- __array( char, comm, TASK_COMM_LEN )
- ),
-
- TP_fast_assign(
- __entry->dev = bio->bi_bdev->bd_dev;
- __entry->sector = bio->bi_sector;
- __entry->nr_sector = bio->bi_size >> 9;
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
- ),
-
- TP_printk("%d,%d %s %llu + %u [%s]",
- MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
- (unsigned long long)__entry->sector,
- __entry->nr_sector, __entry->comm)
+ TP_ARGS(q, bio)
);
-TRACE_EVENT(block_bio_queue,
+DEFINE_EVENT(block_bio, block_bio_frontmerge,
TP_PROTO(struct request_queue *q, struct bio *bio),
- TP_ARGS(q, bio),
+ TP_ARGS(q, bio)
+);
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( sector_t, sector )
- __field( unsigned int, nr_sector )
- __array( char, rwbs, 6 )
- __array( char, comm, TASK_COMM_LEN )
- ),
+DEFINE_EVENT(block_bio, block_bio_queue,
- TP_fast_assign(
- __entry->dev = bio->bi_bdev->bd_dev;
- __entry->sector = bio->bi_sector;
- __entry->nr_sector = bio->bi_size >> 9;
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
- ),
+ TP_PROTO(struct request_queue *q, struct bio *bio),
- TP_printk("%d,%d %s %llu + %u [%s]",
- MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
- (unsigned long long)__entry->sector,
- __entry->nr_sector, __entry->comm)
+ TP_ARGS(q, bio)
);
-TRACE_EVENT(block_getrq,
+DECLARE_EVENT_CLASS(block_get_rq,
TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
@@ -341,33 +243,18 @@ TRACE_EVENT(block_getrq,
__entry->nr_sector, __entry->comm)
);
-TRACE_EVENT(block_sleeprq,
+DEFINE_EVENT(block_get_rq, block_getrq,
TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
- TP_ARGS(q, bio, rw),
+ TP_ARGS(q, bio, rw)
+);
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( sector_t, sector )
- __field( unsigned int, nr_sector )
- __array( char, rwbs, 6 )
- __array( char, comm, TASK_COMM_LEN )
- ),
+DEFINE_EVENT(block_get_rq, block_sleeprq,
- TP_fast_assign(
- __entry->dev = bio ? bio->bi_bdev->bd_dev : 0;
- __entry->sector = bio ? bio->bi_sector : 0;
- __entry->nr_sector = bio ? bio->bi_size >> 9 : 0;
- blk_fill_rwbs(__entry->rwbs,
- bio ? bio->bi_rw : 0, __entry->nr_sector);
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
- ),
+ TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
- TP_printk("%d,%d %s %llu + %u [%s]",
- MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
- (unsigned long long)__entry->sector,
- __entry->nr_sector, __entry->comm)
+ TP_ARGS(q, bio, rw)
);
TRACE_EVENT(block_plug,
@@ -387,7 +274,7 @@ TRACE_EVENT(block_plug,
TP_printk("[%s]", __entry->comm)
);
-TRACE_EVENT(block_unplug_timer,
+DECLARE_EVENT_CLASS(block_unplug,
TP_PROTO(struct request_queue *q),
@@ -406,23 +293,18 @@ TRACE_EVENT(block_unplug_timer,
TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
);
-TRACE_EVENT(block_unplug_io,
+DEFINE_EVENT(block_unplug, block_unplug_timer,
TP_PROTO(struct request_queue *q),
- TP_ARGS(q),
+ TP_ARGS(q)
+);
- TP_STRUCT__entry(
- __field( int, nr_rq )
- __array( char, comm, TASK_COMM_LEN )
- ),
+DEFINE_EVENT(block_unplug, block_unplug_io,
- TP_fast_assign(
- __entry->nr_rq = q->rq.count[READ] + q->rq.count[WRITE];
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
- ),
+ TP_PROTO(struct request_queue *q),
- TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
+ TP_ARGS(q)
);
TRACE_EVENT(block_split,
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index d09550bf3f95..318f76535bd4 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -90,7 +90,7 @@ TRACE_EVENT(ext4_allocate_inode,
(unsigned long) __entry->dir, __entry->mode)
);
-TRACE_EVENT(ext4_write_begin,
+DECLARE_EVENT_CLASS(ext4__write_begin,
TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
unsigned int flags),
@@ -118,7 +118,23 @@ TRACE_EVENT(ext4_write_begin,
__entry->pos, __entry->len, __entry->flags)
);
-TRACE_EVENT(ext4_ordered_write_end,
+DEFINE_EVENT(ext4__write_begin, ext4_write_begin,
+
+ TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
+ unsigned int flags),
+
+ TP_ARGS(inode, pos, len, flags)
+);
+
+DEFINE_EVENT(ext4__write_begin, ext4_da_write_begin,
+
+ TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
+ unsigned int flags),
+
+ TP_ARGS(inode, pos, len, flags)
+);
+
+DECLARE_EVENT_CLASS(ext4__write_end,
TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
unsigned int copied),
@@ -145,57 +161,36 @@ TRACE_EVENT(ext4_ordered_write_end,
__entry->pos, __entry->len, __entry->copied)
);
-TRACE_EVENT(ext4_writeback_write_end,
+DEFINE_EVENT(ext4__write_end, ext4_ordered_write_end,
+
TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
unsigned int copied),
- TP_ARGS(inode, pos, len, copied),
+ TP_ARGS(inode, pos, len, copied)
+);
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( ino_t, ino )
- __field( loff_t, pos )
- __field( unsigned int, len )
- __field( unsigned int, copied )
- ),
+DEFINE_EVENT(ext4__write_end, ext4_writeback_write_end,
- TP_fast_assign(
- __entry->dev = inode->i_sb->s_dev;
- __entry->ino = inode->i_ino;
- __entry->pos = pos;
- __entry->len = len;
- __entry->copied = copied;
- ),
+ TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
+ unsigned int copied),
- TP_printk("dev %s ino %lu pos %llu len %u copied %u",
- jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
- __entry->pos, __entry->len, __entry->copied)
+ TP_ARGS(inode, pos, len, copied)
);
-TRACE_EVENT(ext4_journalled_write_end,
+DEFINE_EVENT(ext4__write_end, ext4_journalled_write_end,
+
TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
unsigned int copied),
- TP_ARGS(inode, pos, len, copied),
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( ino_t, ino )
- __field( loff_t, pos )
- __field( unsigned int, len )
- __field( unsigned int, copied )
- ),
+ TP_ARGS(inode, pos, len, copied)
+);
- TP_fast_assign(
- __entry->dev = inode->i_sb->s_dev;
- __entry->ino = inode->i_ino;
- __entry->pos = pos;
- __entry->len = len;
- __entry->copied = copied;
- ),
+DEFINE_EVENT(ext4__write_end, ext4_da_write_end,
- TP_printk("dev %s ino %lu pos %llu len %u copied %u",
- jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
- __entry->pos, __entry->len, __entry->copied)
+ TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
+ unsigned int copied),
+
+ TP_ARGS(inode, pos, len, copied)
);
TRACE_EVENT(ext4_writepage,
@@ -337,60 +332,6 @@ TRACE_EVENT(ext4_da_writepages_result,
(unsigned long) __entry->writeback_index)
);
-TRACE_EVENT(ext4_da_write_begin,
- TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
- unsigned int flags),
-
- TP_ARGS(inode, pos, len, flags),
-
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( ino_t, ino )
- __field( loff_t, pos )
- __field( unsigned int, len )
- __field( unsigned int, flags )
- ),
-
- TP_fast_assign(
- __entry->dev = inode->i_sb->s_dev;
- __entry->ino = inode->i_ino;
- __entry->pos = pos;
- __entry->len = len;
- __entry->flags = flags;
- ),
-
- TP_printk("dev %s ino %lu pos %llu len %u flags %u",
- jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
- __entry->pos, __entry->len, __entry->flags)
-);
-
-TRACE_EVENT(ext4_da_write_end,
- TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
- unsigned int copied),
-
- TP_ARGS(inode, pos, len, copied),
-
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( ino_t, ino )
- __field( loff_t, pos )
- __field( unsigned int, len )
- __field( unsigned int, copied )
- ),
-
- TP_fast_assign(
- __entry->dev = inode->i_sb->s_dev;
- __entry->ino = inode->i_ino;
- __entry->pos = pos;
- __entry->len = len;
- __entry->copied = copied;
- ),
-
- TP_printk("dev %s ino %lu pos %llu len %u copied %u",
- jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
- __entry->pos, __entry->len, __entry->copied)
-);
-
TRACE_EVENT(ext4_discard_blocks,
TP_PROTO(struct super_block *sb, unsigned long long blk,
unsigned long long count),
diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h
index b89f9db4a404..0e4cfb694fe7 100644
--- a/include/trace/events/irq.h
+++ b/include/trace/events/irq.h
@@ -48,7 +48,7 @@ TRACE_EVENT(irq_handler_entry,
__assign_str(name, action->name);
),
- TP_printk("irq=%d handler=%s", __entry->irq, __get_str(name))
+ TP_printk("irq=%d name=%s", __entry->irq, __get_str(name))
);
/**
@@ -78,22 +78,11 @@ TRACE_EVENT(irq_handler_exit,
__entry->ret = ret;
),
- TP_printk("irq=%d return=%s",
+ TP_printk("irq=%d ret=%s",
__entry->irq, __entry->ret ? "handled" : "unhandled")
);
-/**
- * softirq_entry - called immediately before the softirq handler
- * @h: pointer to struct softirq_action
- * @vec: pointer to first struct softirq_action in softirq_vec array
- *
- * The @h parameter, contains a pointer to the struct softirq_action
- * which has a pointer to the action handler that is called. By subtracting
- * the @vec pointer from the @h pointer, we can determine the softirq
- * number. Also, when used in combination with the softirq_exit tracepoint
- * we can determine the softirq latency.
- */
-TRACE_EVENT(softirq_entry,
+DECLARE_EVENT_CLASS(softirq,
TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
@@ -107,11 +96,29 @@ TRACE_EVENT(softirq_entry,
__entry->vec = (int)(h - vec);
),
- TP_printk("softirq=%d action=%s", __entry->vec,
+ TP_printk("vec=%d [action=%s]", __entry->vec,
show_softirq_name(__entry->vec))
);
/**
+ * softirq_entry - called immediately before the softirq handler
+ * @h: pointer to struct softirq_action
+ * @vec: pointer to first struct softirq_action in softirq_vec array
+ *
+ * The @h parameter, contains a pointer to the struct softirq_action
+ * which has a pointer to the action handler that is called. By subtracting
+ * the @vec pointer from the @h pointer, we can determine the softirq
+ * number. Also, when used in combination with the softirq_exit tracepoint
+ * we can determine the softirq latency.
+ */
+DEFINE_EVENT(softirq, softirq_entry,
+
+ TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+
+ TP_ARGS(h, vec)
+);
+
+/**
* softirq_exit - called immediately after the softirq handler returns
* @h: pointer to struct softirq_action
* @vec: pointer to first struct softirq_action in softirq_vec array
@@ -122,22 +129,11 @@ TRACE_EVENT(softirq_entry,
* combination with the softirq_entry tracepoint we can determine the softirq
* latency.
*/
-TRACE_EVENT(softirq_exit,
+DEFINE_EVENT(softirq, softirq_exit,
TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
- TP_ARGS(h, vec),
-
- TP_STRUCT__entry(
- __field( int, vec )
- ),
-
- TP_fast_assign(
- __entry->vec = (int)(h - vec);
- ),
-
- TP_printk("softirq=%d action=%s", __entry->vec,
- show_softirq_name(__entry->vec))
+ TP_ARGS(h, vec)
);
#endif /* _TRACE_IRQ_H */
diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h
index 3c60b75adb9e..96b370a050de 100644
--- a/include/trace/events/jbd2.h
+++ b/include/trace/events/jbd2.h
@@ -30,7 +30,7 @@ TRACE_EVENT(jbd2_checkpoint,
jbd2_dev_to_name(__entry->dev), __entry->result)
);
-TRACE_EVENT(jbd2_start_commit,
+DECLARE_EVENT_CLASS(jbd2_commit,
TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
@@ -53,73 +53,32 @@ TRACE_EVENT(jbd2_start_commit,
__entry->sync_commit)
);
-TRACE_EVENT(jbd2_commit_locking,
+DEFINE_EVENT(jbd2_commit, jbd2_start_commit,
TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
- TP_ARGS(journal, commit_transaction),
-
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( char, sync_commit )
- __field( int, transaction )
- ),
-
- TP_fast_assign(
- __entry->dev = journal->j_fs_dev->bd_dev;
- __entry->sync_commit = commit_transaction->t_synchronous_commit;
- __entry->transaction = commit_transaction->t_tid;
- ),
-
- TP_printk("dev %s transaction %d sync %d",
- jbd2_dev_to_name(__entry->dev), __entry->transaction,
- __entry->sync_commit)
+ TP_ARGS(journal, commit_transaction)
);
-TRACE_EVENT(jbd2_commit_flushing,
+DEFINE_EVENT(jbd2_commit, jbd2_commit_locking,
TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
- TP_ARGS(journal, commit_transaction),
-
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( char, sync_commit )
- __field( int, transaction )
- ),
-
- TP_fast_assign(
- __entry->dev = journal->j_fs_dev->bd_dev;
- __entry->sync_commit = commit_transaction->t_synchronous_commit;
- __entry->transaction = commit_transaction->t_tid;
- ),
-
- TP_printk("dev %s transaction %d sync %d",
- jbd2_dev_to_name(__entry->dev), __entry->transaction,
- __entry->sync_commit)
+ TP_ARGS(journal, commit_transaction)
);
-TRACE_EVENT(jbd2_commit_logging,
+DEFINE_EVENT(jbd2_commit, jbd2_commit_flushing,
TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
- TP_ARGS(journal, commit_transaction),
+ TP_ARGS(journal, commit_transaction)
+);
- TP_STRUCT__entry(
- __field( dev_t, dev )
- __field( char, sync_commit )
- __field( int, transaction )
- ),
+DEFINE_EVENT(jbd2_commit, jbd2_commit_logging,
- TP_fast_assign(
- __entry->dev = journal->j_fs_dev->bd_dev;
- __entry->sync_commit = commit_transaction->t_synchronous_commit;
- __entry->transaction = commit_transaction->t_tid;
- ),
+ TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
- TP_printk("dev %s transaction %d sync %d",
- jbd2_dev_to_name(__entry->dev), __entry->transaction,
- __entry->sync_commit)
+ TP_ARGS(journal, commit_transaction)
);
TRACE_EVENT(jbd2_end_commit,
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index eaf46bdd18a5..3adca0ca9dbe 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -44,7 +44,7 @@
{(unsigned long)__GFP_MOVABLE, "GFP_MOVABLE"} \
) : "GFP_NOWAIT"
-TRACE_EVENT(kmalloc,
+DECLARE_EVENT_CLASS(kmem_alloc,
TP_PROTO(unsigned long call_site,
const void *ptr,
@@ -78,41 +78,23 @@ TRACE_EVENT(kmalloc,
show_gfp_flags(__entry->gfp_flags))
);
-TRACE_EVENT(kmem_cache_alloc,
+DEFINE_EVENT(kmem_alloc, kmalloc,
- TP_PROTO(unsigned long call_site,
- const void *ptr,
- size_t bytes_req,
- size_t bytes_alloc,
- gfp_t gfp_flags),
+ TP_PROTO(unsigned long call_site, const void *ptr,
+ size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags),
- TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags),
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags)
+);
- TP_STRUCT__entry(
- __field( unsigned long, call_site )
- __field( const void *, ptr )
- __field( size_t, bytes_req )
- __field( size_t, bytes_alloc )
- __field( gfp_t, gfp_flags )
- ),
+DEFINE_EVENT(kmem_alloc, kmem_cache_alloc,
- TP_fast_assign(
- __entry->call_site = call_site;
- __entry->ptr = ptr;
- __entry->bytes_req = bytes_req;
- __entry->bytes_alloc = bytes_alloc;
- __entry->gfp_flags = gfp_flags;
- ),
+ TP_PROTO(unsigned long call_site, const void *ptr,
+ size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags),
- TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s",
- __entry->call_site,
- __entry->ptr,
- __entry->bytes_req,
- __entry->bytes_alloc,
- show_gfp_flags(__entry->gfp_flags))
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags)
);
-TRACE_EVENT(kmalloc_node,
+DECLARE_EVENT_CLASS(kmem_alloc_node,
TP_PROTO(unsigned long call_site,
const void *ptr,
@@ -150,45 +132,25 @@ TRACE_EVENT(kmalloc_node,
__entry->node)
);
-TRACE_EVENT(kmem_cache_alloc_node,
+DEFINE_EVENT(kmem_alloc_node, kmalloc_node,
- TP_PROTO(unsigned long call_site,
- const void *ptr,
- size_t bytes_req,
- size_t bytes_alloc,
- gfp_t gfp_flags,
- int node),
+ TP_PROTO(unsigned long call_site, const void *ptr,
+ size_t bytes_req, size_t bytes_alloc,
+ gfp_t gfp_flags, int node),
- TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node),
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node)
+);
- TP_STRUCT__entry(
- __field( unsigned long, call_site )
- __field( const void *, ptr )
- __field( size_t, bytes_req )
- __field( size_t, bytes_alloc )
- __field( gfp_t, gfp_flags )
- __field( int, node )
- ),
+DEFINE_EVENT(kmem_alloc_node, kmem_cache_alloc_node,
- TP_fast_assign(
- __entry->call_site = call_site;
- __entry->ptr = ptr;
- __entry->bytes_req = bytes_req;
- __entry->bytes_alloc = bytes_alloc;
- __entry->gfp_flags = gfp_flags;
- __entry->node = node;
- ),
+ TP_PROTO(unsigned long call_site, const void *ptr,
+ size_t bytes_req, size_t bytes_alloc,
+ gfp_t gfp_flags, int node),
- TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d",
- __entry->call_site,
- __entry->ptr,
- __entry->bytes_req,
- __entry->bytes_alloc,
- show_gfp_flags(__entry->gfp_flags),
- __entry->node)
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node)
);
-TRACE_EVENT(kfree,
+DECLARE_EVENT_CLASS(kmem_free,
TP_PROTO(unsigned long call_site, const void *ptr),
@@ -207,23 +169,18 @@ TRACE_EVENT(kfree,
TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr)
);
-TRACE_EVENT(kmem_cache_free,
+DEFINE_EVENT(kmem_free, kfree,
TP_PROTO(unsigned long call_site, const void *ptr),
- TP_ARGS(call_site, ptr),
+ TP_ARGS(call_site, ptr)
+);
- TP_STRUCT__entry(
- __field( unsigned long, call_site )
- __field( const void *, ptr )
- ),
+DEFINE_EVENT(kmem_free, kmem_cache_free,
- TP_fast_assign(
- __entry->call_site = call_site;
- __entry->ptr = ptr;
- ),
+ TP_PROTO(unsigned long call_site, const void *ptr),
- TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr)
+ TP_ARGS(call_site, ptr)
);
TRACE_EVENT(mm_page_free_direct,
@@ -299,7 +256,7 @@ TRACE_EVENT(mm_page_alloc,
show_gfp_flags(__entry->gfp_flags))
);
-TRACE_EVENT(mm_page_alloc_zone_locked,
+DECLARE_EVENT_CLASS(mm_page,
TP_PROTO(struct page *page, unsigned int order, int migratetype),
@@ -325,29 +282,22 @@ TRACE_EVENT(mm_page_alloc_zone_locked,
__entry->order == 0)
);
-TRACE_EVENT(mm_page_pcpu_drain,
+DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked,
- TP_PROTO(struct page *page, int order, int migratetype),
+ TP_PROTO(struct page *page, unsigned int order, int migratetype),
- TP_ARGS(page, order, migratetype),
+ TP_ARGS(page, order, migratetype)
+);
- TP_STRUCT__entry(
- __field( struct page *, page )
- __field( int, order )
- __field( int, migratetype )
- ),
+DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain,
- TP_fast_assign(
- __entry->page = page;
- __entry->order = order;
- __entry->migratetype = migratetype;
- ),
+ TP_PROTO(struct page *page, unsigned int order, int migratetype),
+
+ TP_ARGS(page, order, migratetype),
TP_printk("page=%p pfn=%lu order=%d migratetype=%d",
- __entry->page,
- page_to_pfn(__entry->page),
- __entry->order,
- __entry->migratetype)
+ __entry->page, page_to_pfn(__entry->page),
+ __entry->order, __entry->migratetype)
);
TRACE_EVENT(mm_page_alloc_extfrag,
diff --git a/include/trace/events/lockdep.h b/include/trace/events/lock.h
index bcf1d209a00d..a870ba125aa8 100644
--- a/include/trace/events/lockdep.h
+++ b/include/trace/events/lock.h
@@ -1,8 +1,8 @@
#undef TRACE_SYSTEM
-#define TRACE_SYSTEM lockdep
+#define TRACE_SYSTEM lock
-#if !defined(_TRACE_LOCKDEP_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_LOCKDEP_H
+#if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_LOCK_H
#include <linux/lockdep.h>
#include <linux/tracepoint.h>
@@ -90,7 +90,7 @@ TRACE_EVENT(lock_acquired,
#endif
#endif
-#endif /* _TRACE_LOCKDEP_H */
+#endif /* _TRACE_LOCK_H */
/* This part must be outside protection */
#include <trace/define_trace.h>
diff --git a/include/trace/events/mce.h b/include/trace/events/mce.h
new file mode 100644
index 000000000000..7eee77895cb3
--- /dev/null
+++ b/include/trace/events/mce.h
@@ -0,0 +1,69 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM mce
+
+#if !defined(_TRACE_MCE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_MCE_H
+
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+#include <asm/mce.h>
+
+TRACE_EVENT(mce_record,
+
+ TP_PROTO(struct mce *m),
+
+ TP_ARGS(m),
+
+ TP_STRUCT__entry(
+ __field( u64, mcgcap )
+ __field( u64, mcgstatus )
+ __field( u8, bank )
+ __field( u64, status )
+ __field( u64, addr )
+ __field( u64, misc )
+ __field( u64, ip )
+ __field( u8, cs )
+ __field( u64, tsc )
+ __field( u64, walltime )
+ __field( u32, cpu )
+ __field( u32, cpuid )
+ __field( u32, apicid )
+ __field( u32, socketid )
+ __field( u8, cpuvendor )
+ ),
+
+ TP_fast_assign(
+ __entry->mcgcap = m->mcgcap;
+ __entry->mcgstatus = m->mcgstatus;
+ __entry->bank = m->bank;
+ __entry->status = m->status;
+ __entry->addr = m->addr;
+ __entry->misc = m->misc;
+ __entry->ip = m->ip;
+ __entry->cs = m->cs;
+ __entry->tsc = m->tsc;
+ __entry->walltime = m->time;
+ __entry->cpu = m->extcpu;
+ __entry->cpuid = m->cpuid;
+ __entry->apicid = m->apicid;
+ __entry->socketid = m->socketid;
+ __entry->cpuvendor = m->cpuvendor;
+ ),
+
+ TP_printk("CPU: %d, MCGc/s: %llx/%llx, MC%d: %016Lx, ADDR/MISC: %016Lx/%016Lx, RIP: %02x:<%016Lx>, TSC: %llx, PROCESSOR: %u:%x, TIME: %llu, SOCKET: %u, APIC: %x",
+ __entry->cpu,
+ __entry->mcgcap, __entry->mcgstatus,
+ __entry->bank, __entry->status,
+ __entry->addr, __entry->misc,
+ __entry->cs, __entry->ip,
+ __entry->tsc,
+ __entry->cpuvendor, __entry->cpuid,
+ __entry->walltime,
+ __entry->socketid,
+ __entry->apicid)
+);
+
+#endif /* _TRACE_MCE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/module.h b/include/trace/events/module.h
index 84160fb18478..4b0f48ba16a6 100644
--- a/include/trace/events/module.h
+++ b/include/trace/events/module.h
@@ -51,7 +51,7 @@ TRACE_EVENT(module_free,
TP_printk("%s", __get_str(name))
);
-TRACE_EVENT(module_get,
+DECLARE_EVENT_CLASS(module_refcnt,
TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
@@ -73,26 +73,18 @@ TRACE_EVENT(module_get,
__get_str(name), (void *)__entry->ip, __entry->refcnt)
);
-TRACE_EVENT(module_put,
+DEFINE_EVENT(module_refcnt, module_get,
TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
- TP_ARGS(mod, ip, refcnt),
+ TP_ARGS(mod, ip, refcnt)
+);
- TP_STRUCT__entry(
- __field( unsigned long, ip )
- __field( int, refcnt )
- __string( name, mod->name )
- ),
+DEFINE_EVENT(module_refcnt, module_put,
- TP_fast_assign(
- __entry->ip = ip;
- __entry->refcnt = refcnt;
- __assign_str(name, mod->name);
- ),
+ TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
- TP_printk("%s call_site=%pf refcnt=%d",
- __get_str(name), (void *)__entry->ip, __entry->refcnt)
+ TP_ARGS(mod, ip, refcnt)
);
TRACE_EVENT(module_request,
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
index ea6d579261ad..c4efe9b8280d 100644
--- a/include/trace/events/power.h
+++ b/include/trace/events/power.h
@@ -16,9 +16,7 @@ enum {
};
#endif
-
-
-TRACE_EVENT(power_start,
+DECLARE_EVENT_CLASS(power,
TP_PROTO(unsigned int type, unsigned int state),
@@ -37,42 +35,36 @@ TRACE_EVENT(power_start,
TP_printk("type=%lu state=%lu", (unsigned long)__entry->type, (unsigned long)__entry->state)
);
-TRACE_EVENT(power_end,
-
- TP_PROTO(int dummy),
+DEFINE_EVENT(power, power_start,
- TP_ARGS(dummy),
+ TP_PROTO(unsigned int type, unsigned int state),
- TP_STRUCT__entry(
- __field( u64, dummy )
- ),
+ TP_ARGS(type, state)
+);
- TP_fast_assign(
- __entry->dummy = 0xffff;
- ),
+DEFINE_EVENT(power, power_frequency,
- TP_printk("dummy=%lu", (unsigned long)__entry->dummy)
+ TP_PROTO(unsigned int type, unsigned int state),
+ TP_ARGS(type, state)
);
+TRACE_EVENT(power_end,
-TRACE_EVENT(power_frequency,
-
- TP_PROTO(unsigned int type, unsigned int state),
+ TP_PROTO(int dummy),
- TP_ARGS(type, state),
+ TP_ARGS(dummy),
TP_STRUCT__entry(
- __field( u64, type )
- __field( u64, state )
+ __field( u64, dummy )
),
TP_fast_assign(
- __entry->type = type;
- __entry->state = state;
+ __entry->dummy = 0xffff;
),
- TP_printk("type=%lu state=%lu", (unsigned long)__entry->type, (unsigned long) __entry->state)
+ TP_printk("dummy=%lu", (unsigned long)__entry->dummy)
+
);
#endif /* _TRACE_POWER_H */
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 4069c43f4187..cfceb0b73e20 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -26,7 +26,7 @@ TRACE_EVENT(sched_kthread_stop,
__entry->pid = t->pid;
),
- TP_printk("task %s:%d", __entry->comm, __entry->pid)
+ TP_printk("comm=%s pid=%d", __entry->comm, __entry->pid)
);
/*
@@ -46,7 +46,7 @@ TRACE_EVENT(sched_kthread_stop_ret,
__entry->ret = ret;
),
- TP_printk("ret %d", __entry->ret)
+ TP_printk("ret=%d", __entry->ret)
);
/*
@@ -73,7 +73,7 @@ TRACE_EVENT(sched_wait_task,
__entry->prio = p->prio;
),
- TP_printk("task %s:%d [%d]",
+ TP_printk("comm=%s pid=%d prio=%d",
__entry->comm, __entry->pid, __entry->prio)
);
@@ -83,7 +83,7 @@ TRACE_EVENT(sched_wait_task,
* (NOTE: the 'rq' argument is not used by generic trace events,
* but used by the latency tracer plugin. )
*/
-TRACE_EVENT(sched_wakeup,
+DECLARE_EVENT_CLASS(sched_wakeup_template,
TP_PROTO(struct rq *rq, struct task_struct *p, int success),
@@ -94,7 +94,7 @@ TRACE_EVENT(sched_wakeup,
__field( pid_t, pid )
__field( int, prio )
__field( int, success )
- __field( int, cpu )
+ __field( int, target_cpu )
),
TP_fast_assign(
@@ -102,46 +102,27 @@ TRACE_EVENT(sched_wakeup,
__entry->pid = p->pid;
__entry->prio = p->prio;
__entry->success = success;
- __entry->cpu = task_cpu(p);
+ __entry->target_cpu = task_cpu(p);
),
- TP_printk("task %s:%d [%d] success=%d [%03d]",
+ TP_printk("comm=%s pid=%d prio=%d success=%d target_cpu=%03d",
__entry->comm, __entry->pid, __entry->prio,
- __entry->success, __entry->cpu)
+ __entry->success, __entry->target_cpu)
);
+DEFINE_EVENT(sched_wakeup_template, sched_wakeup,
+ TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+ TP_ARGS(rq, p, success));
+
/*
* Tracepoint for waking up a new task:
*
* (NOTE: the 'rq' argument is not used by generic trace events,
* but used by the latency tracer plugin. )
*/
-TRACE_EVENT(sched_wakeup_new,
-
- TP_PROTO(struct rq *rq, struct task_struct *p, int success),
-
- TP_ARGS(rq, p, success),
-
- TP_STRUCT__entry(
- __array( char, comm, TASK_COMM_LEN )
- __field( pid_t, pid )
- __field( int, prio )
- __field( int, success )
- __field( int, cpu )
- ),
-
- TP_fast_assign(
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
- __entry->pid = p->pid;
- __entry->prio = p->prio;
- __entry->success = success;
- __entry->cpu = task_cpu(p);
- ),
-
- TP_printk("task %s:%d [%d] success=%d [%03d]",
- __entry->comm, __entry->pid, __entry->prio,
- __entry->success, __entry->cpu)
-);
+DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new,
+ TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+ TP_ARGS(rq, p, success));
/*
* Tracepoint for task switches, performed by the scheduler:
@@ -176,7 +157,7 @@ TRACE_EVENT(sched_switch,
__entry->next_prio = next->prio;
),
- TP_printk("task %s:%d [%d] (%s) ==> %s:%d [%d]",
+ TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_pid=%d next_prio=%d",
__entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
__entry->prev_state ?
__print_flags(__entry->prev_state, "|",
@@ -211,15 +192,12 @@ TRACE_EVENT(sched_migrate_task,
__entry->dest_cpu = dest_cpu;
),
- TP_printk("task %s:%d [%d] from: %d to: %d",
+ TP_printk("comm=%s pid=%d prio=%d orig_cpu=%d dest_cpu=%d",
__entry->comm, __entry->pid, __entry->prio,
__entry->orig_cpu, __entry->dest_cpu)
);
-/*
- * Tracepoint for freeing a task:
- */
-TRACE_EVENT(sched_process_free,
+DECLARE_EVENT_CLASS(sched_process_template,
TP_PROTO(struct task_struct *p),
@@ -237,34 +215,24 @@ TRACE_EVENT(sched_process_free,
__entry->prio = p->prio;
),
- TP_printk("task %s:%d [%d]",
+ TP_printk("comm=%s pid=%d prio=%d",
__entry->comm, __entry->pid, __entry->prio)
);
/*
- * Tracepoint for a task exiting:
+ * Tracepoint for freeing a task:
*/
-TRACE_EVENT(sched_process_exit,
+DEFINE_EVENT(sched_process_template, sched_process_free,
+ TP_PROTO(struct task_struct *p),
+ TP_ARGS(p));
+
- TP_PROTO(struct task_struct *p),
-
- TP_ARGS(p),
-
- TP_STRUCT__entry(
- __array( char, comm, TASK_COMM_LEN )
- __field( pid_t, pid )
- __field( int, prio )
- ),
-
- TP_fast_assign(
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
- __entry->pid = p->pid;
- __entry->prio = p->prio;
- ),
-
- TP_printk("task %s:%d [%d]",
- __entry->comm, __entry->pid, __entry->prio)
-);
+/*
+ * Tracepoint for a task exiting:
+ */
+DEFINE_EVENT(sched_process_template, sched_process_exit,
+ TP_PROTO(struct task_struct *p),
+ TP_ARGS(p));
/*
* Tracepoint for a waiting task:
@@ -287,7 +255,7 @@ TRACE_EVENT(sched_process_wait,
__entry->prio = current->prio;
),
- TP_printk("task %s:%d [%d]",
+ TP_printk("comm=%s pid=%d prio=%d",
__entry->comm, __entry->pid, __entry->prio)
);
@@ -314,46 +282,16 @@ TRACE_EVENT(sched_process_fork,
__entry->child_pid = child->pid;
),
- TP_printk("parent %s:%d child %s:%d",
+ TP_printk("comm=%s pid=%d child_comm=%s child_pid=%d",
__entry->parent_comm, __entry->parent_pid,
__entry->child_comm, __entry->child_pid)
);
/*
- * Tracepoint for sending a signal:
- */
-TRACE_EVENT(sched_signal_send,
-
- TP_PROTO(int sig, struct task_struct *p),
-
- TP_ARGS(sig, p),
-
- TP_STRUCT__entry(
- __field( int, sig )
- __array( char, comm, TASK_COMM_LEN )
- __field( pid_t, pid )
- ),
-
- TP_fast_assign(
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
- __entry->pid = p->pid;
- __entry->sig = sig;
- ),
-
- TP_printk("sig: %d task %s:%d",
- __entry->sig, __entry->comm, __entry->pid)
-);
-
-/*
* XXX the below sched_stat tracepoints only apply to SCHED_OTHER/BATCH/IDLE
* adding sched_stat support to SCHED_FIFO/RR would be welcome.
*/
-
-/*
- * Tracepoint for accounting wait time (time the task is runnable
- * but not actually running due to scheduler contention).
- */
-TRACE_EVENT(sched_stat_wait,
+DECLARE_EVENT_CLASS(sched_stat_template,
TP_PROTO(struct task_struct *tsk, u64 delay),
@@ -374,11 +312,36 @@ TRACE_EVENT(sched_stat_wait,
__perf_count(delay);
),
- TP_printk("task: %s:%d wait: %Lu [ns]",
+ TP_printk("comm=%s pid=%d delay=%Lu [ns]",
__entry->comm, __entry->pid,
(unsigned long long)__entry->delay)
);
+
+/*
+ * Tracepoint for accounting wait time (time the task is runnable
+ * but not actually running due to scheduler contention).
+ */
+DEFINE_EVENT(sched_stat_template, sched_stat_wait,
+ TP_PROTO(struct task_struct *tsk, u64 delay),
+ TP_ARGS(tsk, delay));
+
+/*
+ * Tracepoint for accounting sleep time (time the task is not runnable,
+ * including iowait, see below).
+ */
+DEFINE_EVENT(sched_stat_template, sched_stat_sleep,
+ TP_PROTO(struct task_struct *tsk, u64 delay),
+ TP_ARGS(tsk, delay));
+
+/*
+ * Tracepoint for accounting iowait time (time the task is not runnable
+ * due to waiting on IO to complete).
+ */
+DEFINE_EVENT(sched_stat_template, sched_stat_iowait,
+ TP_PROTO(struct task_struct *tsk, u64 delay),
+ TP_ARGS(tsk, delay));
+
/*
* Tracepoint for accounting runtime (time the task is executing
* on a CPU).
@@ -406,72 +369,12 @@ TRACE_EVENT(sched_stat_runtime,
__perf_count(runtime);
),
- TP_printk("task: %s:%d runtime: %Lu [ns], vruntime: %Lu [ns]",
+ TP_printk("comm=%s pid=%d runtime=%Lu [ns] vruntime=%Lu [ns]",
__entry->comm, __entry->pid,
(unsigned long long)__entry->runtime,
(unsigned long long)__entry->vruntime)
);
-/*
- * Tracepoint for accounting sleep time (time the task is not runnable,
- * including iowait, see below).
- */
-TRACE_EVENT(sched_stat_sleep,
-
- TP_PROTO(struct task_struct *tsk, u64 delay),
-
- TP_ARGS(tsk, delay),
-
- TP_STRUCT__entry(
- __array( char, comm, TASK_COMM_LEN )
- __field( pid_t, pid )
- __field( u64, delay )
- ),
-
- TP_fast_assign(
- memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
- __entry->pid = tsk->pid;
- __entry->delay = delay;
- )
- TP_perf_assign(
- __perf_count(delay);
- ),
-
- TP_printk("task: %s:%d sleep: %Lu [ns]",
- __entry->comm, __entry->pid,
- (unsigned long long)__entry->delay)
-);
-
-/*
- * Tracepoint for accounting iowait time (time the task is not runnable
- * due to waiting on IO to complete).
- */
-TRACE_EVENT(sched_stat_iowait,
-
- TP_PROTO(struct task_struct *tsk, u64 delay),
-
- TP_ARGS(tsk, delay),
-
- TP_STRUCT__entry(
- __array( char, comm, TASK_COMM_LEN )
- __field( pid_t, pid )
- __field( u64, delay )
- ),
-
- TP_fast_assign(
- memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
- __entry->pid = tsk->pid;
- __entry->delay = delay;
- )
- TP_perf_assign(
- __perf_count(delay);
- ),
-
- TP_printk("task: %s:%d iowait: %Lu [ns]",
- __entry->comm, __entry->pid,
- (unsigned long long)__entry->delay)
-);
-
#endif /* _TRACE_SCHED_H */
/* This part must be outside protection */
diff --git a/include/trace/events/signal.h b/include/trace/events/signal.h
new file mode 100644
index 000000000000..a510b75ac304
--- /dev/null
+++ b/include/trace/events/signal.h
@@ -0,0 +1,173 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM signal
+
+#if !defined(_TRACE_SIGNAL_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SIGNAL_H
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/tracepoint.h>
+
+#define TP_STORE_SIGINFO(__entry, info) \
+ do { \
+ if (info == SEND_SIG_NOINFO) { \
+ __entry->errno = 0; \
+ __entry->code = SI_USER; \
+ } else if (info == SEND_SIG_PRIV) { \
+ __entry->errno = 0; \
+ __entry->code = SI_KERNEL; \
+ } else { \
+ __entry->errno = info->si_errno; \
+ __entry->code = info->si_code; \
+ } \
+ } while (0)
+
+/**
+ * signal_generate - called when a signal is generated
+ * @sig: signal number
+ * @info: pointer to struct siginfo
+ * @task: pointer to struct task_struct
+ *
+ * Current process sends a 'sig' signal to 'task' process with
+ * 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV,
+ * 'info' is not a pointer and you can't access its field. Instead,
+ * SEND_SIG_NOINFO means that si_code is SI_USER, and SEND_SIG_PRIV
+ * means that si_code is SI_KERNEL.
+ */
+TRACE_EVENT(signal_generate,
+
+ TP_PROTO(int sig, struct siginfo *info, struct task_struct *task),
+
+ TP_ARGS(sig, info, task),
+
+ TP_STRUCT__entry(
+ __field( int, sig )
+ __field( int, errno )
+ __field( int, code )
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ ),
+
+ TP_fast_assign(
+ __entry->sig = sig;
+ TP_STORE_SIGINFO(__entry, info);
+ memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
+ __entry->pid = task->pid;
+ ),
+
+ TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d",
+ __entry->sig, __entry->errno, __entry->code,
+ __entry->comm, __entry->pid)
+);
+
+/**
+ * signal_deliver - called when a signal is delivered
+ * @sig: signal number
+ * @info: pointer to struct siginfo
+ * @ka: pointer to struct k_sigaction
+ *
+ * A 'sig' signal is delivered to current process with 'info' siginfo,
+ * and it will be handled by 'ka'. ka->sa.sa_handler can be SIG_IGN or
+ * SIG_DFL.
+ * Note that some signals reported by signal_generate tracepoint can be
+ * lost, ignored or modified (by debugger) before hitting this tracepoint.
+ * This means, this can show which signals are actually delivered, but
+ * matching generated signals and delivered signals may not be correct.
+ */
+TRACE_EVENT(signal_deliver,
+
+ TP_PROTO(int sig, struct siginfo *info, struct k_sigaction *ka),
+
+ TP_ARGS(sig, info, ka),
+
+ TP_STRUCT__entry(
+ __field( int, sig )
+ __field( int, errno )
+ __field( int, code )
+ __field( unsigned long, sa_handler )
+ __field( unsigned long, sa_flags )
+ ),
+
+ TP_fast_assign(
+ __entry->sig = sig;
+ TP_STORE_SIGINFO(__entry, info);
+ __entry->sa_handler = (unsigned long)ka->sa.sa_handler;
+ __entry->sa_flags = ka->sa.sa_flags;
+ ),
+
+ TP_printk("sig=%d errno=%d code=%d sa_handler=%lx sa_flags=%lx",
+ __entry->sig, __entry->errno, __entry->code,
+ __entry->sa_handler, __entry->sa_flags)
+);
+
+/**
+ * signal_overflow_fail - called when signal queue is overflow
+ * @sig: signal number
+ * @group: signal to process group or not (bool)
+ * @info: pointer to struct siginfo
+ *
+ * Kernel fails to generate 'sig' signal with 'info' siginfo, because
+ * siginfo queue is overflow, and the signal is dropped.
+ * 'group' is not 0 if the signal will be sent to a process group.
+ * 'sig' is always one of RT signals.
+ */
+TRACE_EVENT(signal_overflow_fail,
+
+ TP_PROTO(int sig, int group, struct siginfo *info),
+
+ TP_ARGS(sig, group, info),
+
+ TP_STRUCT__entry(
+ __field( int, sig )
+ __field( int, group )
+ __field( int, errno )
+ __field( int, code )
+ ),
+
+ TP_fast_assign(
+ __entry->sig = sig;
+ __entry->group = group;
+ TP_STORE_SIGINFO(__entry, info);
+ ),
+
+ TP_printk("sig=%d group=%d errno=%d code=%d",
+ __entry->sig, __entry->group, __entry->errno, __entry->code)
+);
+
+/**
+ * signal_lose_info - called when siginfo is lost
+ * @sig: signal number
+ * @group: signal to process group or not (bool)
+ * @info: pointer to struct siginfo
+ *
+ * Kernel generates 'sig' signal but loses 'info' siginfo, because siginfo
+ * queue is overflow.
+ * 'group' is not 0 if the signal will be sent to a process group.
+ * 'sig' is always one of non-RT signals.
+ */
+TRACE_EVENT(signal_lose_info,
+
+ TP_PROTO(int sig, int group, struct siginfo *info),
+
+ TP_ARGS(sig, group, info),
+
+ TP_STRUCT__entry(
+ __field( int, sig )
+ __field( int, group )
+ __field( int, errno )
+ __field( int, code )
+ ),
+
+ TP_fast_assign(
+ __entry->sig = sig;
+ __entry->group = group;
+ TP_STORE_SIGINFO(__entry, info);
+ ),
+
+ TP_printk("sig=%d group=%d errno=%d code=%d",
+ __entry->sig, __entry->group, __entry->errno, __entry->code)
+);
+#endif /* _TRACE_SIGNAL_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/syscalls.h b/include/trace/events/syscalls.h
index 397dff2dbd5a..fb726ac7caee 100644
--- a/include/trace/events/syscalls.h
+++ b/include/trace/events/syscalls.h
@@ -1,5 +1,6 @@
#undef TRACE_SYSTEM
-#define TRACE_SYSTEM syscalls
+#define TRACE_SYSTEM raw_syscalls
+#define TRACE_INCLUDE_FILE syscalls
#if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_EVENTS_SYSCALLS_H
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h
index 1844c48d640e..e5ce87a0498d 100644
--- a/include/trace/events/timer.h
+++ b/include/trace/events/timer.h
@@ -26,7 +26,7 @@ TRACE_EVENT(timer_init,
__entry->timer = timer;
),
- TP_printk("timer %p", __entry->timer)
+ TP_printk("timer=%p", __entry->timer)
);
/**
@@ -54,7 +54,7 @@ TRACE_EVENT(timer_start,
__entry->now = jiffies;
),
- TP_printk("timer %p: func %pf, expires %lu, timeout %ld",
+ TP_printk("timer=%p function=%pf expires=%lu [timeout=%ld]",
__entry->timer, __entry->function, __entry->expires,
(long)__entry->expires - __entry->now)
);
@@ -81,7 +81,7 @@ TRACE_EVENT(timer_expire_entry,
__entry->now = jiffies;
),
- TP_printk("timer %p: now %lu", __entry->timer, __entry->now)
+ TP_printk("timer=%p now=%lu", __entry->timer, __entry->now)
);
/**
@@ -108,7 +108,7 @@ TRACE_EVENT(timer_expire_exit,
__entry->timer = timer;
),
- TP_printk("timer %p", __entry->timer)
+ TP_printk("timer=%p", __entry->timer)
);
/**
@@ -129,7 +129,7 @@ TRACE_EVENT(timer_cancel,
__entry->timer = timer;
),
- TP_printk("timer %p", __entry->timer)
+ TP_printk("timer=%p", __entry->timer)
);
/**
@@ -140,24 +140,24 @@ TRACE_EVENT(timer_cancel,
*/
TRACE_EVENT(hrtimer_init,
- TP_PROTO(struct hrtimer *timer, clockid_t clockid,
+ TP_PROTO(struct hrtimer *hrtimer, clockid_t clockid,
enum hrtimer_mode mode),
- TP_ARGS(timer, clockid, mode),
+ TP_ARGS(hrtimer, clockid, mode),
TP_STRUCT__entry(
- __field( void *, timer )
+ __field( void *, hrtimer )
__field( clockid_t, clockid )
__field( enum hrtimer_mode, mode )
),
TP_fast_assign(
- __entry->timer = timer;
+ __entry->hrtimer = hrtimer;
__entry->clockid = clockid;
__entry->mode = mode;
),
- TP_printk("hrtimer %p, clockid %s, mode %s", __entry->timer,
+ TP_printk("hrtimer=%p clockid=%s mode=%s", __entry->hrtimer,
__entry->clockid == CLOCK_REALTIME ?
"CLOCK_REALTIME" : "CLOCK_MONOTONIC",
__entry->mode == HRTIMER_MODE_ABS ?
@@ -170,26 +170,26 @@ TRACE_EVENT(hrtimer_init,
*/
TRACE_EVENT(hrtimer_start,
- TP_PROTO(struct hrtimer *timer),
+ TP_PROTO(struct hrtimer *hrtimer),
- TP_ARGS(timer),
+ TP_ARGS(hrtimer),
TP_STRUCT__entry(
- __field( void *, timer )
+ __field( void *, hrtimer )
__field( void *, function )
__field( s64, expires )
__field( s64, softexpires )
),
TP_fast_assign(
- __entry->timer = timer;
- __entry->function = timer->function;
- __entry->expires = hrtimer_get_expires(timer).tv64;
- __entry->softexpires = hrtimer_get_softexpires(timer).tv64;
+ __entry->hrtimer = hrtimer;
+ __entry->function = hrtimer->function;
+ __entry->expires = hrtimer_get_expires(hrtimer).tv64;
+ __entry->softexpires = hrtimer_get_softexpires(hrtimer).tv64;
),
- TP_printk("hrtimer %p, func %pf, expires %llu, softexpires %llu",
- __entry->timer, __entry->function,
+ TP_printk("hrtimer=%p function=%pf expires=%llu softexpires=%llu",
+ __entry->hrtimer, __entry->function,
(unsigned long long)ktime_to_ns((ktime_t) {
.tv64 = __entry->expires }),
(unsigned long long)ktime_to_ns((ktime_t) {
@@ -206,23 +206,22 @@ TRACE_EVENT(hrtimer_start,
*/
TRACE_EVENT(hrtimer_expire_entry,
- TP_PROTO(struct hrtimer *timer, ktime_t *now),
+ TP_PROTO(struct hrtimer *hrtimer, ktime_t *now),
- TP_ARGS(timer, now),
+ TP_ARGS(hrtimer, now),
TP_STRUCT__entry(
- __field( void *, timer )
+ __field( void *, hrtimer )
__field( s64, now )
),
TP_fast_assign(
- __entry->timer = timer;
- __entry->now = now->tv64;
+ __entry->hrtimer = hrtimer;
+ __entry->now = now->tv64;
),
- TP_printk("hrtimer %p, now %llu", __entry->timer,
- (unsigned long long)ktime_to_ns((ktime_t) {
- .tv64 = __entry->now }))
+ TP_printk("hrtimer=%p now=%llu", __entry->hrtimer,
+ (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now }))
);
/**
@@ -234,40 +233,40 @@ TRACE_EVENT(hrtimer_expire_entry,
*/
TRACE_EVENT(hrtimer_expire_exit,
- TP_PROTO(struct hrtimer *timer),
+ TP_PROTO(struct hrtimer *hrtimer),
- TP_ARGS(timer),
+ TP_ARGS(hrtimer),
TP_STRUCT__entry(
- __field( void *, timer )
+ __field( void *, hrtimer )
),
TP_fast_assign(
- __entry->timer = timer;
+ __entry->hrtimer = hrtimer;
),
- TP_printk("hrtimer %p", __entry->timer)
+ TP_printk("hrtimer=%p", __entry->hrtimer)
);
/**
* hrtimer_cancel - called when the hrtimer is canceled
- * @timer: pointer to struct hrtimer
+ * @hrtimer: pointer to struct hrtimer
*/
TRACE_EVENT(hrtimer_cancel,
- TP_PROTO(struct hrtimer *timer),
+ TP_PROTO(struct hrtimer *hrtimer),
- TP_ARGS(timer),
+ TP_ARGS(hrtimer),
TP_STRUCT__entry(
- __field( void *, timer )
+ __field( void *, hrtimer )
),
TP_fast_assign(
- __entry->timer = timer;
+ __entry->hrtimer = hrtimer;
),
- TP_printk("hrtimer %p", __entry->timer)
+ TP_printk("hrtimer=%p", __entry->hrtimer)
);
/**
@@ -302,7 +301,7 @@ TRACE_EVENT(itimer_state,
__entry->interval_usec = value->it_interval.tv_usec;
),
- TP_printk("which %d, expires %lu, it_value %lu.%lu, it_interval %lu.%lu",
+ TP_printk("which=%d expires=%lu it_value=%lu.%lu it_interval=%lu.%lu",
__entry->which, __entry->expires,
__entry->value_sec, __entry->value_usec,
__entry->interval_sec, __entry->interval_usec)
@@ -332,7 +331,7 @@ TRACE_EVENT(itimer_expire,
__entry->pid = pid_nr(pid);
),
- TP_printk("which %d, pid %d, now %lu", __entry->which,
+ TP_printk("which=%d pid=%d now=%lu", __entry->which,
(int) __entry->pid, __entry->now)
);
diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h
index e4612dbd7ba6..d6c974474e70 100644
--- a/include/trace/events/workqueue.h
+++ b/include/trace/events/workqueue.h
@@ -8,7 +8,7 @@
#include <linux/sched.h>
#include <linux/tracepoint.h>
-TRACE_EVENT(workqueue_insertion,
+DECLARE_EVENT_CLASS(workqueue,
TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
@@ -30,26 +30,18 @@ TRACE_EVENT(workqueue_insertion,
__entry->thread_pid, __entry->func)
);
-TRACE_EVENT(workqueue_execution,
+DEFINE_EVENT(workqueue, workqueue_insertion,
TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
- TP_ARGS(wq_thread, work),
+ TP_ARGS(wq_thread, work)
+);
- TP_STRUCT__entry(
- __array(char, thread_comm, TASK_COMM_LEN)
- __field(pid_t, thread_pid)
- __field(work_func_t, func)
- ),
+DEFINE_EVENT(workqueue, workqueue_execution,
- TP_fast_assign(
- memcpy(__entry->thread_comm, wq_thread->comm, TASK_COMM_LEN);
- __entry->thread_pid = wq_thread->pid;
- __entry->func = work->func;
- ),
+ TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
- TP_printk("thread=%s:%d func=%pf", __entry->thread_comm,
- __entry->thread_pid, __entry->func)
+ TP_ARGS(wq_thread, work)
);
/* Trace the creation of one workqueue thread on a cpu */
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index cc0d9667e182..d1b3de9c1a71 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -18,6 +18,26 @@
#include <linux/ftrace_event.h>
+/*
+ * DECLARE_EVENT_CLASS can be used to add a generic function
+ * handlers for events. That is, if all events have the same
+ * parameters and just have distinct trace points.
+ * Each tracepoint can be defined with DEFINE_EVENT and that
+ * will map the DECLARE_EVENT_CLASS to the tracepoint.
+ *
+ * TRACE_EVENT is a one to one mapping between tracepoint and template.
+ */
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
+ DECLARE_EVENT_CLASS(name, \
+ PARAMS(proto), \
+ PARAMS(args), \
+ PARAMS(tstruct), \
+ PARAMS(assign), \
+ PARAMS(print)); \
+ DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
+
+
#undef __field
#define __field(type, item) type item;
@@ -36,15 +56,21 @@
#undef TP_STRUCT__entry
#define TP_STRUCT__entry(args...) args
-#undef TRACE_EVENT
-#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
- struct ftrace_raw_##name { \
- struct trace_entry ent; \
- tstruct \
- char __data[0]; \
- }; \
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \
+ struct ftrace_raw_##name { \
+ struct trace_entry ent; \
+ tstruct \
+ char __data[0]; \
+ };
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, name, proto, args) \
static struct ftrace_event_call event_##name
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+ DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+
#undef __cpparg
#define __cpparg(arg...) arg
@@ -89,12 +115,19 @@
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
struct ftrace_data_offsets_##call { \
tstruct; \
};
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, name, proto, args)
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+ DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
/*
@@ -120,9 +153,10 @@
#undef __field
#define __field(type, item) \
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
- "offset:%u;\tsize:%u;\n", \
+ "offset:%u;\tsize:%u;\tsigned:%u;\n", \
(unsigned int)offsetof(typeof(field), item), \
- (unsigned int)sizeof(field.item)); \
+ (unsigned int)sizeof(field.item), \
+ (unsigned int)is_signed_type(type)); \
if (!ret) \
return 0;
@@ -132,19 +166,21 @@
#undef __array
#define __array(type, item, len) \
ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
- "offset:%u;\tsize:%u;\n", \
+ "offset:%u;\tsize:%u;\tsigned:%u;\n", \
(unsigned int)offsetof(typeof(field), item), \
- (unsigned int)sizeof(field.item)); \
+ (unsigned int)sizeof(field.item), \
+ (unsigned int)is_signed_type(type)); \
if (!ret) \
return 0;
#undef __dynamic_array
#define __dynamic_array(type, item, len) \
ret = trace_seq_printf(s, "\tfield:__data_loc " #type "[] " #item ";\t"\
- "offset:%u;\tsize:%u;\n", \
+ "offset:%u;\tsize:%u;\tsigned:%u;\n", \
(unsigned int)offsetof(typeof(field), \
__data_loc_##item), \
- (unsigned int)sizeof(field.__data_loc_##item)); \
+ (unsigned int)sizeof(field.__data_loc_##item), \
+ (unsigned int)is_signed_type(type)); \
if (!ret) \
return 0;
@@ -159,7 +195,7 @@
#undef __get_str
#undef TP_printk
-#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
+#define TP_printk(fmt, args...) "\"%s\", %s\n", fmt, __stringify(args)
#undef TP_fast_assign
#define TP_fast_assign(args...) args
@@ -167,17 +203,50 @@
#undef TP_perf_assign
#define TP_perf_assign(args...)
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \
static int \
-ftrace_format_##call(struct ftrace_event_call *unused, \
- struct trace_seq *s) \
+ftrace_format_setup_##call(struct ftrace_event_call *unused, \
+ struct trace_seq *s) \
{ \
struct ftrace_raw_##call field __attribute__((unused)); \
int ret = 0; \
\
tstruct; \
\
+ return ret; \
+} \
+ \
+static int \
+ftrace_format_##call(struct ftrace_event_call *unused, \
+ struct trace_seq *s) \
+{ \
+ int ret = 0; \
+ \
+ ret = ftrace_format_setup_##call(unused, s); \
+ if (!ret) \
+ return ret; \
+ \
+ ret = trace_seq_printf(s, "\nprint fmt: " print); \
+ \
+ return ret; \
+}
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, name, proto, args)
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+static int \
+ftrace_format_##name(struct ftrace_event_call *unused, \
+ struct trace_seq *s) \
+{ \
+ int ret = 0; \
+ \
+ ret = ftrace_format_setup_##template(unused, s); \
+ if (!ret) \
+ return ret; \
+ \
trace_seq_printf(s, "\nprint fmt: " print); \
\
return ret; \
@@ -252,10 +321,11 @@ ftrace_format_##call(struct ftrace_event_call *unused, \
ftrace_print_symbols_seq(p, value, symbols); \
})
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
static enum print_line_t \
-ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
+ftrace_raw_output_id_##call(int event_id, const char *name, \
+ struct trace_iterator *iter, int flags) \
{ \
struct trace_seq *s = &iter->seq; \
struct ftrace_raw_##call *field; \
@@ -265,6 +335,47 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
\
entry = iter->ent; \
\
+ if (entry->type != event_id) { \
+ WARN_ON_ONCE(1); \
+ return TRACE_TYPE_UNHANDLED; \
+ } \
+ \
+ field = (typeof(field))entry; \
+ \
+ p = &get_cpu_var(ftrace_event_seq); \
+ trace_seq_init(p); \
+ ret = trace_seq_printf(s, "%s: ", name); \
+ if (ret) \
+ ret = trace_seq_printf(s, print); \
+ put_cpu(); \
+ if (!ret) \
+ return TRACE_TYPE_PARTIAL_LINE; \
+ \
+ return TRACE_TYPE_HANDLED; \
+}
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, name, proto, args) \
+static enum print_line_t \
+ftrace_raw_output_##name(struct trace_iterator *iter, int flags) \
+{ \
+ return ftrace_raw_output_id_##template(event_##name.id, \
+ #name, iter, flags); \
+}
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \
+static enum print_line_t \
+ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
+{ \
+ struct trace_seq *s = &iter->seq; \
+ struct ftrace_raw_##template *field; \
+ struct trace_entry *entry; \
+ struct trace_seq *p; \
+ int ret; \
+ \
+ entry = iter->ent; \
+ \
if (entry->type != event_##call.id) { \
WARN_ON_ONCE(1); \
return TRACE_TYPE_UNHANDLED; \
@@ -274,14 +385,16 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
\
p = &get_cpu_var(ftrace_event_seq); \
trace_seq_init(p); \
- ret = trace_seq_printf(s, #call ": " print); \
+ ret = trace_seq_printf(s, "%s: ", #call); \
+ if (ret) \
+ ret = trace_seq_printf(s, print); \
put_cpu(); \
if (!ret) \
return TRACE_TYPE_PARTIAL_LINE; \
\
return TRACE_TYPE_HANDLED; \
}
-
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
#undef __field_ext
@@ -315,8 +428,8 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \
static int \
ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
{ \
@@ -332,6 +445,13 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
return ret; \
}
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, name, proto, args)
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+ DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
/*
@@ -358,10 +478,10 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
__data_size += (len) * sizeof(type);
#undef __string
-#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1) \
+#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1)
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
static inline int ftrace_get_offsets_##call( \
struct ftrace_data_offsets_##call *__data_offsets, proto) \
{ \
@@ -373,6 +493,13 @@ static inline int ftrace_get_offsets_##call( \
return __data_size; \
}
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, name, proto, args)
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+ DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
#ifdef CONFIG_EVENT_PROFILE
@@ -394,21 +521,28 @@ static inline int ftrace_get_offsets_##call( \
*
*/
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, name, proto, args) \
\
-static void ftrace_profile_##call(proto); \
+static void ftrace_profile_##name(proto); \
\
-static int ftrace_profile_enable_##call(void) \
+static int ftrace_profile_enable_##name(struct ftrace_event_call *unused)\
{ \
- return register_trace_##call(ftrace_profile_##call); \
+ return register_trace_##name(ftrace_profile_##name); \
} \
\
-static void ftrace_profile_disable_##call(void) \
+static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\
{ \
- unregister_trace_##call(ftrace_profile_##call); \
+ unregister_trace_##name(ftrace_profile_##name); \
}
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+ DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
#endif
@@ -423,7 +557,7 @@ static void ftrace_profile_disable_##call(void) \
* event_trace_printk(_RET_IP_, "<call>: " <fmt>);
* }
*
- * static int ftrace_reg_event_<call>(void)
+ * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused)
* {
* int ret;
*
@@ -434,7 +568,7 @@ static void ftrace_profile_disable_##call(void) \
* return ret;
* }
*
- * static void ftrace_unreg_event_<call>(void)
+ * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
* {
* unregister_trace_<call>(ftrace_event_<call>);
* }
@@ -469,7 +603,7 @@ static void ftrace_profile_disable_##call(void) \
* trace_current_buffer_unlock_commit(buffer, event, irq_flags, pc);
* }
*
- * static int ftrace_raw_reg_event_<call>(void)
+ * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused)
* {
* int ret;
*
@@ -480,7 +614,7 @@ static void ftrace_profile_disable_##call(void) \
* return ret;
* }
*
- * static void ftrace_unreg_event_<call>(void)
+ * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
* {
* unregister_trace_<call>(ftrace_raw_event_<call>);
* }
@@ -489,7 +623,7 @@ static void ftrace_profile_disable_##call(void) \
* .trace = ftrace_raw_output_<call>, <-- stage 2
* };
*
- * static int ftrace_raw_init_event_<call>(void)
+ * static int ftrace_raw_init_event_<call>(struct ftrace_event_call *unused)
* {
* int id;
*
@@ -547,15 +681,13 @@ static void ftrace_profile_disable_##call(void) \
#define __assign_str(dst, src) \
strcpy(__get_str(dst), src);
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
\
-static struct ftrace_event_call event_##call; \
- \
-static void ftrace_raw_event_##call(proto) \
+static void ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \
+ proto) \
{ \
struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
- struct ftrace_event_call *event_call = &event_##call; \
struct ring_buffer_event *event; \
struct ftrace_raw_##call *entry; \
struct ring_buffer *buffer; \
@@ -569,7 +701,7 @@ static void ftrace_raw_event_##call(proto) \
__data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
\
event = trace_current_buffer_lock_reserve(&buffer, \
- event_##call.id, \
+ event_call->id, \
sizeof(*entry) + __data_size, \
irq_flags, pc); \
if (!event) \
@@ -584,9 +716,17 @@ static void ftrace_raw_event_##call(proto) \
if (!filter_current_check_discard(buffer, event_call, entry, event)) \
trace_nowake_buffer_unlock_commit(buffer, \
event, irq_flags, pc); \
+}
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, call, proto, args) \
+ \
+static void ftrace_raw_event_##call(proto) \
+{ \
+ ftrace_raw_event_id_##template(&event_##call, args); \
} \
\
-static int ftrace_raw_reg_event_##call(void *ptr) \
+static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\
{ \
int ret; \
\
@@ -597,7 +737,7 @@ static int ftrace_raw_reg_event_##call(void *ptr) \
return ret; \
} \
\
-static void ftrace_raw_unreg_event_##call(void *ptr) \
+static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\
{ \
unregister_trace_##call(ftrace_raw_event_##call); \
} \
@@ -606,7 +746,7 @@ static struct trace_event ftrace_event_type_##call = { \
.trace = ftrace_raw_output_##call, \
}; \
\
-static int ftrace_raw_init_event_##call(void) \
+static int ftrace_raw_init_event_##call(struct ftrace_event_call *unused)\
{ \
int id; \
\
@@ -616,7 +756,36 @@ static int ftrace_raw_init_event_##call(void) \
event_##call.id = id; \
INIT_LIST_HEAD(&event_##call.fields); \
return 0; \
-} \
+}
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+ DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, call, proto, args) \
+ \
+static struct ftrace_event_call __used \
+__attribute__((__aligned__(4))) \
+__attribute__((section("_ftrace_events"))) event_##call = { \
+ .name = #call, \
+ .system = __stringify(TRACE_SYSTEM), \
+ .event = &ftrace_event_type_##call, \
+ .raw_init = ftrace_raw_init_event_##call, \
+ .regfunc = ftrace_raw_reg_event_##call, \
+ .unregfunc = ftrace_raw_unreg_event_##call, \
+ .show_format = ftrace_format_##template, \
+ .define_fields = ftrace_define_fields_##template, \
+ _TRACE_PROFILE_INIT(call) \
+}
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \
\
static struct ftrace_event_call __used \
__attribute__((__aligned__(4))) \
@@ -628,7 +797,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
.regfunc = ftrace_raw_reg_event_##call, \
.unregfunc = ftrace_raw_unreg_event_##call, \
.show_format = ftrace_format_##call, \
- .define_fields = ftrace_define_fields_##call, \
+ .define_fields = ftrace_define_fields_##template, \
_TRACE_PROFILE_INIT(call) \
}
@@ -646,6 +815,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
* struct ftrace_event_call *event_call = &event_<call>;
* extern void perf_tp_event(int, u64, u64, void *, int);
* struct ftrace_raw_##call *entry;
+ * struct perf_trace_buf *trace_buf;
* u64 __addr = 0, __count = 1;
* unsigned long irq_flags;
* struct trace_entry *ent;
@@ -670,14 +840,25 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
* __cpu = smp_processor_id();
*
* if (in_nmi())
- * raw_data = rcu_dereference(trace_profile_buf_nmi);
+ * trace_buf = rcu_dereference(perf_trace_buf_nmi);
* else
- * raw_data = rcu_dereference(trace_profile_buf);
+ * trace_buf = rcu_dereference(perf_trace_buf);
*
- * if (!raw_data)
+ * if (!trace_buf)
* goto end;
*
- * raw_data = per_cpu_ptr(raw_data, __cpu);
+ * trace_buf = per_cpu_ptr(trace_buf, __cpu);
+ *
+ * // Avoid recursion from perf that could mess up the buffer
+ * if (trace_buf->recursion++)
+ * goto end_recursion;
+ *
+ * raw_data = trace_buf->buf;
+ *
+ * // Make recursion update visible before entering perf_tp_event
+ * // so that we protect from perf recursions.
+ *
+ * barrier();
*
* //zero dead bytes from alignment to avoid stack leak to userspace:
* *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;
@@ -704,21 +885,26 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
#undef __perf_count
#define __perf_count(c) __count = (c)
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
-static void ftrace_profile_##call(proto) \
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
+static void \
+ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \
+ proto) \
{ \
struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
- struct ftrace_event_call *event_call = &event_##call; \
- extern void perf_tp_event(int, u64, u64, void *, int); \
+ extern int perf_swevent_get_recursion_context(void); \
+ extern void perf_swevent_put_recursion_context(int rctx); \
+ extern void perf_tp_event(int, u64, u64, void *, int); \
struct ftrace_raw_##call *entry; \
u64 __addr = 0, __count = 1; \
unsigned long irq_flags; \
struct trace_entry *ent; \
int __entry_size; \
int __data_size; \
+ char *trace_buf; \
char *raw_data; \
int __cpu; \
+ int rctx; \
int pc; \
\
pc = preempt_count(); \
@@ -733,17 +919,22 @@ static void ftrace_profile_##call(proto) \
return; \
\
local_irq_save(irq_flags); \
+ \
+ rctx = perf_swevent_get_recursion_context(); \
+ if (rctx < 0) \
+ goto end_recursion; \
+ \
__cpu = smp_processor_id(); \
\
if (in_nmi()) \
- raw_data = rcu_dereference(trace_profile_buf_nmi); \
+ trace_buf = rcu_dereference(perf_trace_buf_nmi); \
else \
- raw_data = rcu_dereference(trace_profile_buf); \
+ trace_buf = rcu_dereference(perf_trace_buf); \
\
- if (!raw_data) \
+ if (!trace_buf) \
goto end; \
\
- raw_data = per_cpu_ptr(raw_data, __cpu); \
+ raw_data = per_cpu_ptr(trace_buf, __cpu); \
\
*(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; \
entry = (struct ftrace_raw_##call *)raw_data; \
@@ -759,10 +950,25 @@ static void ftrace_profile_##call(proto) \
__entry_size); \
\
end: \
+ perf_swevent_put_recursion_context(rctx); \
+end_recursion: \
local_irq_restore(irq_flags); \
\
}
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, call, proto, args) \
+static void ftrace_profile_##call(proto) \
+{ \
+ struct ftrace_event_call *event_call = &event_##call; \
+ \
+ ftrace_profile_templ_##template(event_call, args); \
+}
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
+ DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
#endif /* CONFIG_EVENT_PROFILE */
diff --git a/include/trace/power.h b/include/trace/power.h
deleted file mode 100644
index ef204666e983..000000000000
--- a/include/trace/power.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _TRACE_POWER_H
-#define _TRACE_POWER_H
-
-#include <linux/ktime.h>
-#include <linux/tracepoint.h>
-
-enum {
- POWER_NONE = 0,
- POWER_CSTATE = 1,
- POWER_PSTATE = 2,
-};
-
-struct power_trace {
- ktime_t stamp;
- ktime_t end;
- int type;
- int state;
-};
-
-DECLARE_TRACE(power_start,
- TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state),
- TP_ARGS(it, type, state));
-
-DECLARE_TRACE(power_mark,
- TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state),
- TP_ARGS(it, type, state));
-
-DECLARE_TRACE(power_end,
- TP_PROTO(struct power_trace *it),
- TP_ARGS(it));
-
-#endif /* _TRACE_POWER_H */
diff --git a/include/trace/syscall.h b/include/trace/syscall.h
index 5dc283ba5ae0..961fda3556bb 100644
--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -12,51 +12,48 @@
* A syscall entry in the ftrace syscalls array.
*
* @name: name of the syscall
+ * @syscall_nr: number of the syscall
* @nb_args: number of parameters it takes
* @types: list of types as strings
* @args: list of args as strings (args[i] matches types[i])
- * @enter_id: associated ftrace enter event id
- * @exit_id: associated ftrace exit event id
* @enter_event: associated syscall_enter trace event
* @exit_event: associated syscall_exit trace event
*/
struct syscall_metadata {
const char *name;
+ int syscall_nr;
int nb_args;
const char **types;
const char **args;
- int enter_id;
- int exit_id;
struct ftrace_event_call *enter_event;
struct ftrace_event_call *exit_event;
};
#ifdef CONFIG_FTRACE_SYSCALLS
-extern struct syscall_metadata *syscall_nr_to_meta(int nr);
-extern int syscall_name_to_nr(char *name);
-void set_syscall_enter_id(int num, int id);
-void set_syscall_exit_id(int num, int id);
-extern struct trace_event event_syscall_enter;
-extern struct trace_event event_syscall_exit;
-extern int reg_event_syscall_enter(void *ptr);
-extern void unreg_event_syscall_enter(void *ptr);
-extern int reg_event_syscall_exit(void *ptr);
-extern void unreg_event_syscall_exit(void *ptr);
+extern unsigned long arch_syscall_addr(int nr);
+extern int init_syscall_trace(struct ftrace_event_call *call);
+
extern int syscall_enter_format(struct ftrace_event_call *call,
struct trace_seq *s);
extern int syscall_exit_format(struct ftrace_event_call *call,
struct trace_seq *s);
extern int syscall_enter_define_fields(struct ftrace_event_call *call);
extern int syscall_exit_define_fields(struct ftrace_event_call *call);
+extern int reg_event_syscall_enter(struct ftrace_event_call *call);
+extern void unreg_event_syscall_enter(struct ftrace_event_call *call);
+extern int reg_event_syscall_exit(struct ftrace_event_call *call);
+extern void unreg_event_syscall_exit(struct ftrace_event_call *call);
+extern int
+ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s);
enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags);
enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags);
#endif
#ifdef CONFIG_EVENT_PROFILE
-int reg_prof_syscall_enter(char *name);
-void unreg_prof_syscall_enter(char *name);
-int reg_prof_syscall_exit(char *name);
-void unreg_prof_syscall_exit(char *name);
+int prof_sysenter_enable(struct ftrace_event_call *call);
+void prof_sysenter_disable(struct ftrace_event_call *call);
+int prof_sysexit_enable(struct ftrace_event_call *call);
+void prof_sysexit_disable(struct ftrace_event_call *call);
#endif
diff --git a/init/Kconfig b/init/Kconfig
index 09c5c6431f42..9ee778294756 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -297,7 +297,7 @@ config AUDIT
config AUDITSYSCALL
bool "Enable system-call auditing support"
- depends on AUDIT && (X86 || PPC || PPC64 || S390 || IA64 || UML || SPARC64|| SUPERH)
+ depends on AUDIT && (X86 || PPC || S390 || IA64 || UML || SPARC64 || SUPERH)
default y if SECURITY_SELINUX
help
Enable low-overhead system-call auditing infrastructure that
@@ -334,6 +334,15 @@ config TREE_PREEMPT_RCU
is also required. It also scales down nicely to
smaller systems.
+config TINY_RCU
+ bool "UP-only small-memory-footprint RCU"
+ depends on !SMP
+ help
+ This option selects the RCU implementation that is
+ designed for UP systems from which real-time response
+ is not required. This option greatly reduces the
+ memory footprint of RCU.
+
endchoice
config RCU_TRACE
@@ -606,7 +615,7 @@ config SYSFS_DEPRECATED
bool
config SYSFS_DEPRECATED_V2
- bool "remove sysfs features which may confuse old userspace tools"
+ bool "enable deprecated sysfs features which may confuse old userspace tools"
depends on SYSFS
default n
select SYSFS_DEPRECATED
@@ -937,7 +946,7 @@ config PERF_EVENTS
Enable kernel support for various performance events provided
by software and hardware.
- Software events are supported either build-in or via the
+ Software events are supported either built-in or via the
use of generic tracepoints.
Most modern CPUs support performance events via performance
@@ -949,7 +958,7 @@ config PERF_EVENTS
used to profile the code that runs on that CPU.
The Linux Performance Event subsystem provides an abstraction of
- these software and hardware cevent apabilities, available via a
+ these software and hardware event capabilities, available via a
system call and used by the "perf" utility in tools/perf/. It
provides per task and per CPU counters, and it provides event
capabilities on top of those.
@@ -1098,6 +1107,16 @@ config SLOW_WORK
See Documentation/slow-work.txt.
+config SLOW_WORK_DEBUG
+ bool "Slow work debugging through debugfs"
+ default n
+ depends on SLOW_WORK && DEBUG_FS
+ help
+ Display the contents of the slow work run queue through debugfs,
+ including items currently executing.
+
+ See Documentation/slow-work.txt.
+
endmenu # General setup
config HAVE_GENERIC_DMA_COHERENT
@@ -1210,3 +1229,4 @@ source "block/Kconfig"
config PREEMPT_NOTIFIERS
bool
+source "kernel/Kconfig.locks"
diff --git a/init/main.c b/init/main.c
index 5988debfc505..4051d75dd2d6 100644
--- a/init/main.c
+++ b/init/main.c
@@ -251,7 +251,7 @@ early_param("loglevel", loglevel);
/*
* Unknown boot options get handed to init, unless they look like
- * failed parameters
+ * unused parameters (modprobe will find them in /proc/cmdline).
*/
static int __init unknown_bootoption(char *param, char *val)
{
@@ -272,14 +272,9 @@ static int __init unknown_bootoption(char *param, char *val)
if (obsolete_checksetup(param))
return 0;
- /*
- * Preemptive maintenance for "why didn't my misspelled command
- * line work?"
- */
- if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
- printk(KERN_ERR "Unknown boot option `%s': ignoring\n", param);
+ /* Unused module parameter. */
+ if (strchr(param, '.') && (!val || strchr(param, '.') < val))
return 0;
- }
if (panic_later)
return 0;
diff --git a/kernel/Kconfig.locks b/kernel/Kconfig.locks
new file mode 100644
index 000000000000..88c92fb44618
--- /dev/null
+++ b/kernel/Kconfig.locks
@@ -0,0 +1,202 @@
+#
+# The ARCH_INLINE foo is necessary because select ignores "depends on"
+#
+config ARCH_INLINE_SPIN_TRYLOCK
+ bool
+
+config ARCH_INLINE_SPIN_TRYLOCK_BH
+ bool
+
+config ARCH_INLINE_SPIN_LOCK
+ bool
+
+config ARCH_INLINE_SPIN_LOCK_BH
+ bool
+
+config ARCH_INLINE_SPIN_LOCK_IRQ
+ bool
+
+config ARCH_INLINE_SPIN_LOCK_IRQSAVE
+ bool
+
+config ARCH_INLINE_SPIN_UNLOCK
+ bool
+
+config ARCH_INLINE_SPIN_UNLOCK_BH
+ bool
+
+config ARCH_INLINE_SPIN_UNLOCK_IRQ
+ bool
+
+config ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
+ bool
+
+
+config ARCH_INLINE_READ_TRYLOCK
+ bool
+
+config ARCH_INLINE_READ_LOCK
+ bool
+
+config ARCH_INLINE_READ_LOCK_BH
+ bool
+
+config ARCH_INLINE_READ_LOCK_IRQ
+ bool
+
+config ARCH_INLINE_READ_LOCK_IRQSAVE
+ bool
+
+config ARCH_INLINE_READ_UNLOCK
+ bool
+
+config ARCH_INLINE_READ_UNLOCK_BH
+ bool
+
+config ARCH_INLINE_READ_UNLOCK_IRQ
+ bool
+
+config ARCH_INLINE_READ_UNLOCK_IRQRESTORE
+ bool
+
+
+config ARCH_INLINE_WRITE_TRYLOCK
+ bool
+
+config ARCH_INLINE_WRITE_LOCK
+ bool
+
+config ARCH_INLINE_WRITE_LOCK_BH
+ bool
+
+config ARCH_INLINE_WRITE_LOCK_IRQ
+ bool
+
+config ARCH_INLINE_WRITE_LOCK_IRQSAVE
+ bool
+
+config ARCH_INLINE_WRITE_UNLOCK
+ bool
+
+config ARCH_INLINE_WRITE_UNLOCK_BH
+ bool
+
+config ARCH_INLINE_WRITE_UNLOCK_IRQ
+ bool
+
+config ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+ bool
+
+#
+# lock_* functions are inlined when:
+# - DEBUG_SPINLOCK=n and GENERIC_LOCKBREAK=n and ARCH_INLINE_*LOCK=y
+#
+# trylock_* functions are inlined when:
+# - DEBUG_SPINLOCK=n and ARCH_INLINE_*LOCK=y
+#
+# unlock and unlock_irq functions are inlined when:
+# - DEBUG_SPINLOCK=n and ARCH_INLINE_*LOCK=y
+# or
+# - DEBUG_SPINLOCK=n and PREEMPT=n
+#
+# unlock_bh and unlock_irqrestore functions are inlined when:
+# - DEBUG_SPINLOCK=n and ARCH_INLINE_*LOCK=y
+#
+
+config INLINE_SPIN_TRYLOCK
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_SPIN_TRYLOCK
+
+config INLINE_SPIN_TRYLOCK_BH
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_SPIN_TRYLOCK_BH
+
+config INLINE_SPIN_LOCK
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && ARCH_INLINE_SPIN_LOCK
+
+config INLINE_SPIN_LOCK_BH
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+ ARCH_INLINE_SPIN_LOCK_BH
+
+config INLINE_SPIN_LOCK_IRQ
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+ ARCH_INLINE_SPIN_LOCK_IRQ
+
+config INLINE_SPIN_LOCK_IRQSAVE
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+ ARCH_INLINE_SPIN_LOCK_IRQSAVE
+
+config INLINE_SPIN_UNLOCK
+ def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_SPIN_UNLOCK)
+
+config INLINE_SPIN_UNLOCK_BH
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_SPIN_UNLOCK_BH
+
+config INLINE_SPIN_UNLOCK_IRQ
+ def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_SPIN_UNLOCK_BH)
+
+config INLINE_SPIN_UNLOCK_IRQRESTORE
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
+
+
+config INLINE_READ_TRYLOCK
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_READ_TRYLOCK
+
+config INLINE_READ_LOCK
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && ARCH_INLINE_READ_LOCK
+
+config INLINE_READ_LOCK_BH
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+ ARCH_INLINE_READ_LOCK_BH
+
+config INLINE_READ_LOCK_IRQ
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+ ARCH_INLINE_READ_LOCK_IRQ
+
+config INLINE_READ_LOCK_IRQSAVE
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+ ARCH_INLINE_READ_LOCK_IRQSAVE
+
+config INLINE_READ_UNLOCK
+ def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_READ_UNLOCK)
+
+config INLINE_READ_UNLOCK_BH
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_READ_UNLOCK_BH
+
+config INLINE_READ_UNLOCK_IRQ
+ def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_READ_UNLOCK_BH)
+
+config INLINE_READ_UNLOCK_IRQRESTORE
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_READ_UNLOCK_IRQRESTORE
+
+
+config INLINE_WRITE_TRYLOCK
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_WRITE_TRYLOCK
+
+config INLINE_WRITE_LOCK
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && ARCH_INLINE_WRITE_LOCK
+
+config INLINE_WRITE_LOCK_BH
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+ ARCH_INLINE_WRITE_LOCK_BH
+
+config INLINE_WRITE_LOCK_IRQ
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+ ARCH_INLINE_WRITE_LOCK_IRQ
+
+config INLINE_WRITE_LOCK_IRQSAVE
+ def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+ ARCH_INLINE_WRITE_LOCK_IRQSAVE
+
+config INLINE_WRITE_UNLOCK
+ def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_WRITE_UNLOCK)
+
+config INLINE_WRITE_UNLOCK_BH
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_WRITE_UNLOCK_BH
+
+config INLINE_WRITE_UNLOCK_IRQ
+ def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_WRITE_UNLOCK_BH)
+
+config INLINE_WRITE_UNLOCK_IRQRESTORE
+ def_bool !DEBUG_SPINLOCK && ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+
+config MUTEX_SPIN_ON_OWNER
+ def_bool SMP && !DEBUG_MUTEXES && !HAVE_DEFAULT_NO_SPIN_MUTEXES
diff --git a/kernel/Makefile b/kernel/Makefile
index b8d4cd8ac0b9..982c50e2ce53 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -21,6 +21,7 @@ CFLAGS_REMOVE_mutex-debug.o = -pg
CFLAGS_REMOVE_rtmutex-debug.o = -pg
CFLAGS_REMOVE_cgroup-debug.o = -pg
CFLAGS_REMOVE_sched_clock.o = -pg
+CFLAGS_REMOVE_perf_event.o = -pg
endif
obj-$(CONFIG_FREEZER) += freezer.o
@@ -82,6 +83,7 @@ obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
obj-$(CONFIG_TREE_RCU) += rcutree.o
obj-$(CONFIG_TREE_PREEMPT_RCU) += rcutree.o
obj-$(CONFIG_TREE_RCU_TRACE) += rcutree_trace.o
+obj-$(CONFIG_TINY_RCU) += rcutiny.o
obj-$(CONFIG_RELAY) += relay.o
obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
@@ -94,7 +96,9 @@ obj-$(CONFIG_X86_DS) += trace/
obj-$(CONFIG_RING_BUFFER) += trace/
obj-$(CONFIG_SMP) += sched_cpupri.o
obj-$(CONFIG_SLOW_WORK) += slow-work.o
+obj-$(CONFIG_SLOW_WORK_DEBUG) += slow-work-debugfs.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/capability.c b/kernel/capability.c
index 4e17041963f5..7f876e60521f 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -29,7 +29,6 @@ EXPORT_SYMBOL(__cap_empty_set);
EXPORT_SYMBOL(__cap_full_set);
EXPORT_SYMBOL(__cap_init_eff_set);
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
int file_caps_enabled = 1;
static int __init file_caps_disable(char *str)
@@ -38,7 +37,6 @@ static int __init file_caps_disable(char *str)
return 1;
}
__setup("no_file_caps", file_caps_disable);
-#endif
/*
* More recent versions of libcap are available from:
@@ -169,8 +167,8 @@ SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr)
kernel_cap_t pE, pI, pP;
ret = cap_validate_magic(header, &tocopy);
- if (ret != 0)
- return ret;
+ if ((dataptr == NULL) || (ret != 0))
+ return ((dataptr == NULL) && (ret == -EINVAL)) ? 0 : ret;
if (get_user(pid, &header->pid))
return -EFAULT;
@@ -238,7 +236,7 @@ SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr)
SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data)
{
struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S];
- unsigned i, tocopy;
+ unsigned i, tocopy, copybytes;
kernel_cap_t inheritable, permitted, effective;
struct cred *new;
int ret;
@@ -255,8 +253,11 @@ SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data)
if (pid != 0 && pid != task_pid_vnr(current))
return -EPERM;
- if (copy_from_user(&kdata, data,
- tocopy * sizeof(struct __user_cap_data_struct)))
+ copybytes = tocopy * sizeof(struct __user_cap_data_struct);
+ if (copybytes > sizeof(kdata))
+ return -EFAULT;
+
+ if (copy_from_user(&kdata, data, copybytes))
return -EFAULT;
for (i = 0; i < tocopy; i++) {
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index ca83b73fba19..0249f4be9b5c 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1710,14 +1710,13 @@ static ssize_t cgroup_write_X64(struct cgroup *cgrp, struct cftype *cft,
return -EFAULT;
buffer[nbytes] = 0; /* nul-terminate */
- strstrip(buffer);
if (cft->write_u64) {
- u64 val = simple_strtoull(buffer, &end, 0);
+ u64 val = simple_strtoull(strstrip(buffer), &end, 0);
if (*end)
return -EINVAL;
retval = cft->write_u64(cgrp, cft, val);
} else {
- s64 val = simple_strtoll(buffer, &end, 0);
+ s64 val = simple_strtoll(strstrip(buffer), &end, 0);
if (*end)
return -EINVAL;
retval = cft->write_s64(cgrp, cft, val);
@@ -1753,8 +1752,7 @@ static ssize_t cgroup_write_string(struct cgroup *cgrp, struct cftype *cft,
}
buffer[nbytes] = 0; /* nul-terminate */
- strstrip(buffer);
- retval = cft->write_string(cgrp, cft, buffer);
+ retval = cft->write_string(cgrp, cft, strstrip(buffer));
if (!retval)
retval = nbytes;
out:
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index b5cb469d2545..3cf2183b472d 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -537,8 +537,7 @@ update_domain_attr_tree(struct sched_domain_attr *dattr, struct cpuset *c)
* element of the partition (one sched domain) to be passed to
* partition_sched_domains().
*/
-/* FIXME: see the FIXME in partition_sched_domains() */
-static int generate_sched_domains(struct cpumask **domains,
+static int generate_sched_domains(cpumask_var_t **domains,
struct sched_domain_attr **attributes)
{
LIST_HEAD(q); /* queue of cpusets to be scanned */
@@ -546,7 +545,7 @@ static int generate_sched_domains(struct cpumask **domains,
struct cpuset **csa; /* array of all cpuset ptrs */
int csn; /* how many cpuset ptrs in csa so far */
int i, j, k; /* indices for partition finding loops */
- struct cpumask *doms; /* resulting partition; i.e. sched domains */
+ cpumask_var_t *doms; /* resulting partition; i.e. sched domains */
struct sched_domain_attr *dattr; /* attributes for custom domains */
int ndoms = 0; /* number of sched domains in result */
int nslot; /* next empty doms[] struct cpumask slot */
@@ -557,7 +556,8 @@ static int generate_sched_domains(struct cpumask **domains,
/* Special case for the 99% of systems with one, full, sched domain */
if (is_sched_load_balance(&top_cpuset)) {
- doms = kmalloc(cpumask_size(), GFP_KERNEL);
+ ndoms = 1;
+ doms = alloc_sched_domains(ndoms);
if (!doms)
goto done;
@@ -566,9 +566,8 @@ static int generate_sched_domains(struct cpumask **domains,
*dattr = SD_ATTR_INIT;
update_domain_attr_tree(dattr, &top_cpuset);
}
- cpumask_copy(doms, top_cpuset.cpus_allowed);
+ cpumask_copy(doms[0], top_cpuset.cpus_allowed);
- ndoms = 1;
goto done;
}
@@ -636,7 +635,7 @@ restart:
* Now we know how many domains to create.
* Convert <csn, csa> to <ndoms, doms> and populate cpu masks.
*/
- doms = kmalloc(ndoms * cpumask_size(), GFP_KERNEL);
+ doms = alloc_sched_domains(ndoms);
if (!doms)
goto done;
@@ -656,7 +655,7 @@ restart:
continue;
}
- dp = doms + nslot;
+ dp = doms[nslot];
if (nslot == ndoms) {
static int warnings = 10;
@@ -718,7 +717,7 @@ done:
static void do_rebuild_sched_domains(struct work_struct *unused)
{
struct sched_domain_attr *attr;
- struct cpumask *doms;
+ cpumask_var_t *doms;
int ndoms;
get_online_cpus();
@@ -2052,7 +2051,7 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
unsigned long phase, void *unused_cpu)
{
struct sched_domain_attr *attr;
- struct cpumask *doms;
+ cpumask_var_t *doms;
int ndoms;
switch (phase) {
@@ -2537,15 +2536,9 @@ const struct file_operations proc_cpuset_operations = {
};
#endif /* CONFIG_PROC_PID_CPUSET */
-/* Display task cpus_allowed, mems_allowed in /proc/<pid>/status file. */
+/* Display task mems_allowed in /proc/<pid>/status file. */
void cpuset_task_status_allowed(struct seq_file *m, struct task_struct *task)
{
- seq_printf(m, "Cpus_allowed:\t");
- seq_cpumask(m, &task->cpus_allowed);
- seq_printf(m, "\n");
- seq_printf(m, "Cpus_allowed_list:\t");
- seq_cpumask_list(m, &task->cpus_allowed);
- seq_printf(m, "\n");
seq_printf(m, "Mems_allowed:\t");
seq_nodemask(m, &task->mems_allowed);
seq_printf(m, "\n");
diff --git a/kernel/exit.c b/kernel/exit.c
index e61891f80123..80ae941cfd2e 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -49,6 +49,7 @@
#include <linux/init_task.h>
#include <linux/perf_event.h>
#include <trace/events/sched.h>
+#include <linux/hw_breakpoint.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -110,9 +111,9 @@ static void __exit_signal(struct task_struct *tsk)
* We won't ever get here for the group leader, since it
* will have been the last reference on the signal_struct.
*/
- sig->utime = cputime_add(sig->utime, task_utime(tsk));
- sig->stime = cputime_add(sig->stime, task_stime(tsk));
- sig->gtime = cputime_add(sig->gtime, task_gtime(tsk));
+ sig->utime = cputime_add(sig->utime, tsk->utime);
+ sig->stime = cputime_add(sig->stime, tsk->stime);
+ sig->gtime = cputime_add(sig->gtime, tsk->gtime);
sig->min_flt += tsk->min_flt;
sig->maj_flt += tsk->maj_flt;
sig->nvcsw += tsk->nvcsw;
@@ -359,10 +360,8 @@ void __set_special_pids(struct pid *pid)
{
struct task_struct *curr = current->group_leader;
- if (task_session(curr) != pid) {
+ if (task_session(curr) != pid)
change_pid(curr, PIDTYPE_SID, pid);
- proc_sid_connector(curr);
- }
if (task_pgrp(curr) != pid)
change_pid(curr, PIDTYPE_PGID, pid);
@@ -980,6 +979,10 @@ NORET_TYPE void do_exit(long code)
proc_exit_connector(tsk);
/*
+ * FIXME: do that only when needed, using sched_exit tracepoint
+ */
+ flush_ptrace_hw_breakpoint(tsk);
+ /*
* Flush inherited counters to the parent - before the parent
* gets woken up by child-exit notifications.
*/
@@ -1207,6 +1210,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
struct signal_struct *psig;
struct signal_struct *sig;
unsigned long maxrss;
+ cputime_t tgutime, tgstime;
/*
* The resource counters for the group leader are in its
@@ -1222,20 +1226,23 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
* need to protect the access to parent->signal fields,
* as other threads in the parent group can be right
* here reaping other children at the same time.
+ *
+ * We use thread_group_times() to get times for the thread
+ * group, which consolidates times for all threads in the
+ * group including the group leader.
*/
+ thread_group_times(p, &tgutime, &tgstime);
spin_lock_irq(&p->real_parent->sighand->siglock);
psig = p->real_parent->signal;
sig = p->signal;
psig->cutime =
cputime_add(psig->cutime,
- cputime_add(p->utime,
- cputime_add(sig->utime,
- sig->cutime)));
+ cputime_add(tgutime,
+ sig->cutime));
psig->cstime =
cputime_add(psig->cstime,
- cputime_add(p->stime,
- cputime_add(sig->stime,
- sig->cstime)));
+ cputime_add(tgstime,
+ sig->cstime));
psig->cgtime =
cputime_add(psig->cgtime,
cputime_add(p->gtime,
diff --git a/kernel/fork.c b/kernel/fork.c
index 4c20fff8c13a..3d6f121bbe8a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -91,7 +91,7 @@ int nr_processes(void)
int cpu;
int total = 0;
- for_each_online_cpu(cpu)
+ for_each_possible_cpu(cpu)
total += per_cpu(process_counts, cpu);
return total;
@@ -884,6 +884,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
sig->gtime = cputime_zero;
sig->cgtime = cputime_zero;
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+ sig->prev_utime = sig->prev_stime = cputime_zero;
+#endif
sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
@@ -1066,8 +1069,10 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->gtime = cputime_zero;
p->utimescaled = cputime_zero;
p->stimescaled = cputime_zero;
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
p->prev_utime = cputime_zero;
p->prev_stime = cputime_zero;
+#endif
p->default_timer_slack_ns = current->timer_slack_ns;
diff --git a/kernel/futex.c b/kernel/futex.c
index 4949d336d88d..fb65e822fc41 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -150,7 +150,8 @@ static struct futex_hash_bucket *hash_futex(union futex_key *key)
*/
static inline int match_futex(union futex_key *key1, union futex_key *key2)
{
- return (key1->both.word == key2->both.word
+ return (key1 && key2
+ && key1->both.word == key2->both.word
&& key1->both.ptr == key2->both.ptr
&& key1->both.offset == key2->both.offset);
}
@@ -1028,7 +1029,6 @@ static inline
void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
struct futex_hash_bucket *hb)
{
- drop_futex_key_refs(&q->key);
get_futex_key_refs(key);
q->key = *key;
@@ -1226,6 +1226,7 @@ retry_private:
*/
if (ret == 1) {
WARN_ON(pi_state);
+ drop_count++;
task_count++;
ret = get_futex_value_locked(&curval2, uaddr2);
if (!ret)
@@ -1304,6 +1305,7 @@ retry_private:
if (ret == 1) {
/* We got the lock. */
requeue_pi_wake_futex(this, &key2, hb2);
+ drop_count++;
continue;
} else if (ret) {
/* -EDEADLK */
@@ -1791,6 +1793,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
current->timer_slack_ns);
}
+retry:
/* Prepare to wait on uaddr. */
ret = futex_wait_setup(uaddr, val, fshared, &q, &hb);
if (ret)
@@ -1808,9 +1811,14 @@ static int futex_wait(u32 __user *uaddr, int fshared,
goto out_put_key;
/*
- * We expect signal_pending(current), but another thread may
- * have handled it for us already.
+ * We expect signal_pending(current), but we might be the
+ * victim of a spurious wakeup as well.
*/
+ if (!signal_pending(current)) {
+ put_futex_key(fshared, &q.key);
+ goto retry;
+ }
+
ret = -ERESTARTSYS;
if (!abs_time)
goto out_put_key;
@@ -2118,9 +2126,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
*/
plist_del(&q->list, &q->list.plist);
+ /* Handle spurious wakeups gracefully */
+ ret = -EWOULDBLOCK;
if (timeout && !timeout->task)
ret = -ETIMEDOUT;
- else
+ else if (signal_pending(current))
ret = -ERESTARTNOINTR;
}
return ret;
diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index d4e841747400..0c642d51aac2 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -144,7 +144,7 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
rcu_read_lock();
do_each_thread(g, t) {
- if (!--max_count)
+ if (!max_count--)
goto unlock;
if (!--batch_count) {
batch_count = HUNG_TASK_BATCHING;
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c
new file mode 100644
index 000000000000..cf5ee1628411
--- /dev/null
+++ b/kernel/hw_breakpoint.c
@@ -0,0 +1,423 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2007 Alan Stern
+ * Copyright (C) IBM Corporation, 2009
+ * Copyright (C) 2009, Frederic Weisbecker <fweisbec@gmail.com>
+ *
+ * Thanks to Ingo Molnar for his many suggestions.
+ *
+ * Authors: Alan Stern <stern@rowland.harvard.edu>
+ * K.Prasad <prasad@linux.vnet.ibm.com>
+ * Frederic Weisbecker <fweisbec@gmail.com>
+ */
+
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers.
+ * This file contains the arch-independent routines.
+ */
+
+#include <linux/irqflags.h>
+#include <linux/kallsyms.h>
+#include <linux/notifier.h>
+#include <linux/kprobes.h>
+#include <linux/kdebug.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <linux/hw_breakpoint.h>
+
+/*
+ * Constraints data
+ */
+
+/* Number of pinned cpu breakpoints in a cpu */
+static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned);
+
+/* Number of pinned task breakpoints in a cpu */
+static DEFINE_PER_CPU(unsigned int, task_bp_pinned[HBP_NUM]);
+
+/* Number of non-pinned cpu/task breakpoints in a cpu */
+static DEFINE_PER_CPU(unsigned int, nr_bp_flexible);
+
+/* Gather the number of total pinned and un-pinned bp in a cpuset */
+struct bp_busy_slots {
+ unsigned int pinned;
+ unsigned int flexible;
+};
+
+/* Serialize accesses to the above constraints */
+static DEFINE_MUTEX(nr_bp_mutex);
+
+/*
+ * Report the maximum number of pinned breakpoints a task
+ * have in this cpu
+ */
+static unsigned int max_task_bp_pinned(int cpu)
+{
+ int i;
+ unsigned int *tsk_pinned = per_cpu(task_bp_pinned, cpu);
+
+ for (i = HBP_NUM -1; i >= 0; i--) {
+ if (tsk_pinned[i] > 0)
+ return i + 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Report the number of pinned/un-pinned breakpoints we have in
+ * a given cpu (cpu > -1) or in all of them (cpu = -1).
+ */
+static void fetch_bp_busy_slots(struct bp_busy_slots *slots, int cpu)
+{
+ if (cpu >= 0) {
+ slots->pinned = per_cpu(nr_cpu_bp_pinned, cpu);
+ slots->pinned += max_task_bp_pinned(cpu);
+ slots->flexible = per_cpu(nr_bp_flexible, cpu);
+
+ return;
+ }
+
+ for_each_online_cpu(cpu) {
+ unsigned int nr;
+
+ nr = per_cpu(nr_cpu_bp_pinned, cpu);
+ nr += max_task_bp_pinned(cpu);
+
+ if (nr > slots->pinned)
+ slots->pinned = nr;
+
+ nr = per_cpu(nr_bp_flexible, cpu);
+
+ if (nr > slots->flexible)
+ slots->flexible = nr;
+ }
+}
+
+/*
+ * Add a pinned breakpoint for the given task in our constraint table
+ */
+static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable)
+{
+ int count = 0;
+ struct perf_event *bp;
+ struct perf_event_context *ctx = tsk->perf_event_ctxp;
+ unsigned int *tsk_pinned;
+ struct list_head *list;
+ unsigned long flags;
+
+ if (WARN_ONCE(!ctx, "No perf context for this task"))
+ return;
+
+ list = &ctx->event_list;
+
+ spin_lock_irqsave(&ctx->lock, flags);
+
+ /*
+ * The current breakpoint counter is not included in the list
+ * at the open() callback time
+ */
+ list_for_each_entry(bp, list, event_entry) {
+ if (bp->attr.type == PERF_TYPE_BREAKPOINT)
+ count++;
+ }
+
+ spin_unlock_irqrestore(&ctx->lock, flags);
+
+ if (WARN_ONCE(count < 0, "No breakpoint counter found in the counter list"))
+ return;
+
+ tsk_pinned = per_cpu(task_bp_pinned, cpu);
+ if (enable) {
+ tsk_pinned[count]++;
+ if (count > 0)
+ tsk_pinned[count-1]--;
+ } else {
+ tsk_pinned[count]--;
+ if (count > 0)
+ tsk_pinned[count-1]++;
+ }
+}
+
+/*
+ * Add/remove the given breakpoint in our constraint table
+ */
+static void toggle_bp_slot(struct perf_event *bp, bool enable)
+{
+ int cpu = bp->cpu;
+ struct task_struct *tsk = bp->ctx->task;
+
+ /* Pinned counter task profiling */
+ if (tsk) {
+ if (cpu >= 0) {
+ toggle_bp_task_slot(tsk, cpu, enable);
+ return;
+ }
+
+ for_each_online_cpu(cpu)
+ toggle_bp_task_slot(tsk, cpu, enable);
+ return;
+ }
+
+ /* Pinned counter cpu profiling */
+ if (enable)
+ per_cpu(nr_cpu_bp_pinned, bp->cpu)++;
+ else
+ per_cpu(nr_cpu_bp_pinned, bp->cpu)--;
+}
+
+/*
+ * Contraints to check before allowing this new breakpoint counter:
+ *
+ * == Non-pinned counter == (Considered as pinned for now)
+ *
+ * - If attached to a single cpu, check:
+ *
+ * (per_cpu(nr_bp_flexible, cpu) || (per_cpu(nr_cpu_bp_pinned, cpu)
+ * + max(per_cpu(task_bp_pinned, cpu)))) < HBP_NUM
+ *
+ * -> If there are already non-pinned counters in this cpu, it means
+ * there is already a free slot for them.
+ * Otherwise, we check that the maximum number of per task
+ * breakpoints (for this cpu) plus the number of per cpu breakpoint
+ * (for this cpu) doesn't cover every registers.
+ *
+ * - If attached to every cpus, check:
+ *
+ * (per_cpu(nr_bp_flexible, *) || (max(per_cpu(nr_cpu_bp_pinned, *))
+ * + max(per_cpu(task_bp_pinned, *)))) < HBP_NUM
+ *
+ * -> This is roughly the same, except we check the number of per cpu
+ * bp for every cpu and we keep the max one. Same for the per tasks
+ * breakpoints.
+ *
+ *
+ * == Pinned counter ==
+ *
+ * - If attached to a single cpu, check:
+ *
+ * ((per_cpu(nr_bp_flexible, cpu) > 1) + per_cpu(nr_cpu_bp_pinned, cpu)
+ * + max(per_cpu(task_bp_pinned, cpu))) < HBP_NUM
+ *
+ * -> Same checks as before. But now the nr_bp_flexible, if any, must keep
+ * one register at least (or they will never be fed).
+ *
+ * - If attached to every cpus, check:
+ *
+ * ((per_cpu(nr_bp_flexible, *) > 1) + max(per_cpu(nr_cpu_bp_pinned, *))
+ * + max(per_cpu(task_bp_pinned, *))) < HBP_NUM
+ */
+int reserve_bp_slot(struct perf_event *bp)
+{
+ struct bp_busy_slots slots = {0};
+ int ret = 0;
+
+ mutex_lock(&nr_bp_mutex);
+
+ fetch_bp_busy_slots(&slots, bp->cpu);
+
+ /* Flexible counters need to keep at least one slot */
+ if (slots.pinned + (!!slots.flexible) == HBP_NUM) {
+ ret = -ENOSPC;
+ goto end;
+ }
+
+ toggle_bp_slot(bp, true);
+
+end:
+ mutex_unlock(&nr_bp_mutex);
+
+ return ret;
+}
+
+void release_bp_slot(struct perf_event *bp)
+{
+ mutex_lock(&nr_bp_mutex);
+
+ toggle_bp_slot(bp, false);
+
+ mutex_unlock(&nr_bp_mutex);
+}
+
+
+int __register_perf_hw_breakpoint(struct perf_event *bp)
+{
+ int ret;
+
+ ret = reserve_bp_slot(bp);
+ if (ret)
+ return ret;
+
+ /*
+ * Ptrace breakpoints can be temporary perf events only
+ * meant to reserve a slot. In this case, it is created disabled and
+ * we don't want to check the params right now (as we put a null addr)
+ * But perf tools create events as disabled and we want to check
+ * the params for them.
+ * This is a quick hack that will be removed soon, once we remove
+ * the tmp breakpoints from ptrace
+ */
+ if (!bp->attr.disabled || bp->callback == perf_bp_event)
+ ret = arch_validate_hwbkpt_settings(bp, bp->ctx->task);
+
+ return ret;
+}
+
+int register_perf_hw_breakpoint(struct perf_event *bp)
+{
+ bp->callback = perf_bp_event;
+
+ return __register_perf_hw_breakpoint(bp);
+}
+
+/**
+ * register_user_hw_breakpoint - register a hardware breakpoint for user space
+ * @attr: breakpoint attributes
+ * @triggered: callback to trigger when we hit the breakpoint
+ * @tsk: pointer to 'task_struct' of the process to which the address belongs
+ */
+struct perf_event *
+register_user_hw_breakpoint(struct perf_event_attr *attr,
+ perf_callback_t triggered,
+ struct task_struct *tsk)
+{
+ return perf_event_create_kernel_counter(attr, -1, tsk->pid, triggered);
+}
+EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
+
+/**
+ * modify_user_hw_breakpoint - modify a user-space hardware breakpoint
+ * @bp: the breakpoint structure to modify
+ * @attr: new breakpoint attributes
+ * @triggered: callback to trigger when we hit the breakpoint
+ * @tsk: pointer to 'task_struct' of the process to which the address belongs
+ */
+struct perf_event *
+modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr,
+ perf_callback_t triggered,
+ struct task_struct *tsk)
+{
+ /*
+ * FIXME: do it without unregistering
+ * - We don't want to lose our slot
+ * - If the new bp is incorrect, don't lose the older one
+ */
+ unregister_hw_breakpoint(bp);
+
+ return perf_event_create_kernel_counter(attr, -1, tsk->pid, triggered);
+}
+EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);
+
+/**
+ * unregister_hw_breakpoint - unregister a user-space hardware breakpoint
+ * @bp: the breakpoint structure to unregister
+ */
+void unregister_hw_breakpoint(struct perf_event *bp)
+{
+ if (!bp)
+ return;
+ perf_event_release_kernel(bp);
+}
+EXPORT_SYMBOL_GPL(unregister_hw_breakpoint);
+
+/**
+ * register_wide_hw_breakpoint - register a wide breakpoint in the kernel
+ * @attr: breakpoint attributes
+ * @triggered: callback to trigger when we hit the breakpoint
+ *
+ * @return a set of per_cpu pointers to perf events
+ */
+struct perf_event **
+register_wide_hw_breakpoint(struct perf_event_attr *attr,
+ perf_callback_t triggered)
+{
+ struct perf_event **cpu_events, **pevent, *bp;
+ long err;
+ int cpu;
+
+ cpu_events = alloc_percpu(typeof(*cpu_events));
+ if (!cpu_events)
+ return ERR_PTR(-ENOMEM);
+
+ for_each_possible_cpu(cpu) {
+ pevent = per_cpu_ptr(cpu_events, cpu);
+ bp = perf_event_create_kernel_counter(attr, cpu, -1, triggered);
+
+ *pevent = bp;
+
+ if (IS_ERR(bp)) {
+ err = PTR_ERR(bp);
+ goto fail;
+ }
+ }
+
+ return cpu_events;
+
+fail:
+ for_each_possible_cpu(cpu) {
+ pevent = per_cpu_ptr(cpu_events, cpu);
+ if (IS_ERR(*pevent))
+ break;
+ unregister_hw_breakpoint(*pevent);
+ }
+ free_percpu(cpu_events);
+ /* return the error if any */
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint);
+
+/**
+ * unregister_wide_hw_breakpoint - unregister a wide breakpoint in the kernel
+ * @cpu_events: the per cpu set of events to unregister
+ */
+void unregister_wide_hw_breakpoint(struct perf_event **cpu_events)
+{
+ int cpu;
+ struct perf_event **pevent;
+
+ for_each_possible_cpu(cpu) {
+ pevent = per_cpu_ptr(cpu_events, cpu);
+ unregister_hw_breakpoint(*pevent);
+ }
+ free_percpu(cpu_events);
+}
+EXPORT_SYMBOL_GPL(unregister_wide_hw_breakpoint);
+
+static struct notifier_block hw_breakpoint_exceptions_nb = {
+ .notifier_call = hw_breakpoint_exceptions_notify,
+ /* we need to be notified first */
+ .priority = 0x7fffffff
+};
+
+static int __init init_hw_breakpoint(void)
+{
+ return register_die_notifier(&hw_breakpoint_exceptions_nb);
+}
+core_initcall(init_hw_breakpoint);
+
+
+struct pmu perf_ops_bp = {
+ .enable = arch_install_hw_breakpoint,
+ .disable = arch_uninstall_hw_breakpoint,
+ .read = hw_breakpoint_pmu_read,
+ .unthrottle = hw_breakpoint_pmu_unthrottle
+};
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index c1660194d115..ba566c261adc 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -166,11 +166,11 @@ int set_irq_data(unsigned int irq, void *data)
EXPORT_SYMBOL(set_irq_data);
/**
- * set_irq_data - set irq type data for an irq
+ * set_irq_msi - set MSI descriptor data for an irq
* @irq: Interrupt number
* @entry: Pointer to MSI descriptor data
*
- * Set the hardware irq controller data for an irq
+ * Set the MSI descriptor entry for an irq
*/
int set_irq_msi(unsigned int irq, struct msi_desc *entry)
{
@@ -590,7 +590,7 @@ out_unlock:
}
/**
- * handle_percpu_IRQ - Per CPU local irq handler
+ * handle_percpu_irq - Per CPU local irq handler
* @irq: the interrupt number
* @desc: the interrupt description structure for this irq
*
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 692363dd591f..0832145fea97 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -136,7 +136,7 @@ out:
static int default_affinity_open(struct inode *inode, struct file *file)
{
- return single_open(file, default_affinity_show, NULL);
+ return single_open(file, default_affinity_show, PDE(inode)->data);
}
static const struct file_operations default_affinity_proc_fops = {
@@ -148,18 +148,28 @@ static const struct file_operations default_affinity_proc_fops = {
};
#endif
-static int irq_spurious_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int irq_spurious_proc_show(struct seq_file *m, void *v)
{
- struct irq_desc *desc = irq_to_desc((long) data);
- return sprintf(page, "count %u\n"
- "unhandled %u\n"
- "last_unhandled %u ms\n",
- desc->irq_count,
- desc->irqs_unhandled,
- jiffies_to_msecs(desc->last_unhandled));
+ struct irq_desc *desc = irq_to_desc((long) m->private);
+
+ seq_printf(m, "count %u\n" "unhandled %u\n" "last_unhandled %u ms\n",
+ desc->irq_count, desc->irqs_unhandled,
+ jiffies_to_msecs(desc->last_unhandled));
+ return 0;
+}
+
+static int irq_spurious_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, irq_spurious_proc_show, NULL);
}
+static const struct file_operations irq_spurious_proc_fops = {
+ .open = irq_spurious_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
#define MAX_NAMELEN 128
static int name_unique(unsigned int irq, struct irqaction *new_action)
@@ -204,7 +214,6 @@ void register_handler_proc(unsigned int irq, struct irqaction *action)
void register_irq_proc(unsigned int irq, struct irq_desc *desc)
{
char name [MAX_NAMELEN];
- struct proc_dir_entry *entry;
if (!root_irq_dir || (desc->chip == &no_irq_chip) || desc->dir)
return;
@@ -214,6 +223,8 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
/* create /proc/irq/1234 */
desc->dir = proc_mkdir(name, root_irq_dir);
+ if (!desc->dir)
+ return;
#ifdef CONFIG_SMP
/* create /proc/irq/<irq>/smp_affinity */
@@ -221,11 +232,8 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
&irq_affinity_proc_fops, (void *)(long)irq);
#endif
- entry = create_proc_entry("spurious", 0444, desc->dir);
- if (entry) {
- entry->data = (void *)(long)irq;
- entry->read_proc = irq_spurious_read;
- }
+ proc_create_data("spurious", 0444, desc->dir,
+ &irq_spurious_proc_fops, (void *)(long)irq);
}
#undef MAX_NAMELEN
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 114e704760fe..22b0a6eedf24 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -104,7 +104,7 @@ static int misrouted_irq(int irq)
return ok;
}
-static void poll_all_shared_irqs(void)
+static void poll_spurious_irqs(unsigned long dummy)
{
struct irq_desc *desc;
int i;
@@ -121,25 +121,15 @@ static void poll_all_shared_irqs(void)
if (!(status & IRQ_SPURIOUS_DISABLED))
continue;
+ local_irq_disable();
try_one_irq(i, desc);
+ local_irq_enable();
}
-}
-
-static void poll_spurious_irqs(unsigned long dummy)
-{
- poll_all_shared_irqs();
mod_timer(&poll_spurious_irq_timer,
jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
}
-#ifdef CONFIG_DEBUG_SHIRQ
-void debug_poll_all_shared_irqs(void)
-{
- poll_all_shared_irqs();
-}
-#endif
-
/*
* If 99,900 of the previous 100,000 interrupts have not been handled
* then assume that the IRQ is stuck in some manner. Drop a diagnostic
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 8b6b8b697c68..8e5288a8a355 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -181,6 +181,7 @@ unsigned long kallsyms_lookup_name(const char *name)
}
return module_kallsyms_lookup_name(name);
}
+EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
unsigned long),
diff --git a/kernel/kgdb.c b/kernel/kgdb.c
index 9147a3190c9d..7d7014634022 100644
--- a/kernel/kgdb.c
+++ b/kernel/kgdb.c
@@ -870,7 +870,7 @@ static void gdb_cmd_getregs(struct kgdb_state *ks)
/*
* All threads that don't have debuggerinfo should be
- * in __schedule() sleeping, since all other CPUs
+ * in schedule() sleeping, since all other CPUs
* are in kgdb_wait, and thus have debuggerinfo.
*/
if (local_debuggerinfo) {
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 9fcb53a11f87..25b103190364 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -80,16 +80,16 @@ int __request_module(bool wait, const char *fmt, ...)
#define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
static int kmod_loop_msg;
- ret = security_kernel_module_request();
- if (ret)
- return ret;
-
va_start(args, fmt);
ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
va_end(args);
if (ret >= MODULE_NAME_LEN)
return -ENAMETOOLONG;
+ ret = security_kernel_module_request(module_name);
+ if (ret)
+ return ret;
+
/* If modprobe needs a service that is in a module, we get a recursive
* loop. Limit the number of running kmod threads to max_threads/2 or
* MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 5240d75f4c60..e5342a344c43 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -90,6 +90,9 @@ static spinlock_t *kretprobe_table_lock_ptr(unsigned long hash)
*/
static struct kprobe_blackpoint kprobe_blacklist[] = {
{"preempt_schedule",},
+ {"native_get_debugreg",},
+ {"irq_entries_start",},
+ {"common_interrupt",},
{NULL} /* Terminator */
};
@@ -673,6 +676,40 @@ static kprobe_opcode_t __kprobes *kprobe_addr(struct kprobe *p)
return (kprobe_opcode_t *)(((char *)addr) + p->offset);
}
+/* Check passed kprobe is valid and return kprobe in kprobe_table. */
+static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p)
+{
+ struct kprobe *old_p, *list_p;
+
+ old_p = get_kprobe(p->addr);
+ if (unlikely(!old_p))
+ return NULL;
+
+ if (p != old_p) {
+ list_for_each_entry_rcu(list_p, &old_p->list, list)
+ if (list_p == p)
+ /* kprobe p is a valid probe */
+ goto valid;
+ return NULL;
+ }
+valid:
+ return old_p;
+}
+
+/* Return error if the kprobe is being re-registered */
+static inline int check_kprobe_rereg(struct kprobe *p)
+{
+ int ret = 0;
+ struct kprobe *old_p;
+
+ mutex_lock(&kprobe_mutex);
+ old_p = __get_valid_kprobe(p);
+ if (old_p)
+ ret = -EINVAL;
+ mutex_unlock(&kprobe_mutex);
+ return ret;
+}
+
int __kprobes register_kprobe(struct kprobe *p)
{
int ret = 0;
@@ -685,6 +722,10 @@ int __kprobes register_kprobe(struct kprobe *p)
return -EINVAL;
p->addr = addr;
+ ret = check_kprobe_rereg(p);
+ if (ret)
+ return ret;
+
preempt_disable();
if (!kernel_text_address((unsigned long) p->addr) ||
in_kprobes_functions((unsigned long) p->addr)) {
@@ -754,26 +795,6 @@ out:
}
EXPORT_SYMBOL_GPL(register_kprobe);
-/* Check passed kprobe is valid and return kprobe in kprobe_table. */
-static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p)
-{
- struct kprobe *old_p, *list_p;
-
- old_p = get_kprobe(p->addr);
- if (unlikely(!old_p))
- return NULL;
-
- if (p != old_p) {
- list_for_each_entry_rcu(list_p, &old_p->list, list)
- if (list_p == p)
- /* kprobe p is a valid probe */
- goto valid;
- return NULL;
- }
-valid:
- return old_p;
-}
-
/*
* Unregister a kprobe without a scheduler synchronization.
*/
@@ -1014,9 +1035,9 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
/* Pre-allocate memory for max kretprobe instances */
if (rp->maxactive <= 0) {
#ifdef CONFIG_PREEMPT
- rp->maxactive = max(10, 2 * NR_CPUS);
+ rp->maxactive = max(10, 2 * num_possible_cpus());
#else
- rp->maxactive = NR_CPUS;
+ rp->maxactive = num_possible_cpus();
#endif
}
spin_lock_init(&rp->lock);
@@ -1141,6 +1162,13 @@ static void __kprobes kill_kprobe(struct kprobe *p)
arch_remove_kprobe(p);
}
+void __kprobes dump_kprobe(struct kprobe *kp)
+{
+ printk(KERN_WARNING "Dumping kprobe:\n");
+ printk(KERN_WARNING "Name: %s\nAddress: %p\nOffset: %x\n",
+ kp->symbol_name, kp->addr, kp->offset);
+}
+
/* Module notifier call back, checking kprobes on the module */
static int __kprobes kprobes_module_callback(struct notifier_block *nb,
unsigned long val, void *data)
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 5fe709982caa..ab7ae57773e1 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -150,29 +150,6 @@ struct task_struct *kthread_create(int (*threadfn)(void *data),
EXPORT_SYMBOL(kthread_create);
/**
- * kthread_bind - bind a just-created kthread to a cpu.
- * @k: thread created by kthread_create().
- * @cpu: cpu (might not be online, must be possible) for @k to run on.
- *
- * Description: This function is equivalent to set_cpus_allowed(),
- * except that @cpu doesn't need to be online, and the thread must be
- * stopped (i.e., just returned from kthread_create()).
- */
-void kthread_bind(struct task_struct *k, unsigned int cpu)
-{
- /* Must have done schedule() in kthread() before we set_task_cpu */
- if (!wait_task_inactive(k, TASK_UNINTERRUPTIBLE)) {
- WARN_ON(1);
- return;
- }
- set_task_cpu(k, cpu);
- k->cpus_allowed = cpumask_of_cpu(cpu);
- k->rt.nr_cpus_allowed = 1;
- k->flags |= PF_THREAD_BOUND;
-}
-EXPORT_SYMBOL(kthread_bind);
-
-/**
* kthread_stop - stop a thread created by kthread_create().
* @k: thread created by kthread_create().
*
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 3815ac1d58b2..f5dcd36d3151 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -49,7 +49,7 @@
#include "lockdep_internals.h"
#define CREATE_TRACE_POINTS
-#include <trace/events/lockdep.h>
+#include <trace/events/lock.h>
#ifdef CONFIG_PROVE_LOCKING
int prove_locking = 1;
@@ -142,6 +142,11 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
#ifdef CONFIG_LOCK_STAT
static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats);
+static inline u64 lockstat_clock(void)
+{
+ return cpu_clock(smp_processor_id());
+}
+
static int lock_point(unsigned long points[], unsigned long ip)
{
int i;
@@ -158,7 +163,7 @@ static int lock_point(unsigned long points[], unsigned long ip)
return i;
}
-static void lock_time_inc(struct lock_time *lt, s64 time)
+static void lock_time_inc(struct lock_time *lt, u64 time)
{
if (time > lt->max)
lt->max = time;
@@ -234,12 +239,12 @@ static void put_lock_stats(struct lock_class_stats *stats)
static void lock_release_holdtime(struct held_lock *hlock)
{
struct lock_class_stats *stats;
- s64 holdtime;
+ u64 holdtime;
if (!lock_stat)
return;
- holdtime = sched_clock() - hlock->holdtime_stamp;
+ holdtime = lockstat_clock() - hlock->holdtime_stamp;
stats = get_lock_stats(hlock_class(hlock));
if (hlock->read)
@@ -2792,7 +2797,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
hlock->references = references;
#ifdef CONFIG_LOCK_STAT
hlock->waittime_stamp = 0;
- hlock->holdtime_stamp = sched_clock();
+ hlock->holdtime_stamp = lockstat_clock();
#endif
if (check == 2 && !mark_irqflags(curr, hlock))
@@ -3322,7 +3327,7 @@ found_it:
if (hlock->instance != lock)
return;
- hlock->waittime_stamp = sched_clock();
+ hlock->waittime_stamp = lockstat_clock();
contention_point = lock_point(hlock_class(hlock)->contention_point, ip);
contending_point = lock_point(hlock_class(hlock)->contending_point,
@@ -3345,8 +3350,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip)
struct held_lock *hlock, *prev_hlock;
struct lock_class_stats *stats;
unsigned int depth;
- u64 now;
- s64 waittime = 0;
+ u64 now, waittime = 0;
int i, cpu;
depth = curr->lockdep_depth;
@@ -3374,7 +3378,7 @@ found_it:
cpu = smp_processor_id();
if (hlock->waittime_stamp) {
- now = sched_clock();
+ now = lockstat_clock();
waittime = now - hlock->waittime_stamp;
hlock->holdtime_stamp = now;
}
diff --git a/kernel/module.c b/kernel/module.c
index 8b7d8805819d..5842a71cf052 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1187,7 +1187,8 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
/* Count loaded sections and allocate structures */
for (i = 0; i < nsect; i++)
- if (sechdrs[i].sh_flags & SHF_ALLOC)
+ if (sechdrs[i].sh_flags & SHF_ALLOC
+ && sechdrs[i].sh_size)
nloaded++;
size[0] = ALIGN(sizeof(*sect_attrs)
+ nloaded * sizeof(sect_attrs->attrs[0]),
@@ -1207,6 +1208,8 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
for (i = 0; i < nsect; i++) {
if (! (sechdrs[i].sh_flags & SHF_ALLOC))
continue;
+ if (!sechdrs[i].sh_size)
+ continue;
sattr->address = sechdrs[i].sh_addr;
sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
GFP_KERNEL);
diff --git a/kernel/mutex.c b/kernel/mutex.c
index 947b3ad551f8..632f04c57d82 100644
--- a/kernel/mutex.c
+++ b/kernel/mutex.c
@@ -148,8 +148,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
preempt_disable();
mutex_acquire(&lock->dep_map, subclass, 0, ip);
-#if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES) && \
- !defined(CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES)
+
+#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
/*
* Optimistic spinning.
*
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 61d5aa5eced3..acd24e7643eb 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -558,7 +558,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier);
static ATOMIC_NOTIFIER_HEAD(die_chain);
-int notrace notify_die(enum die_val val, const char *str,
+int notrace __kprobes notify_die(enum die_val val, const char *str,
struct pt_regs *regs, long err, int trap, int sig)
{
struct die_args args = {
diff --git a/kernel/params.c b/kernel/params.c
index 9da58eabdcb2..d656c276508d 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -218,15 +218,11 @@ int param_set_charp(const char *val, struct kernel_param *kp)
return -ENOSPC;
}
- if (kp->flags & KPARAM_KMALLOCED)
- kfree(*(char **)kp->arg);
-
/* This is a hack. We can't need to strdup in early boot, and we
* don't need to; this mangled commandline is preserved. */
if (slab_is_available()) {
- kp->flags |= KPARAM_KMALLOCED;
*(char **)kp->arg = kstrdup(val, GFP_KERNEL);
- if (!kp->arg)
+ if (!*(char **)kp->arg)
return -ENOMEM;
} else
*(const char **)kp->arg = val;
@@ -304,6 +300,7 @@ static int param_array(const char *name,
unsigned int min, unsigned int max,
void *elem, int elemsize,
int (*set)(const char *, struct kernel_param *kp),
+ u16 flags,
unsigned int *num)
{
int ret;
@@ -313,6 +310,7 @@ static int param_array(const char *name,
/* Get the name right for errors. */
kp.name = name;
kp.arg = elem;
+ kp.flags = flags;
/* No equals sign? */
if (!val) {
@@ -358,7 +356,8 @@ int param_array_set(const char *val, struct kernel_param *kp)
unsigned int temp_num;
return param_array(kp->name, val, 1, arr->max, arr->elem,
- arr->elemsize, arr->set, arr->num ?: &temp_num);
+ arr->elemsize, arr->set, kp->flags,
+ arr->num ?: &temp_num);
}
int param_array_get(char *buffer, struct kernel_param *kp)
@@ -605,11 +604,7 @@ void module_param_sysfs_remove(struct module *mod)
void destroy_params(const struct kernel_param *params, unsigned num)
{
- unsigned int i;
-
- for (i = 0; i < num; i++)
- if (params[i].flags & KPARAM_KMALLOCED)
- kfree(*(char **)params[i].arg);
+ /* FIXME: This should free kmalloced charp parameters. It doesn't. */
}
static void __init kernel_add_sysfs_param(const char *name,
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 9d0b5c665883..6b7ddba1dd64 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -28,6 +28,8 @@
#include <linux/anon_inodes.h>
#include <linux/kernel_stat.h>
#include <linux/perf_event.h>
+#include <linux/ftrace_event.h>
+#include <linux/hw_breakpoint.h>
#include <asm/irq_regs.h>
@@ -244,6 +246,49 @@ static void perf_unpin_context(struct perf_event_context *ctx)
put_ctx(ctx);
}
+static inline u64 perf_clock(void)
+{
+ return cpu_clock(smp_processor_id());
+}
+
+/*
+ * Update the record of the current time in a context.
+ */
+static void update_context_time(struct perf_event_context *ctx)
+{
+ u64 now = perf_clock();
+
+ ctx->time += now - ctx->timestamp;
+ ctx->timestamp = now;
+}
+
+/*
+ * Update the total_time_enabled and total_time_running fields for a event.
+ */
+static void update_event_times(struct perf_event *event)
+{
+ struct perf_event_context *ctx = event->ctx;
+ u64 run_end;
+
+ if (event->state < PERF_EVENT_STATE_INACTIVE ||
+ event->group_leader->state < PERF_EVENT_STATE_INACTIVE)
+ return;
+
+ if (ctx->is_active)
+ run_end = ctx->time;
+ else
+ run_end = event->tstamp_stopped;
+
+ event->total_time_enabled = run_end - event->tstamp_enabled;
+
+ if (event->state == PERF_EVENT_STATE_INACTIVE)
+ run_end = event->tstamp_stopped;
+ else
+ run_end = ctx->time;
+
+ event->total_time_running = run_end - event->tstamp_running;
+}
+
/*
* Add a event from the lists for its context.
* Must be called with ctx->mutex and ctx->lock held.
@@ -292,6 +337,18 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
if (event->group_leader != event)
event->group_leader->nr_siblings--;
+ update_event_times(event);
+
+ /*
+ * If event was in error state, then keep it
+ * that way, otherwise bogus counts will be
+ * returned on read(). The only way to get out
+ * of error state is by explicit re-enabling
+ * of the event
+ */
+ if (event->state > PERF_EVENT_STATE_OFF)
+ event->state = PERF_EVENT_STATE_OFF;
+
/*
* If this was a group event with sibling events then
* upgrade the siblings to singleton events by adding them
@@ -445,50 +502,11 @@ retry:
* can remove the event safely, if the call above did not
* succeed.
*/
- if (!list_empty(&event->group_entry)) {
+ if (!list_empty(&event->group_entry))
list_del_event(event, ctx);
- }
spin_unlock_irq(&ctx->lock);
}
-static inline u64 perf_clock(void)
-{
- return cpu_clock(smp_processor_id());
-}
-
-/*
- * Update the record of the current time in a context.
- */
-static void update_context_time(struct perf_event_context *ctx)
-{
- u64 now = perf_clock();
-
- ctx->time += now - ctx->timestamp;
- ctx->timestamp = now;
-}
-
-/*
- * Update the total_time_enabled and total_time_running fields for a event.
- */
-static void update_event_times(struct perf_event *event)
-{
- struct perf_event_context *ctx = event->ctx;
- u64 run_end;
-
- if (event->state < PERF_EVENT_STATE_INACTIVE ||
- event->group_leader->state < PERF_EVENT_STATE_INACTIVE)
- return;
-
- event->total_time_enabled = ctx->time - event->tstamp_enabled;
-
- if (event->state == PERF_EVENT_STATE_INACTIVE)
- run_end = event->tstamp_stopped;
- else
- run_end = ctx->time;
-
- event->total_time_running = run_end - event->tstamp_running;
-}
-
/*
* Update total_time_enabled and total_time_running for all events in a group.
*/
@@ -1031,10 +1049,10 @@ void __perf_event_sched_out(struct perf_event_context *ctx,
update_context_time(ctx);
perf_disable();
- if (ctx->nr_active)
+ if (ctx->nr_active) {
list_for_each_entry(event, &ctx->group_list, group_entry)
group_sched_out(event, cpuctx, ctx);
-
+ }
perf_enable();
out:
spin_unlock(&ctx->lock);
@@ -1059,8 +1077,6 @@ static int context_equiv(struct perf_event_context *ctx1,
&& !ctx1->pin_count && !ctx2->pin_count;
}
-static void __perf_event_read(void *event);
-
static void __perf_event_sync_stat(struct perf_event *event,
struct perf_event *next_event)
{
@@ -1078,8 +1094,8 @@ static void __perf_event_sync_stat(struct perf_event *event,
*/
switch (event->state) {
case PERF_EVENT_STATE_ACTIVE:
- __perf_event_read(event);
- break;
+ event->pmu->read(event);
+ /* fall-through */
case PERF_EVENT_STATE_INACTIVE:
update_event_times(event);
@@ -1118,6 +1134,8 @@ static void perf_event_sync_stat(struct perf_event_context *ctx,
if (!ctx->nr_stat)
return;
+ update_context_time(ctx);
+
event = list_first_entry(&ctx->event_list,
struct perf_event, event_entry);
@@ -1161,8 +1179,6 @@ void perf_event_task_sched_out(struct task_struct *task,
if (likely(!ctx || !cpuctx->task_ctx))
return;
- update_context_time(ctx);
-
rcu_read_lock();
parent = rcu_dereference(ctx->parent_ctx);
next_ctx = next->perf_event_ctxp;
@@ -1355,7 +1371,7 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
u64 interrupts, freq;
spin_lock(&ctx->lock);
- list_for_each_entry(event, &ctx->group_list, group_entry) {
+ list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
if (event->state != PERF_EVENT_STATE_ACTIVE)
continue;
@@ -1515,7 +1531,6 @@ static void __perf_event_read(void *info)
struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
struct perf_event *event = info;
struct perf_event_context *ctx = event->ctx;
- unsigned long flags;
/*
* If this is a task context, we need to check whether it is
@@ -1527,12 +1542,12 @@ static void __perf_event_read(void *info)
if (ctx->task && cpuctx->task_ctx != ctx)
return;
- local_irq_save(flags);
- if (ctx->is_active)
- update_context_time(ctx);
- event->pmu->read(event);
+ spin_lock(&ctx->lock);
+ update_context_time(ctx);
update_event_times(event);
- local_irq_restore(flags);
+ spin_unlock(&ctx->lock);
+
+ event->pmu->read(event);
}
static u64 perf_event_read(struct perf_event *event)
@@ -1545,7 +1560,13 @@ static u64 perf_event_read(struct perf_event *event)
smp_call_function_single(event->oncpu,
__perf_event_read, event, 1);
} else if (event->state == PERF_EVENT_STATE_INACTIVE) {
+ struct perf_event_context *ctx = event->ctx;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->lock, flags);
+ update_context_time(ctx);
update_event_times(event);
+ spin_unlock_irqrestore(&ctx->lock, flags);
}
return atomic64_read(&event->count);
@@ -1658,6 +1679,8 @@ static struct perf_event_context *find_get_context(pid_t pid, int cpu)
return ERR_PTR(err);
}
+static void perf_event_free_filter(struct perf_event *event);
+
static void free_event_rcu(struct rcu_head *head)
{
struct perf_event *event;
@@ -1665,6 +1688,7 @@ static void free_event_rcu(struct rcu_head *head)
event = container_of(head, struct perf_event, rcu_head);
if (event->ns)
put_pid_ns(event->ns);
+ perf_event_free_filter(event);
kfree(event);
}
@@ -1696,16 +1720,10 @@ static void free_event(struct perf_event *event)
call_rcu(&event->rcu_head, free_event_rcu);
}
-/*
- * Called when the last reference to the file is gone.
- */
-static int perf_release(struct inode *inode, struct file *file)
+int perf_event_release_kernel(struct perf_event *event)
{
- struct perf_event *event = file->private_data;
struct perf_event_context *ctx = event->ctx;
- file->private_data = NULL;
-
WARN_ON_ONCE(ctx->parent_ctx);
mutex_lock(&ctx->mutex);
perf_event_remove_from_context(event);
@@ -1720,6 +1738,19 @@ static int perf_release(struct inode *inode, struct file *file)
return 0;
}
+EXPORT_SYMBOL_GPL(perf_event_release_kernel);
+
+/*
+ * Called when the last reference to the file is gone.
+ */
+static int perf_release(struct inode *inode, struct file *file)
+{
+ struct perf_event *event = file->private_data;
+
+ file->private_data = NULL;
+
+ return perf_event_release_kernel(event);
+}
static int perf_event_read_size(struct perf_event *event)
{
@@ -1746,91 +1777,94 @@ static int perf_event_read_size(struct perf_event *event)
return size;
}
-static u64 perf_event_read_value(struct perf_event *event)
+u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
{
struct perf_event *child;
u64 total = 0;
+ *enabled = 0;
+ *running = 0;
+
+ mutex_lock(&event->child_mutex);
total += perf_event_read(event);
- list_for_each_entry(child, &event->child_list, child_list)
+ *enabled += event->total_time_enabled +
+ atomic64_read(&event->child_total_time_enabled);
+ *running += event->total_time_running +
+ atomic64_read(&event->child_total_time_running);
+
+ list_for_each_entry(child, &event->child_list, child_list) {
total += perf_event_read(child);
+ *enabled += child->total_time_enabled;
+ *running += child->total_time_running;
+ }
+ mutex_unlock(&event->child_mutex);
return total;
}
-
-static int perf_event_read_entry(struct perf_event *event,
- u64 read_format, char __user *buf)
-{
- int n = 0, count = 0;
- u64 values[2];
-
- values[n++] = perf_event_read_value(event);
- if (read_format & PERF_FORMAT_ID)
- values[n++] = primary_event_id(event);
-
- count = n * sizeof(u64);
-
- if (copy_to_user(buf, values, count))
- return -EFAULT;
-
- return count;
-}
+EXPORT_SYMBOL_GPL(perf_event_read_value);
static int perf_event_read_group(struct perf_event *event,
u64 read_format, char __user *buf)
{
struct perf_event *leader = event->group_leader, *sub;
- int n = 0, size = 0, err = -EFAULT;
- u64 values[3];
+ int n = 0, size = 0, ret = -EFAULT;
+ struct perf_event_context *ctx = leader->ctx;
+ u64 values[5];
+ u64 count, enabled, running;
+
+ mutex_lock(&ctx->mutex);
+ count = perf_event_read_value(leader, &enabled, &running);
values[n++] = 1 + leader->nr_siblings;
- if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
- values[n++] = leader->total_time_enabled +
- atomic64_read(&leader->child_total_time_enabled);
- }
- if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
- values[n++] = leader->total_time_running +
- atomic64_read(&leader->child_total_time_running);
- }
+ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+ values[n++] = enabled;
+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+ values[n++] = running;
+ values[n++] = count;
+ if (read_format & PERF_FORMAT_ID)
+ values[n++] = primary_event_id(leader);
size = n * sizeof(u64);
if (copy_to_user(buf, values, size))
- return -EFAULT;
-
- err = perf_event_read_entry(leader, read_format, buf + size);
- if (err < 0)
- return err;
+ goto unlock;
- size += err;
+ ret = size;
list_for_each_entry(sub, &leader->sibling_list, group_entry) {
- err = perf_event_read_entry(sub, read_format,
- buf + size);
- if (err < 0)
- return err;
+ n = 0;
+
+ values[n++] = perf_event_read_value(sub, &enabled, &running);
+ if (read_format & PERF_FORMAT_ID)
+ values[n++] = primary_event_id(sub);
+
+ size = n * sizeof(u64);
+
+ if (copy_to_user(buf + ret, values, size)) {
+ ret = -EFAULT;
+ goto unlock;
+ }
- size += err;
+ ret += size;
}
+unlock:
+ mutex_unlock(&ctx->mutex);
- return size;
+ return ret;
}
static int perf_event_read_one(struct perf_event *event,
u64 read_format, char __user *buf)
{
+ u64 enabled, running;
u64 values[4];
int n = 0;
- values[n++] = perf_event_read_value(event);
- if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
- values[n++] = event->total_time_enabled +
- atomic64_read(&event->child_total_time_enabled);
- }
- if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
- values[n++] = event->total_time_running +
- atomic64_read(&event->child_total_time_running);
- }
+ values[n++] = perf_event_read_value(event, &enabled, &running);
+ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+ values[n++] = enabled;
+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+ values[n++] = running;
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(event);
@@ -1861,12 +1895,10 @@ perf_read_hw(struct perf_event *event, char __user *buf, size_t count)
return -ENOSPC;
WARN_ON_ONCE(event->ctx->parent_ctx);
- mutex_lock(&event->child_mutex);
if (read_format & PERF_FORMAT_GROUP)
ret = perf_event_read_group(event, read_format, buf);
else
ret = perf_event_read_one(event, read_format, buf);
- mutex_unlock(&event->child_mutex);
return ret;
}
@@ -1974,7 +2006,8 @@ unlock:
return ret;
}
-int perf_event_set_output(struct perf_event *event, int output_fd);
+static int perf_event_set_output(struct perf_event *event, int output_fd);
+static int perf_event_set_filter(struct perf_event *event, void __user *arg);
static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
@@ -2002,6 +2035,9 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case PERF_EVENT_IOC_SET_OUTPUT:
return perf_event_set_output(event, arg);
+ case PERF_EVENT_IOC_SET_FILTER:
+ return perf_event_set_filter(event, (void __user *)arg);
+
default:
return -ENOTTY;
}
@@ -2174,6 +2210,7 @@ static void perf_mmap_data_free(struct perf_mmap_data *data)
perf_mmap_free_page((unsigned long)data->user_page);
for (i = 0; i < data->nr_pages; i++)
perf_mmap_free_page((unsigned long)data->data_pages[i]);
+ kfree(data);
}
#else
@@ -2214,6 +2251,7 @@ static void perf_mmap_data_free_work(struct work_struct *work)
perf_mmap_unmark_page(base + (i * PAGE_SIZE));
vfree(base);
+ kfree(data);
}
static void perf_mmap_data_free(struct perf_mmap_data *data)
@@ -2307,7 +2345,7 @@ perf_mmap_data_init(struct perf_event *event, struct perf_mmap_data *data)
}
if (!data->watermark)
- data->watermark = max_t(long, PAGE_SIZE, max_size / 2);
+ data->watermark = max_size / 2;
rcu_assign_pointer(event->data, data);
@@ -2319,7 +2357,6 @@ static void perf_mmap_data_free_rcu(struct rcu_head *rcu_head)
data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
perf_mmap_data_free(data);
- kfree(data);
}
static void perf_mmap_data_release(struct perf_event *event)
@@ -2666,20 +2703,21 @@ static void perf_output_wakeup(struct perf_output_handle *handle)
static void perf_output_lock(struct perf_output_handle *handle)
{
struct perf_mmap_data *data = handle->data;
- int cpu;
+ int cur, cpu = get_cpu();
handle->locked = 0;
- local_irq_save(handle->flags);
- cpu = smp_processor_id();
-
- if (in_nmi() && atomic_read(&data->lock) == cpu)
- return;
+ for (;;) {
+ cur = atomic_cmpxchg(&data->lock, -1, cpu);
+ if (cur == -1) {
+ handle->locked = 1;
+ break;
+ }
+ if (cur == cpu)
+ break;
- while (atomic_cmpxchg(&data->lock, -1, cpu) != -1)
cpu_relax();
-
- handle->locked = 1;
+ }
}
static void perf_output_unlock(struct perf_output_handle *handle)
@@ -2725,7 +2763,7 @@ again:
if (atomic_xchg(&data->wakeup, 0))
perf_output_wakeup(handle);
out:
- local_irq_restore(handle->flags);
+ put_cpu();
}
void perf_output_copy(struct perf_output_handle *handle,
@@ -3236,15 +3274,10 @@ static void perf_event_task_ctx(struct perf_event_context *ctx,
{
struct perf_event *event;
- if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
- return;
-
- rcu_read_lock();
list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
if (perf_event_task_match(event))
perf_event_task_output(event, task_event);
}
- rcu_read_unlock();
}
static void perf_event_task_event(struct perf_task_event *task_event)
@@ -3252,11 +3285,11 @@ static void perf_event_task_event(struct perf_task_event *task_event)
struct perf_cpu_context *cpuctx;
struct perf_event_context *ctx = task_event->task_ctx;
+ rcu_read_lock();
cpuctx = &get_cpu_var(perf_cpu_context);
perf_event_task_ctx(&cpuctx->ctx, task_event);
put_cpu_var(perf_cpu_context);
- rcu_read_lock();
if (!ctx)
ctx = rcu_dereference(task_event->task->perf_event_ctxp);
if (ctx)
@@ -3348,15 +3381,10 @@ static void perf_event_comm_ctx(struct perf_event_context *ctx,
{
struct perf_event *event;
- if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
- return;
-
- rcu_read_lock();
list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
if (perf_event_comm_match(event))
perf_event_comm_output(event, comm_event);
}
- rcu_read_unlock();
}
static void perf_event_comm_event(struct perf_comm_event *comm_event)
@@ -3367,7 +3395,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
char comm[TASK_COMM_LEN];
memset(comm, 0, sizeof(comm));
- strncpy(comm, comm_event->task->comm, sizeof(comm));
+ strlcpy(comm, comm_event->task->comm, sizeof(comm));
size = ALIGN(strlen(comm)+1, sizeof(u64));
comm_event->comm = comm;
@@ -3375,11 +3403,11 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
comm_event->event_id.header.size = sizeof(comm_event->event_id) + size;
+ rcu_read_lock();
cpuctx = &get_cpu_var(perf_cpu_context);
perf_event_comm_ctx(&cpuctx->ctx, comm_event);
put_cpu_var(perf_cpu_context);
- rcu_read_lock();
/*
* doesn't really matter which of the child contexts the
* events ends up in.
@@ -3472,15 +3500,10 @@ static void perf_event_mmap_ctx(struct perf_event_context *ctx,
{
struct perf_event *event;
- if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
- return;
-
- rcu_read_lock();
list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
if (perf_event_mmap_match(event, mmap_event))
perf_event_mmap_output(event, mmap_event);
}
- rcu_read_unlock();
}
static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
@@ -3536,11 +3559,11 @@ got_name:
mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size;
+ rcu_read_lock();
cpuctx = &get_cpu_var(perf_cpu_context);
perf_event_mmap_ctx(&cpuctx->ctx, mmap_event);
put_cpu_var(perf_cpu_context);
- rcu_read_lock();
/*
* doesn't really matter which of the child contexts the
* events ends up in.
@@ -3679,7 +3702,11 @@ static int __perf_event_overflow(struct perf_event *event, int nmi,
perf_event_disable(event);
}
- perf_event_output(event, nmi, data, regs);
+ if (event->overflow_handler)
+ event->overflow_handler(event, nmi, data, regs);
+ else
+ perf_event_output(event, nmi, data, regs);
+
return ret;
}
@@ -3724,16 +3751,16 @@ again:
return nr;
}
-static void perf_swevent_overflow(struct perf_event *event,
+static void perf_swevent_overflow(struct perf_event *event, u64 overflow,
int nmi, struct perf_sample_data *data,
struct pt_regs *regs)
{
struct hw_perf_event *hwc = &event->hw;
int throttle = 0;
- u64 overflow;
data->period = event->hw.last_period;
- overflow = perf_swevent_set_period(event);
+ if (!overflow)
+ overflow = perf_swevent_set_period(event);
if (hwc->interrupts == MAX_INTERRUPTS)
return;
@@ -3766,14 +3793,19 @@ static void perf_swevent_add(struct perf_event *event, u64 nr,
atomic64_add(nr, &event->count);
+ if (!regs)
+ return;
+
if (!hwc->sample_period)
return;
- if (!regs)
+ if (nr == 1 && hwc->sample_period == 1 && !event->attr.freq)
+ return perf_swevent_overflow(event, 1, nmi, data, regs);
+
+ if (atomic64_add_negative(nr, &hwc->period_left))
return;
- if (!atomic64_add_negative(nr, &hwc->period_left))
- perf_swevent_overflow(event, nmi, data, regs);
+ perf_swevent_overflow(event, 0, nmi, data, regs);
}
static int perf_swevent_is_counting(struct perf_event *event)
@@ -3806,25 +3838,44 @@ static int perf_swevent_is_counting(struct perf_event *event)
return 1;
}
+static int perf_tp_event_match(struct perf_event *event,
+ struct perf_sample_data *data);
+
+static int perf_exclude_event(struct perf_event *event,
+ struct pt_regs *regs)
+{
+ if (regs) {
+ if (event->attr.exclude_user && user_mode(regs))
+ return 1;
+
+ if (event->attr.exclude_kernel && !user_mode(regs))
+ return 1;
+ }
+
+ return 0;
+}
+
static int perf_swevent_match(struct perf_event *event,
enum perf_type_id type,
- u32 event_id, struct pt_regs *regs)
+ u32 event_id,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
{
if (!perf_swevent_is_counting(event))
return 0;
if (event->attr.type != type)
return 0;
+
if (event->attr.config != event_id)
return 0;
- if (regs) {
- if (event->attr.exclude_user && user_mode(regs))
- return 0;
+ if (perf_exclude_event(event, regs))
+ return 0;
- if (event->attr.exclude_kernel && !user_mode(regs))
- return 0;
- }
+ if (event->attr.type == PERF_TYPE_TRACEPOINT &&
+ !perf_tp_event_match(event, data))
+ return 0;
return 1;
}
@@ -3837,49 +3888,59 @@ static void perf_swevent_ctx_event(struct perf_event_context *ctx,
{
struct perf_event *event;
- if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
- return;
-
- rcu_read_lock();
list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
- if (perf_swevent_match(event, type, event_id, regs))
+ if (perf_swevent_match(event, type, event_id, data, regs))
perf_swevent_add(event, nr, nmi, data, regs);
}
- rcu_read_unlock();
}
-static int *perf_swevent_recursion_context(struct perf_cpu_context *cpuctx)
+int perf_swevent_get_recursion_context(void)
{
+ struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context);
+ int rctx;
+
if (in_nmi())
- return &cpuctx->recursion[3];
+ rctx = 3;
+ else if (in_irq())
+ rctx = 2;
+ else if (in_softirq())
+ rctx = 1;
+ else
+ rctx = 0;
- if (in_irq())
- return &cpuctx->recursion[2];
+ if (cpuctx->recursion[rctx]) {
+ put_cpu_var(perf_cpu_context);
+ return -1;
+ }
- if (in_softirq())
- return &cpuctx->recursion[1];
+ cpuctx->recursion[rctx]++;
+ barrier();
- return &cpuctx->recursion[0];
+ return rctx;
+}
+EXPORT_SYMBOL_GPL(perf_swevent_get_recursion_context);
+
+void perf_swevent_put_recursion_context(int rctx)
+{
+ struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+ barrier();
+ cpuctx->recursion[rctx]--;
+ put_cpu_var(perf_cpu_context);
}
+EXPORT_SYMBOL_GPL(perf_swevent_put_recursion_context);
static void do_perf_sw_event(enum perf_type_id type, u32 event_id,
u64 nr, int nmi,
struct perf_sample_data *data,
struct pt_regs *regs)
{
- struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context);
- int *recursion = perf_swevent_recursion_context(cpuctx);
+ struct perf_cpu_context *cpuctx;
struct perf_event_context *ctx;
- if (*recursion)
- goto out;
-
- (*recursion)++;
- barrier();
-
+ cpuctx = &__get_cpu_var(perf_cpu_context);
+ rcu_read_lock();
perf_swevent_ctx_event(&cpuctx->ctx, type, event_id,
nr, nmi, data, regs);
- rcu_read_lock();
/*
* doesn't really matter which of the child contexts the
* events ends up in.
@@ -3888,23 +3949,24 @@ static void do_perf_sw_event(enum perf_type_id type, u32 event_id,
if (ctx)
perf_swevent_ctx_event(ctx, type, event_id, nr, nmi, data, regs);
rcu_read_unlock();
-
- barrier();
- (*recursion)--;
-
-out:
- put_cpu_var(perf_cpu_context);
}
void __perf_sw_event(u32 event_id, u64 nr, int nmi,
struct pt_regs *regs, u64 addr)
{
- struct perf_sample_data data = {
- .addr = addr,
- };
+ struct perf_sample_data data;
+ int rctx;
- do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi,
- &data, regs);
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
+ return;
+
+ data.addr = addr;
+ data.raw = NULL;
+
+ do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi, &data, regs);
+
+ perf_swevent_put_recursion_context(rctx);
}
static void perf_swevent_read(struct perf_event *event)
@@ -3949,6 +4011,7 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
event->pmu->read(event);
data.addr = 0;
+ data.period = event->hw.last_period;
regs = get_irq_regs();
/*
* In case we exclude kernel IPs or are somehow not in interrupt
@@ -3959,8 +4022,9 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
regs = task_pt_regs(current);
if (regs) {
- if (perf_event_overflow(event, 0, &data, regs))
- ret = HRTIMER_NORESTART;
+ if (!(event->attr.exclude_idle && current->pid == 0))
+ if (perf_event_overflow(event, 0, &data, regs))
+ ret = HRTIMER_NORESTART;
}
period = max_t(u64, 10000, event->hw.sample_period);
@@ -3969,6 +4033,42 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
return ret;
}
+static void perf_swevent_start_hrtimer(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ hwc->hrtimer.function = perf_swevent_hrtimer;
+ if (hwc->sample_period) {
+ u64 period;
+
+ if (hwc->remaining) {
+ if (hwc->remaining < 0)
+ period = 10000;
+ else
+ period = hwc->remaining;
+ hwc->remaining = 0;
+ } else {
+ period = max_t(u64, 10000, hwc->sample_period);
+ }
+ __hrtimer_start_range_ns(&hwc->hrtimer,
+ ns_to_ktime(period), 0,
+ HRTIMER_MODE_REL, 0);
+ }
+}
+
+static void perf_swevent_cancel_hrtimer(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (hwc->sample_period) {
+ ktime_t remaining = hrtimer_get_remaining(&hwc->hrtimer);
+ hwc->remaining = ktime_to_ns(remaining);
+
+ hrtimer_cancel(&hwc->hrtimer);
+ }
+}
+
/*
* Software event: cpu wall time clock
*/
@@ -3991,22 +4091,14 @@ static int cpu_clock_perf_event_enable(struct perf_event *event)
int cpu = raw_smp_processor_id();
atomic64_set(&hwc->prev_count, cpu_clock(cpu));
- hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- hwc->hrtimer.function = perf_swevent_hrtimer;
- if (hwc->sample_period) {
- u64 period = max_t(u64, 10000, hwc->sample_period);
- __hrtimer_start_range_ns(&hwc->hrtimer,
- ns_to_ktime(period), 0,
- HRTIMER_MODE_REL, 0);
- }
+ perf_swevent_start_hrtimer(event);
return 0;
}
static void cpu_clock_perf_event_disable(struct perf_event *event)
{
- if (event->hw.sample_period)
- hrtimer_cancel(&event->hw.hrtimer);
+ perf_swevent_cancel_hrtimer(event);
cpu_clock_perf_event_update(event);
}
@@ -4043,22 +4135,15 @@ static int task_clock_perf_event_enable(struct perf_event *event)
now = event->ctx->time;
atomic64_set(&hwc->prev_count, now);
- hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- hwc->hrtimer.function = perf_swevent_hrtimer;
- if (hwc->sample_period) {
- u64 period = max_t(u64, 10000, hwc->sample_period);
- __hrtimer_start_range_ns(&hwc->hrtimer,
- ns_to_ktime(period), 0,
- HRTIMER_MODE_REL, 0);
- }
+
+ perf_swevent_start_hrtimer(event);
return 0;
}
static void task_clock_perf_event_disable(struct perf_event *event)
{
- if (event->hw.sample_period)
- hrtimer_cancel(&event->hw.hrtimer);
+ perf_swevent_cancel_hrtimer(event);
task_clock_perf_event_update(event, event->ctx->time);
}
@@ -4086,6 +4171,7 @@ static const struct pmu perf_ops_task_clock = {
};
#ifdef CONFIG_EVENT_PROFILE
+
void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
int entry_size)
{
@@ -4104,13 +4190,21 @@ void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
if (!regs)
regs = task_pt_regs(current);
+ /* Trace events already protected against recursion */
do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1,
&data, regs);
}
EXPORT_SYMBOL_GPL(perf_tp_event);
-extern int ftrace_profile_enable(int);
-extern void ftrace_profile_disable(int);
+static int perf_tp_event_match(struct perf_event *event,
+ struct perf_sample_data *data)
+{
+ void *record = data->raw->data;
+
+ if (likely(!event->filter) || filter_match_preds(event->filter, record))
+ return 1;
+ return 0;
+}
static void tp_perf_event_destroy(struct perf_event *event)
{
@@ -4135,11 +4229,99 @@ static const struct pmu *tp_perf_event_init(struct perf_event *event)
return &perf_ops_generic;
}
+
+static int perf_event_set_filter(struct perf_event *event, void __user *arg)
+{
+ char *filter_str;
+ int ret;
+
+ if (event->attr.type != PERF_TYPE_TRACEPOINT)
+ return -EINVAL;
+
+ filter_str = strndup_user(arg, PAGE_SIZE);
+ if (IS_ERR(filter_str))
+ return PTR_ERR(filter_str);
+
+ ret = ftrace_profile_set_filter(event, event->attr.config, filter_str);
+
+ kfree(filter_str);
+ return ret;
+}
+
+static void perf_event_free_filter(struct perf_event *event)
+{
+ ftrace_profile_free_filter(event);
+}
+
#else
+
+static int perf_tp_event_match(struct perf_event *event,
+ struct perf_sample_data *data)
+{
+ return 1;
+}
+
static const struct pmu *tp_perf_event_init(struct perf_event *event)
{
return NULL;
}
+
+static int perf_event_set_filter(struct perf_event *event, void __user *arg)
+{
+ return -ENOENT;
+}
+
+static void perf_event_free_filter(struct perf_event *event)
+{
+}
+
+#endif /* CONFIG_EVENT_PROFILE */
+
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+static void bp_perf_event_destroy(struct perf_event *event)
+{
+ release_bp_slot(event);
+}
+
+static const struct pmu *bp_perf_event_init(struct perf_event *bp)
+{
+ int err;
+ /*
+ * The breakpoint is already filled if we haven't created the counter
+ * through perf syscall
+ * FIXME: manage to get trigerred to NULL if it comes from syscalls
+ */
+ if (!bp->callback)
+ err = register_perf_hw_breakpoint(bp);
+ else
+ err = __register_perf_hw_breakpoint(bp);
+ if (err)
+ return ERR_PTR(err);
+
+ bp->destroy = bp_perf_event_destroy;
+
+ return &perf_ops_bp;
+}
+
+void perf_bp_event(struct perf_event *bp, void *data)
+{
+ struct perf_sample_data sample;
+ struct pt_regs *regs = data;
+
+ sample.addr = bp->attr.bp_addr;
+
+ if (!perf_exclude_event(bp, regs))
+ perf_swevent_add(bp, 1, 1, &sample, regs);
+}
+#else
+static const struct pmu *bp_perf_event_init(struct perf_event *bp)
+{
+ return NULL;
+}
+
+void perf_bp_event(struct perf_event *bp, void *regs)
+{
+}
#endif
atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX];
@@ -4186,6 +4368,8 @@ static const struct pmu *sw_perf_event_init(struct perf_event *event)
case PERF_COUNT_SW_PAGE_FAULTS_MAJ:
case PERF_COUNT_SW_CONTEXT_SWITCHES:
case PERF_COUNT_SW_CPU_MIGRATIONS:
+ case PERF_COUNT_SW_ALIGNMENT_FAULTS:
+ case PERF_COUNT_SW_EMULATION_FAULTS:
if (!event->parent) {
atomic_inc(&perf_swevent_enabled[event_id]);
event->destroy = sw_perf_event_destroy;
@@ -4206,6 +4390,7 @@ perf_event_alloc(struct perf_event_attr *attr,
struct perf_event_context *ctx,
struct perf_event *group_leader,
struct perf_event *parent_event,
+ perf_callback_t callback,
gfp_t gfpflags)
{
const struct pmu *pmu;
@@ -4248,6 +4433,11 @@ perf_event_alloc(struct perf_event_attr *attr,
event->state = PERF_EVENT_STATE_INACTIVE;
+ if (!callback && parent_event)
+ callback = parent_event->callback;
+
+ event->callback = callback;
+
if (attr->disabled)
event->state = PERF_EVENT_STATE_OFF;
@@ -4282,6 +4472,11 @@ perf_event_alloc(struct perf_event_attr *attr,
pmu = tp_perf_event_init(event);
break;
+ case PERF_TYPE_BREAKPOINT:
+ pmu = bp_perf_event_init(event);
+ break;
+
+
default:
break;
}
@@ -4394,7 +4589,7 @@ err_size:
goto out;
}
-int perf_event_set_output(struct perf_event *event, int output_fd)
+static int perf_event_set_output(struct perf_event *event, int output_fd)
{
struct perf_event *output_event = NULL;
struct file *output_file = NULL;
@@ -4524,7 +4719,7 @@ SYSCALL_DEFINE5(perf_event_open,
}
event = perf_event_alloc(&attr, cpu, ctx, group_leader,
- NULL, GFP_KERNEL);
+ NULL, NULL, GFP_KERNEL);
err = PTR_ERR(event);
if (IS_ERR(event))
goto err_put_context;
@@ -4572,6 +4767,60 @@ err_put_context:
return err;
}
+/**
+ * perf_event_create_kernel_counter
+ *
+ * @attr: attributes of the counter to create
+ * @cpu: cpu in which the counter is bound
+ * @pid: task to profile
+ */
+struct perf_event *
+perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
+ pid_t pid, perf_callback_t callback)
+{
+ struct perf_event *event;
+ struct perf_event_context *ctx;
+ int err;
+
+ /*
+ * Get the target context (task or percpu):
+ */
+
+ ctx = find_get_context(pid, cpu);
+ if (IS_ERR(ctx)) {
+ err = PTR_ERR(ctx);
+ goto err_exit;
+ }
+
+ event = perf_event_alloc(attr, cpu, ctx, NULL,
+ NULL, callback, GFP_KERNEL);
+ if (IS_ERR(event)) {
+ err = PTR_ERR(event);
+ goto err_put_context;
+ }
+
+ event->filp = NULL;
+ WARN_ON_ONCE(ctx->parent_ctx);
+ mutex_lock(&ctx->mutex);
+ perf_install_in_context(ctx, event, cpu);
+ ++ctx->generation;
+ mutex_unlock(&ctx->mutex);
+
+ event->owner = current;
+ get_task_struct(current);
+ mutex_lock(&current->perf_event_mutex);
+ list_add_tail(&event->owner_entry, &current->perf_event_list);
+ mutex_unlock(&current->perf_event_mutex);
+
+ return event;
+
+ err_put_context:
+ put_ctx(ctx);
+ err_exit:
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter);
+
/*
* inherit a event from parent task to child task:
*/
@@ -4597,7 +4846,7 @@ inherit_event(struct perf_event *parent_event,
child_event = perf_event_alloc(&parent_event->attr,
parent_event->cpu, child_ctx,
group_leader, parent_event,
- GFP_KERNEL);
+ NULL, GFP_KERNEL);
if (IS_ERR(child_event))
return child_event;
get_ctx(child_ctx);
@@ -4615,6 +4864,8 @@ inherit_event(struct perf_event *parent_event,
if (parent_event->attr.freq)
child_event->hw.sample_period = parent_event->hw.sample_period;
+ child_event->overflow_handler = parent_event->overflow_handler;
+
/*
* Link it up in the child's context:
*/
@@ -4704,7 +4955,6 @@ __perf_event_exit_task(struct perf_event *child_event,
{
struct perf_event *parent_event;
- update_event_times(child_event);
perf_event_remove_from_context(child_event);
parent_event = child_event->parent;
@@ -4756,6 +5006,7 @@ void perf_event_exit_task(struct task_struct *child)
* the events from it.
*/
unclone_ctx(child_ctx);
+ update_context_time(child_ctx);
spin_unlock_irqrestore(&child_ctx->lock, flags);
/*
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 04b3a83d686f..04a9e90d248f 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -693,21 +693,22 @@ static int software_resume(void)
/* The snapshot device should not be opened while we're running */
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
error = -EBUSY;
+ swsusp_close(FMODE_READ);
goto Unlock;
}
pm_prepare_console();
error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
if (error)
- goto Finish;
+ goto close_finish;
error = usermodehelper_disable();
if (error)
- goto Finish;
+ goto close_finish;
error = create_basic_memory_bitmaps();
if (error)
- goto Finish;
+ goto close_finish;
pr_debug("PM: Preparing processes for restore.\n");
error = prepare_processes();
@@ -719,6 +720,7 @@ static int software_resume(void)
pr_debug("PM: Reading hibernation image.\n");
error = swsusp_read(&flags);
+ swsusp_close(FMODE_READ);
if (!error)
hibernation_restore(flags & SF_PLATFORM_MODE);
@@ -737,6 +739,9 @@ static int software_resume(void)
mutex_unlock(&pm_mutex);
pr_debug("PM: Resume from disk failed.\n");
return error;
+close_finish:
+ swsusp_close(FMODE_READ);
+ goto Finish;
}
late_initcall(software_resume);
diff --git a/kernel/power/suspend_test.c b/kernel/power/suspend_test.c
index 17d8bb1acf9c..25596e450ac7 100644
--- a/kernel/power/suspend_test.c
+++ b/kernel/power/suspend_test.c
@@ -19,7 +19,7 @@
* The time it takes is system-specific though, so when we test this
* during system bootup we allow a LOT of time.
*/
-#define TEST_SUSPEND_SECONDS 5
+#define TEST_SUSPEND_SECONDS 10
static unsigned long suspend_test_start_time;
@@ -49,7 +49,8 @@ void suspend_test_finish(const char *label)
* has some performance issues. The stack dump of a WARN_ON
* is more likely to get the right attention than a printk...
*/
- WARN(msec > (TEST_SUSPEND_SECONDS * 1000), "Component: %s\n", label);
+ WARN(msec > (TEST_SUSPEND_SECONDS * 1000),
+ "Component: %s, time: %u\n", label, msec);
}
/*
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index b101cdc4df3f..890f6b11b1d3 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -314,7 +314,6 @@ static int save_image(struct swap_map_handle *handle,
{
unsigned int m;
int ret;
- int error = 0;
int nr_pages;
int err2;
struct bio *bio;
@@ -329,26 +328,27 @@ static int save_image(struct swap_map_handle *handle,
nr_pages = 0;
bio = NULL;
do_gettimeofday(&start);
- do {
+ while (1) {
ret = snapshot_read_next(snapshot, PAGE_SIZE);
- if (ret > 0) {
- error = swap_write_page(handle, data_of(*snapshot),
- &bio);
- if (error)
- break;
- if (!(nr_pages % m))
- printk("\b\b\b\b%3d%%", nr_pages / m);
- nr_pages++;
- }
- } while (ret > 0);
+ if (ret <= 0)
+ break;
+ ret = swap_write_page(handle, data_of(*snapshot), &bio);
+ if (ret)
+ break;
+ if (!(nr_pages % m))
+ printk("\b\b\b\b%3d%%", nr_pages / m);
+ nr_pages++;
+ }
err2 = wait_on_bio_chain(&bio);
do_gettimeofday(&stop);
- if (!error)
- error = err2;
- if (!error)
+ if (!ret)
+ ret = err2;
+ if (!ret)
printk("\b\b\b\bdone\n");
+ else
+ printk("\n");
swsusp_show_speed(&start, &stop, nr_to_write, "Wrote");
- return error;
+ return ret;
}
/**
@@ -536,7 +536,8 @@ static int load_image(struct swap_map_handle *handle,
snapshot_write_finalize(snapshot);
if (!snapshot_image_loaded(snapshot))
error = -ENODATA;
- }
+ } else
+ printk("\n");
swsusp_show_speed(&start, &stop, nr_to_read, "Read");
return error;
}
@@ -572,8 +573,6 @@ int swsusp_read(unsigned int *flags_p)
error = load_image(&handle, &snapshot, header->pages - 1);
release_swap_reader(&handle);
- blkdev_put(resume_bdev, FMODE_READ);
-
if (!error)
pr_debug("PM: Image successfully loaded\n");
else
@@ -596,7 +595,7 @@ int swsusp_check(void)
error = bio_read_page(swsusp_resume_block,
swsusp_header, NULL);
if (error)
- return error;
+ goto put;
if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) {
memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10);
@@ -604,8 +603,10 @@ int swsusp_check(void)
error = bio_write_page(swsusp_resume_block,
swsusp_header, NULL);
} else {
- return -EINVAL;
+ error = -EINVAL;
}
+
+put:
if (error)
blkdev_put(resume_bdev, FMODE_READ);
else
diff --git a/kernel/printk.c b/kernel/printk.c
index f38b07f78a4e..b5ac4d99c667 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -33,6 +33,7 @@
#include <linux/bootmem.h>
#include <linux/syscalls.h>
#include <linux/kexec.h>
+#include <linux/ratelimit.h>
#include <asm/uaccess.h>
@@ -1376,11 +1377,11 @@ late_initcall(disable_boot_consoles);
*/
DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10);
-int printk_ratelimit(void)
+int __printk_ratelimit(const char *func)
{
- return __ratelimit(&printk_ratelimit_state);
+ return ___ratelimit(&printk_ratelimit_state, func);
}
-EXPORT_SYMBOL(printk_ratelimit);
+EXPORT_SYMBOL(__printk_ratelimit);
/**
* printk_timed_ratelimit - caller-controlled printk ratelimiting
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 400183346ad2..9b7fd4723878 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -44,7 +44,6 @@
#include <linux/cpu.h>
#include <linux/mutex.h>
#include <linux/module.h>
-#include <linux/kernel_stat.h>
#ifdef CONFIG_DEBUG_LOCK_ALLOC
static struct lock_class_key rcu_lock_key;
@@ -53,8 +52,6 @@ struct lockdep_map rcu_lock_map =
EXPORT_SYMBOL_GPL(rcu_lock_map);
#endif
-int rcu_scheduler_active __read_mostly;
-
/*
* Awaken the corresponding synchronize_rcu() instance now that a
* grace period has elapsed.
@@ -66,122 +63,3 @@ void wakeme_after_rcu(struct rcu_head *head)
rcu = container_of(head, struct rcu_synchronize, head);
complete(&rcu->completion);
}
-
-#ifdef CONFIG_TREE_PREEMPT_RCU
-
-/**
- * synchronize_rcu - wait until a grace period has elapsed.
- *
- * Control will return to the caller some time after a full grace
- * period has elapsed, in other words after all currently executing RCU
- * read-side critical sections have completed. RCU read-side critical
- * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
- * and may be nested.
- */
-void synchronize_rcu(void)
-{
- struct rcu_synchronize rcu;
-
- if (!rcu_scheduler_active)
- return;
-
- init_completion(&rcu.completion);
- /* Will wake me after RCU finished. */
- call_rcu(&rcu.head, wakeme_after_rcu);
- /* Wait for it. */
- wait_for_completion(&rcu.completion);
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu);
-
-#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
-
-/**
- * synchronize_sched - wait until an rcu-sched grace period has elapsed.
- *
- * Control will return to the caller some time after a full rcu-sched
- * grace period has elapsed, in other words after all currently executing
- * rcu-sched read-side critical sections have completed. These read-side
- * critical sections are delimited by rcu_read_lock_sched() and
- * rcu_read_unlock_sched(), and may be nested. Note that preempt_disable(),
- * local_irq_disable(), and so on may be used in place of
- * rcu_read_lock_sched().
- *
- * This means that all preempt_disable code sequences, including NMI and
- * hardware-interrupt handlers, in progress on entry will have completed
- * before this primitive returns. However, this does not guarantee that
- * softirq handlers will have completed, since in some kernels, these
- * handlers can run in process context, and can block.
- *
- * This primitive provides the guarantees made by the (now removed)
- * synchronize_kernel() API. In contrast, synchronize_rcu() only
- * guarantees that rcu_read_lock() sections will have completed.
- * In "classic RCU", these two guarantees happen to be one and
- * the same, but can differ in realtime RCU implementations.
- */
-void synchronize_sched(void)
-{
- struct rcu_synchronize rcu;
-
- if (rcu_blocking_is_gp())
- return;
-
- init_completion(&rcu.completion);
- /* Will wake me after RCU finished. */
- call_rcu_sched(&rcu.head, wakeme_after_rcu);
- /* Wait for it. */
- wait_for_completion(&rcu.completion);
-}
-EXPORT_SYMBOL_GPL(synchronize_sched);
-
-/**
- * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed.
- *
- * Control will return to the caller some time after a full rcu_bh grace
- * period has elapsed, in other words after all currently executing rcu_bh
- * read-side critical sections have completed. RCU read-side critical
- * sections are delimited by rcu_read_lock_bh() and rcu_read_unlock_bh(),
- * and may be nested.
- */
-void synchronize_rcu_bh(void)
-{
- struct rcu_synchronize rcu;
-
- if (rcu_blocking_is_gp())
- return;
-
- init_completion(&rcu.completion);
- /* Will wake me after RCU finished. */
- call_rcu_bh(&rcu.head, wakeme_after_rcu);
- /* Wait for it. */
- wait_for_completion(&rcu.completion);
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
-
-static int __cpuinit rcu_barrier_cpu_hotplug(struct notifier_block *self,
- unsigned long action, void *hcpu)
-{
- return rcu_cpu_notify(self, action, hcpu);
-}
-
-void __init rcu_init(void)
-{
- int i;
-
- __rcu_init();
- cpu_notifier(rcu_barrier_cpu_hotplug, 0);
-
- /*
- * We don't need protection against CPU-hotplug here because
- * this is called early in boot, before either interrupts
- * or the scheduler are operational.
- */
- for_each_online_cpu(i)
- rcu_barrier_cpu_hotplug(NULL, CPU_UP_PREPARE, (void *)(long)i);
-}
-
-void rcu_scheduler_starting(void)
-{
- WARN_ON(num_online_cpus() != 1);
- WARN_ON(nr_context_switches() > 0);
- rcu_scheduler_active = 1;
-}
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
new file mode 100644
index 000000000000..9f6d9ff2572c
--- /dev/null
+++ b/kernel/rcutiny.c
@@ -0,0 +1,282 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion, the Bloatwatch edition.
+ *
+ * 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.
+ *
+ * Copyright IBM Corporation, 2008
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ * Documentation/RCU
+ */
+#include <linux/moduleparam.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/notifier.h>
+#include <linux/rcupdate.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/cpu.h>
+
+/* Global control variables for rcupdate callback mechanism. */
+struct rcu_ctrlblk {
+ struct rcu_head *rcucblist; /* List of pending callbacks (CBs). */
+ struct rcu_head **donetail; /* ->next pointer of last "done" CB. */
+ struct rcu_head **curtail; /* ->next pointer of last CB. */
+};
+
+/* Definition for rcupdate control block. */
+static struct rcu_ctrlblk rcu_ctrlblk = {
+ .donetail = &rcu_ctrlblk.rcucblist,
+ .curtail = &rcu_ctrlblk.rcucblist,
+};
+
+static struct rcu_ctrlblk rcu_bh_ctrlblk = {
+ .donetail = &rcu_bh_ctrlblk.rcucblist,
+ .curtail = &rcu_bh_ctrlblk.rcucblist,
+};
+
+#ifdef CONFIG_NO_HZ
+
+static long rcu_dynticks_nesting = 1;
+
+/*
+ * Enter dynticks-idle mode, which is an extended quiescent state
+ * if we have fully entered that mode (i.e., if the new value of
+ * dynticks_nesting is zero).
+ */
+void rcu_enter_nohz(void)
+{
+ if (--rcu_dynticks_nesting == 0)
+ rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */
+}
+
+/*
+ * Exit dynticks-idle mode, so that we are no longer in an extended
+ * quiescent state.
+ */
+void rcu_exit_nohz(void)
+{
+ rcu_dynticks_nesting++;
+}
+
+#endif /* #ifdef CONFIG_NO_HZ */
+
+/*
+ * Helper function for rcu_qsctr_inc() and rcu_bh_qsctr_inc().
+ * Also disable irqs to avoid confusion due to interrupt handlers
+ * invoking call_rcu().
+ */
+static int rcu_qsctr_help(struct rcu_ctrlblk *rcp)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (rcp->rcucblist != NULL &&
+ rcp->donetail != rcp->curtail) {
+ rcp->donetail = rcp->curtail;
+ local_irq_restore(flags);
+ return 1;
+ }
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+/*
+ * Record an rcu quiescent state. And an rcu_bh quiescent state while we
+ * are at it, given that any rcu quiescent state is also an rcu_bh
+ * quiescent state. Use "+" instead of "||" to defeat short circuiting.
+ */
+void rcu_sched_qs(int cpu)
+{
+ if (rcu_qsctr_help(&rcu_ctrlblk) + rcu_qsctr_help(&rcu_bh_ctrlblk))
+ raise_softirq(RCU_SOFTIRQ);
+}
+
+/*
+ * Record an rcu_bh quiescent state.
+ */
+void rcu_bh_qs(int cpu)
+{
+ if (rcu_qsctr_help(&rcu_bh_ctrlblk))
+ raise_softirq(RCU_SOFTIRQ);
+}
+
+/*
+ * Check to see if the scheduling-clock interrupt came from an extended
+ * quiescent state, and, if so, tell RCU about it.
+ */
+void rcu_check_callbacks(int cpu, int user)
+{
+ if (user ||
+ (idle_cpu(cpu) &&
+ !in_softirq() &&
+ hardirq_count() <= (1 << HARDIRQ_SHIFT)))
+ rcu_sched_qs(cpu);
+ else if (!in_softirq())
+ rcu_bh_qs(cpu);
+}
+
+/*
+ * Helper function for rcu_process_callbacks() that operates on the
+ * specified rcu_ctrlkblk structure.
+ */
+static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
+{
+ struct rcu_head *next, *list;
+ unsigned long flags;
+
+ /* If no RCU callbacks ready to invoke, just return. */
+ if (&rcp->rcucblist == rcp->donetail)
+ return;
+
+ /* Move the ready-to-invoke callbacks to a local list. */
+ local_irq_save(flags);
+ list = rcp->rcucblist;
+ rcp->rcucblist = *rcp->donetail;
+ *rcp->donetail = NULL;
+ if (rcp->curtail == rcp->donetail)
+ rcp->curtail = &rcp->rcucblist;
+ rcp->donetail = &rcp->rcucblist;
+ local_irq_restore(flags);
+
+ /* Invoke the callbacks on the local list. */
+ while (list) {
+ next = list->next;
+ prefetch(next);
+ list->func(list);
+ list = next;
+ }
+}
+
+/*
+ * Invoke any callbacks whose grace period has completed.
+ */
+static void rcu_process_callbacks(struct softirq_action *unused)
+{
+ __rcu_process_callbacks(&rcu_ctrlblk);
+ __rcu_process_callbacks(&rcu_bh_ctrlblk);
+}
+
+/*
+ * Wait for a grace period to elapse. But it is illegal to invoke
+ * synchronize_sched() from within an RCU read-side critical section.
+ * Therefore, any legal call to synchronize_sched() is a quiescent
+ * state, and so on a UP system, synchronize_sched() need do nothing.
+ * Ditto for synchronize_rcu_bh(). (But Lai Jiangshan points out the
+ * benefits of doing might_sleep() to reduce latency.)
+ *
+ * Cool, huh? (Due to Josh Triplett.)
+ *
+ * But we want to make this a static inline later.
+ */
+void synchronize_sched(void)
+{
+ cond_resched();
+}
+EXPORT_SYMBOL_GPL(synchronize_sched);
+
+void synchronize_rcu_bh(void)
+{
+ synchronize_sched();
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
+
+/*
+ * Helper function for call_rcu() and call_rcu_bh().
+ */
+static void __call_rcu(struct rcu_head *head,
+ void (*func)(struct rcu_head *rcu),
+ struct rcu_ctrlblk *rcp)
+{
+ unsigned long flags;
+
+ head->func = func;
+ head->next = NULL;
+
+ local_irq_save(flags);
+ *rcp->curtail = head;
+ rcp->curtail = &head->next;
+ local_irq_restore(flags);
+}
+
+/*
+ * Post an RCU callback to be invoked after the end of an RCU grace
+ * period. But since we have but one CPU, that would be after any
+ * quiescent state.
+ */
+void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
+{
+ __call_rcu(head, func, &rcu_ctrlblk);
+}
+EXPORT_SYMBOL_GPL(call_rcu);
+
+/*
+ * Post an RCU bottom-half callback to be invoked after any subsequent
+ * quiescent state.
+ */
+void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
+{
+ __call_rcu(head, func, &rcu_bh_ctrlblk);
+}
+EXPORT_SYMBOL_GPL(call_rcu_bh);
+
+void rcu_barrier(void)
+{
+ struct rcu_synchronize rcu;
+
+ init_completion(&rcu.completion);
+ /* Will wake me after RCU finished. */
+ call_rcu(&rcu.head, wakeme_after_rcu);
+ /* Wait for it. */
+ wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier);
+
+void rcu_barrier_bh(void)
+{
+ struct rcu_synchronize rcu;
+
+ init_completion(&rcu.completion);
+ /* Will wake me after RCU finished. */
+ call_rcu_bh(&rcu.head, wakeme_after_rcu);
+ /* Wait for it. */
+ wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_bh);
+
+void rcu_barrier_sched(void)
+{
+ struct rcu_synchronize rcu;
+
+ init_completion(&rcu.completion);
+ /* Will wake me after RCU finished. */
+ call_rcu_sched(&rcu.head, wakeme_after_rcu);
+ /* Wait for it. */
+ wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_sched);
+
+void __init rcu_init(void)
+{
+ open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+}
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 697c0a0229d4..a621a67ef4e3 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -327,6 +327,11 @@ rcu_torture_cb(struct rcu_head *p)
cur_ops->deferred_free(rp);
}
+static int rcu_no_completed(void)
+{
+ return 0;
+}
+
static void rcu_torture_deferred_free(struct rcu_torture *p)
{
call_rcu(&p->rtort_rcu, rcu_torture_cb);
@@ -388,6 +393,21 @@ static struct rcu_torture_ops rcu_sync_ops = {
.name = "rcu_sync"
};
+static struct rcu_torture_ops rcu_expedited_ops = {
+ .init = rcu_sync_torture_init,
+ .cleanup = NULL,
+ .readlock = rcu_torture_read_lock,
+ .read_delay = rcu_read_delay, /* just reuse rcu's version. */
+ .readunlock = rcu_torture_read_unlock,
+ .completed = rcu_no_completed,
+ .deferred_free = rcu_sync_torture_deferred_free,
+ .sync = synchronize_rcu_expedited,
+ .cb_barrier = NULL,
+ .stats = NULL,
+ .irq_capable = 1,
+ .name = "rcu_expedited"
+};
+
/*
* Definitions for rcu_bh torture testing.
*/
@@ -547,6 +567,25 @@ static struct rcu_torture_ops srcu_ops = {
.name = "srcu"
};
+static void srcu_torture_synchronize_expedited(void)
+{
+ synchronize_srcu_expedited(&srcu_ctl);
+}
+
+static struct rcu_torture_ops srcu_expedited_ops = {
+ .init = srcu_torture_init,
+ .cleanup = srcu_torture_cleanup,
+ .readlock = srcu_torture_read_lock,
+ .read_delay = srcu_read_delay,
+ .readunlock = srcu_torture_read_unlock,
+ .completed = srcu_torture_completed,
+ .deferred_free = rcu_sync_torture_deferred_free,
+ .sync = srcu_torture_synchronize_expedited,
+ .cb_barrier = NULL,
+ .stats = srcu_torture_stats,
+ .name = "srcu_expedited"
+};
+
/*
* Definitions for sched torture testing.
*/
@@ -562,11 +601,6 @@ static void sched_torture_read_unlock(int idx)
preempt_enable();
}
-static int sched_torture_completed(void)
-{
- return 0;
-}
-
static void rcu_sched_torture_deferred_free(struct rcu_torture *p)
{
call_rcu_sched(&p->rtort_rcu, rcu_torture_cb);
@@ -583,7 +617,7 @@ static struct rcu_torture_ops sched_ops = {
.readlock = sched_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = sched_torture_read_unlock,
- .completed = sched_torture_completed,
+ .completed = rcu_no_completed,
.deferred_free = rcu_sched_torture_deferred_free,
.sync = sched_torture_synchronize,
.cb_barrier = rcu_barrier_sched,
@@ -592,13 +626,13 @@ static struct rcu_torture_ops sched_ops = {
.name = "sched"
};
-static struct rcu_torture_ops sched_ops_sync = {
+static struct rcu_torture_ops sched_sync_ops = {
.init = rcu_sync_torture_init,
.cleanup = NULL,
.readlock = sched_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = sched_torture_read_unlock,
- .completed = sched_torture_completed,
+ .completed = rcu_no_completed,
.deferred_free = rcu_sync_torture_deferred_free,
.sync = sched_torture_synchronize,
.cb_barrier = NULL,
@@ -612,7 +646,7 @@ static struct rcu_torture_ops sched_expedited_ops = {
.readlock = sched_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = sched_torture_read_unlock,
- .completed = sched_torture_completed,
+ .completed = rcu_no_completed,
.deferred_free = rcu_sync_torture_deferred_free,
.sync = synchronize_sched_expedited,
.cb_barrier = NULL,
@@ -1097,9 +1131,10 @@ rcu_torture_init(void)
int cpu;
int firsterr = 0;
static struct rcu_torture_ops *torture_ops[] =
- { &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops,
- &sched_expedited_ops,
- &srcu_ops, &sched_ops, &sched_ops_sync, };
+ { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops,
+ &rcu_bh_ops, &rcu_bh_sync_ops,
+ &srcu_ops, &srcu_expedited_ops,
+ &sched_ops, &sched_sync_ops, &sched_expedited_ops, };
mutex_lock(&fullstop_mutex);
@@ -1110,8 +1145,12 @@ rcu_torture_init(void)
break;
}
if (i == ARRAY_SIZE(torture_ops)) {
- printk(KERN_ALERT "rcutorture: invalid torture type: \"%s\"\n",
+ printk(KERN_ALERT "rcu-torture: invalid torture type: \"%s\"\n",
torture_type);
+ printk(KERN_ALERT "rcu-torture types:");
+ for (i = 0; i < ARRAY_SIZE(torture_ops); i++)
+ printk(KERN_ALERT " %s", torture_ops[i]->name);
+ printk(KERN_ALERT "\n");
mutex_unlock(&fullstop_mutex);
return -EINVAL;
}
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 705f02ac7433..53ae9598f798 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -46,20 +46,24 @@
#include <linux/cpu.h>
#include <linux/mutex.h>
#include <linux/time.h>
+#include <linux/kernel_stat.h>
#include "rcutree.h"
/* Data structures. */
+static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
+
#define RCU_STATE_INITIALIZER(name) { \
.level = { &name.node[0] }, \
.levelcnt = { \
NUM_RCU_LVL_0, /* root of hierarchy. */ \
NUM_RCU_LVL_1, \
NUM_RCU_LVL_2, \
- NUM_RCU_LVL_3, /* == MAX_RCU_LVLS */ \
+ NUM_RCU_LVL_3, \
+ NUM_RCU_LVL_4, /* == MAX_RCU_LVLS */ \
}, \
- .signaled = RCU_SIGNAL_INIT, \
+ .signaled = RCU_GP_IDLE, \
.gpnum = -300, \
.completed = -300, \
.onofflock = __SPIN_LOCK_UNLOCKED(&name.onofflock), \
@@ -77,6 +81,8 @@ DEFINE_PER_CPU(struct rcu_data, rcu_sched_data);
struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
+static int rcu_scheduler_active __read_mostly;
+
/*
* Return true if an RCU grace period is in progress. The ACCESS_ONCE()s
@@ -98,7 +104,7 @@ void rcu_sched_qs(int cpu)
struct rcu_data *rdp;
rdp = &per_cpu(rcu_sched_data, cpu);
- rdp->passed_quiesc_completed = rdp->completed;
+ rdp->passed_quiesc_completed = rdp->gpnum - 1;
barrier();
rdp->passed_quiesc = 1;
rcu_preempt_note_context_switch(cpu);
@@ -109,7 +115,7 @@ void rcu_bh_qs(int cpu)
struct rcu_data *rdp;
rdp = &per_cpu(rcu_bh_data, cpu);
- rdp->passed_quiesc_completed = rdp->completed;
+ rdp->passed_quiesc_completed = rdp->gpnum - 1;
barrier();
rdp->passed_quiesc = 1;
}
@@ -335,28 +341,9 @@ void rcu_irq_exit(void)
set_need_resched();
}
-/*
- * Record the specified "completed" value, which is later used to validate
- * dynticks counter manipulations. Specify "rsp->completed - 1" to
- * unconditionally invalidate any future dynticks manipulations (which is
- * useful at the beginning of a grace period).
- */
-static void dyntick_record_completed(struct rcu_state *rsp, long comp)
-{
- rsp->dynticks_completed = comp;
-}
-
#ifdef CONFIG_SMP
/*
- * Recall the previously recorded value of the completion for dynticks.
- */
-static long dyntick_recall_completed(struct rcu_state *rsp)
-{
- return rsp->dynticks_completed;
-}
-
-/*
* Snapshot the specified CPU's dynticks counter so that we can later
* credit them with an implicit quiescent state. Return 1 if this CPU
* is in dynticks idle mode, which is an extended quiescent state.
@@ -419,24 +406,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
#else /* #ifdef CONFIG_NO_HZ */
-static void dyntick_record_completed(struct rcu_state *rsp, long comp)
-{
-}
-
#ifdef CONFIG_SMP
-/*
- * If there are no dynticks, then the only way that a CPU can passively
- * be in a quiescent state is to be offline. Unlike dynticks idle, which
- * is a point in time during the prior (already finished) grace period,
- * an offline CPU is always in a quiescent state, and thus can be
- * unconditionally applied. So just return the current value of completed.
- */
-static long dyntick_recall_completed(struct rcu_state *rsp)
-{
- return rsp->completed;
-}
-
static int dyntick_save_progress_counter(struct rcu_data *rdp)
{
return 0;
@@ -553,13 +524,33 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
/*
* Update CPU-local rcu_data state to record the newly noticed grace period.
* This is used both when we started the grace period and when we notice
- * that someone else started the grace period.
+ * that someone else started the grace period. The caller must hold the
+ * ->lock of the leaf rcu_node structure corresponding to the current CPU,
+ * and must have irqs disabled.
*/
+static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+{
+ if (rdp->gpnum != rnp->gpnum) {
+ rdp->qs_pending = 1;
+ rdp->passed_quiesc = 0;
+ rdp->gpnum = rnp->gpnum;
+ }
+}
+
static void note_new_gpnum(struct rcu_state *rsp, struct rcu_data *rdp)
{
- rdp->qs_pending = 1;
- rdp->passed_quiesc = 0;
- rdp->gpnum = rsp->gpnum;
+ unsigned long flags;
+ struct rcu_node *rnp;
+
+ local_irq_save(flags);
+ rnp = rdp->mynode;
+ if (rdp->gpnum == ACCESS_ONCE(rnp->gpnum) || /* outside lock. */
+ !spin_trylock(&rnp->lock)) { /* irqs already off, retry later. */
+ local_irq_restore(flags);
+ return;
+ }
+ __note_new_gpnum(rsp, rnp, rdp);
+ spin_unlock_irqrestore(&rnp->lock, flags);
}
/*
@@ -583,6 +574,79 @@ check_for_new_grace_period(struct rcu_state *rsp, struct rcu_data *rdp)
}
/*
+ * Advance this CPU's callbacks, but only if the current grace period
+ * has ended. This may be called only from the CPU to whom the rdp
+ * belongs. In addition, the corresponding leaf rcu_node structure's
+ * ->lock must be held by the caller, with irqs disabled.
+ */
+static void
+__rcu_process_gp_end(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+{
+ /* Did another grace period end? */
+ if (rdp->completed != rnp->completed) {
+
+ /* Advance callbacks. No harm if list empty. */
+ rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[RCU_WAIT_TAIL];
+ rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_READY_TAIL];
+ rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+
+ /* Remember that we saw this grace-period completion. */
+ rdp->completed = rnp->completed;
+ }
+}
+
+/*
+ * Advance this CPU's callbacks, but only if the current grace period
+ * has ended. This may be called only from the CPU to whom the rdp
+ * belongs.
+ */
+static void
+rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp)
+{
+ unsigned long flags;
+ struct rcu_node *rnp;
+
+ local_irq_save(flags);
+ rnp = rdp->mynode;
+ if (rdp->completed == ACCESS_ONCE(rnp->completed) || /* outside lock. */
+ !spin_trylock(&rnp->lock)) { /* irqs already off, retry later. */
+ local_irq_restore(flags);
+ return;
+ }
+ __rcu_process_gp_end(rsp, rnp, rdp);
+ spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+/*
+ * Do per-CPU grace-period initialization for running CPU. The caller
+ * must hold the lock of the leaf rcu_node structure corresponding to
+ * this CPU.
+ */
+static void
+rcu_start_gp_per_cpu(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+{
+ /* Prior grace period ended, so advance callbacks for current CPU. */
+ __rcu_process_gp_end(rsp, rnp, rdp);
+
+ /*
+ * Because this CPU just now started the new grace period, we know
+ * that all of its callbacks will be covered by this upcoming grace
+ * period, even the ones that were registered arbitrarily recently.
+ * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL.
+ *
+ * Other CPUs cannot be sure exactly when the grace period started.
+ * Therefore, their recently registered callbacks must pass through
+ * an additional RCU_NEXT_READY stage, so that they will be handled
+ * by the next RCU grace period.
+ */
+ rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+ rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+
+ /* Set state so that this CPU will detect the next quiescent state. */
+ __note_new_gpnum(rsp, rnp, rdp);
+}
+
+/*
* Start a new RCU grace period if warranted, re-initializing the hierarchy
* in preparation for detecting the next grace period. The caller must hold
* the root node's ->lock, which is released before return. Hard irqs must
@@ -596,7 +660,23 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
struct rcu_node *rnp = rcu_get_root(rsp);
if (!cpu_needs_another_gp(rsp, rdp)) {
- spin_unlock_irqrestore(&rnp->lock, flags);
+ if (rnp->completed == rsp->completed) {
+ spin_unlock_irqrestore(&rnp->lock, flags);
+ return;
+ }
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
+
+ /*
+ * Propagate new ->completed value to rcu_node structures
+ * so that other CPUs don't have to wait until the start
+ * of the next grace period to process their callbacks.
+ */
+ rcu_for_each_node_breadth_first(rsp, rnp) {
+ spin_lock(&rnp->lock); /* irqs already disabled. */
+ rnp->completed = rsp->completed;
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
+ }
+ local_irq_restore(flags);
return;
}
@@ -606,29 +686,15 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
rsp->signaled = RCU_GP_INIT; /* Hold off force_quiescent_state. */
rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
record_gp_stall_check_time(rsp);
- dyntick_record_completed(rsp, rsp->completed - 1);
- note_new_gpnum(rsp, rdp);
-
- /*
- * Because this CPU just now started the new grace period, we know
- * that all of its callbacks will be covered by this upcoming grace
- * period, even the ones that were registered arbitrarily recently.
- * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL.
- *
- * Other CPUs cannot be sure exactly when the grace period started.
- * Therefore, their recently registered callbacks must pass through
- * an additional RCU_NEXT_READY stage, so that they will be handled
- * by the next RCU grace period.
- */
- rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
- rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
/* Special-case the common single-level case. */
if (NUM_RCU_NODES == 1) {
rcu_preempt_check_blocked_tasks(rnp);
rnp->qsmask = rnp->qsmaskinit;
rnp->gpnum = rsp->gpnum;
+ rnp->completed = rsp->completed;
rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state OK. */
+ rcu_start_gp_per_cpu(rsp, rnp, rdp);
spin_unlock_irqrestore(&rnp->lock, flags);
return;
}
@@ -657,69 +723,50 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
* irqs disabled.
*/
rcu_for_each_node_breadth_first(rsp, rnp) {
- spin_lock(&rnp->lock); /* irqs already disabled. */
+ spin_lock(&rnp->lock); /* irqs already disabled. */
rcu_preempt_check_blocked_tasks(rnp);
rnp->qsmask = rnp->qsmaskinit;
rnp->gpnum = rsp->gpnum;
- spin_unlock(&rnp->lock); /* irqs already disabled. */
+ rnp->completed = rsp->completed;
+ if (rnp == rdp->mynode)
+ rcu_start_gp_per_cpu(rsp, rnp, rdp);
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
}
+ rnp = rcu_get_root(rsp);
+ spin_lock(&rnp->lock); /* irqs already disabled. */
rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state now OK. */
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
spin_unlock_irqrestore(&rsp->onofflock, flags);
}
/*
- * Advance this CPU's callbacks, but only if the current grace period
- * has ended. This may be called only from the CPU to whom the rdp
- * belongs.
- */
-static void
-rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp)
-{
- long completed_snap;
- unsigned long flags;
-
- local_irq_save(flags);
- completed_snap = ACCESS_ONCE(rsp->completed); /* outside of lock. */
-
- /* Did another grace period end? */
- if (rdp->completed != completed_snap) {
-
- /* Advance callbacks. No harm if list empty. */
- rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[RCU_WAIT_TAIL];
- rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_READY_TAIL];
- rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
-
- /* Remember that we saw this grace-period completion. */
- rdp->completed = completed_snap;
- }
- local_irq_restore(flags);
-}
-
-/*
- * Clean up after the prior grace period and let rcu_start_gp() start up
- * the next grace period if one is needed. Note that the caller must
- * hold rnp->lock, as required by rcu_start_gp(), which will release it.
+ * Report a full set of quiescent states to the specified rcu_state
+ * data structure. This involves cleaning up after the prior grace
+ * period and letting rcu_start_gp() start up the next grace period
+ * if one is needed. Note that the caller must hold rnp->lock, as
+ * required by rcu_start_gp(), which will release it.
*/
-static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags)
+static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags)
__releases(rcu_get_root(rsp)->lock)
{
WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
rsp->completed = rsp->gpnum;
- rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]);
+ rsp->signaled = RCU_GP_IDLE;
rcu_start_gp(rsp, flags); /* releases root node's rnp->lock. */
}
/*
- * Similar to cpu_quiet(), for which it is a helper function. Allows
- * a group of CPUs to be quieted at one go, though all the CPUs in the
- * group must be represented by the same leaf rcu_node structure.
- * That structure's lock must be held upon entry, and it is released
- * before return.
+ * Similar to rcu_report_qs_rdp(), for which it is a helper function.
+ * Allows quiescent states for a group of CPUs to be reported at one go
+ * to the specified rcu_node structure, though all the CPUs in the group
+ * must be represented by the same rcu_node structure (which need not be
+ * a leaf rcu_node structure, though it often will be). That structure's
+ * lock must be held upon entry, and it is released before return.
*/
static void
-cpu_quiet_msk(unsigned long mask, struct rcu_state *rsp, struct rcu_node *rnp,
- unsigned long flags)
+rcu_report_qs_rnp(unsigned long mask, struct rcu_state *rsp,
+ struct rcu_node *rnp, unsigned long flags)
__releases(rnp->lock)
{
struct rcu_node *rnp_c;
@@ -755,21 +802,23 @@ cpu_quiet_msk(unsigned long mask, struct rcu_state *rsp, struct rcu_node *rnp,
/*
* Get here if we are the last CPU to pass through a quiescent
- * state for this grace period. Invoke cpu_quiet_msk_finish()
+ * state for this grace period. Invoke rcu_report_qs_rsp()
* to clean up and start the next grace period if one is needed.
*/
- cpu_quiet_msk_finish(rsp, flags); /* releases rnp->lock. */
+ rcu_report_qs_rsp(rsp, flags); /* releases rnp->lock. */
}
/*
- * Record a quiescent state for the specified CPU, which must either be
- * the current CPU. The lastcomp argument is used to make sure we are
- * still in the grace period of interest. We don't want to end the current
- * grace period based on quiescent states detected in an earlier grace
- * period!
+ * Record a quiescent state for the specified CPU to that CPU's rcu_data
+ * structure. This must be either called from the specified CPU, or
+ * called when the specified CPU is known to be offline (and when it is
+ * also known that no other CPU is concurrently trying to help the offline
+ * CPU). The lastcomp argument is used to make sure we are still in the
+ * grace period of interest. We don't want to end the current grace period
+ * based on quiescent states detected in an earlier grace period!
*/
static void
-cpu_quiet(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
+rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
{
unsigned long flags;
unsigned long mask;
@@ -777,15 +826,15 @@ cpu_quiet(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
rnp = rdp->mynode;
spin_lock_irqsave(&rnp->lock, flags);
- if (lastcomp != ACCESS_ONCE(rsp->completed)) {
+ if (lastcomp != rnp->completed) {
/*
* Someone beat us to it for this grace period, so leave.
* The race with GP start is resolved by the fact that we
* hold the leaf rcu_node lock, so that the per-CPU bits
* cannot yet be initialized -- so we would simply find our
- * CPU's bit already cleared in cpu_quiet_msk() if this race
- * occurred.
+ * CPU's bit already cleared in rcu_report_qs_rnp() if this
+ * race occurred.
*/
rdp->passed_quiesc = 0; /* try again later! */
spin_unlock_irqrestore(&rnp->lock, flags);
@@ -803,7 +852,7 @@ cpu_quiet(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
*/
rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
- cpu_quiet_msk(mask, rsp, rnp, flags); /* releases rnp->lock */
+ rcu_report_qs_rnp(mask, rsp, rnp, flags); /* rlses rnp->lock */
}
}
@@ -834,8 +883,11 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
if (!rdp->passed_quiesc)
return;
- /* Tell RCU we are done (but cpu_quiet() will be the judge of that). */
- cpu_quiet(rdp->cpu, rsp, rdp, rdp->passed_quiesc_completed);
+ /*
+ * Tell RCU we are done (but rcu_report_qs_rdp() will be the
+ * judge of that).
+ */
+ rcu_report_qs_rdp(rdp->cpu, rsp, rdp, rdp->passed_quiesc_completed);
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -895,8 +947,8 @@ static void rcu_adopt_orphan_cbs(struct rcu_state *rsp)
static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
{
unsigned long flags;
- long lastcomp;
unsigned long mask;
+ int need_report = 0;
struct rcu_data *rdp = rsp->rda[cpu];
struct rcu_node *rnp;
@@ -910,17 +962,32 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
spin_lock(&rnp->lock); /* irqs already disabled. */
rnp->qsmaskinit &= ~mask;
if (rnp->qsmaskinit != 0) {
- spin_unlock(&rnp->lock); /* irqs remain disabled. */
+ if (rnp != rdp->mynode)
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
break;
}
- rcu_preempt_offline_tasks(rsp, rnp, rdp);
+ if (rnp == rdp->mynode)
+ need_report = rcu_preempt_offline_tasks(rsp, rnp, rdp);
+ else
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
mask = rnp->grpmask;
- spin_unlock(&rnp->lock); /* irqs remain disabled. */
rnp = rnp->parent;
} while (rnp != NULL);
- lastcomp = rsp->completed;
- spin_unlock_irqrestore(&rsp->onofflock, flags);
+ /*
+ * We still hold the leaf rcu_node structure lock here, and
+ * irqs are still disabled. The reason for this subterfuge is
+ * because invoking rcu_report_unblock_qs_rnp() with ->onofflock
+ * held leads to deadlock.
+ */
+ spin_unlock(&rsp->onofflock); /* irqs remain disabled. */
+ rnp = rdp->mynode;
+ if (need_report & RCU_OFL_TASKS_NORM_GP)
+ rcu_report_unblock_qs_rnp(rnp, flags);
+ else
+ spin_unlock_irqrestore(&rnp->lock, flags);
+ if (need_report & RCU_OFL_TASKS_EXP_GP)
+ rcu_report_exp_rnp(rsp, rnp);
rcu_adopt_orphan_cbs(rsp);
}
@@ -958,7 +1025,7 @@ static void rcu_offline_cpu(int cpu)
* Invoke any RCU callbacks that have made it to the end of their grace
* period. Thottle as specified by rdp->blimit.
*/
-static void rcu_do_batch(struct rcu_data *rdp)
+static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
{
unsigned long flags;
struct rcu_head *next, *list, **tail;
@@ -1011,6 +1078,13 @@ static void rcu_do_batch(struct rcu_data *rdp)
if (rdp->blimit == LONG_MAX && rdp->qlen <= qlowmark)
rdp->blimit = blimit;
+ /* Reset ->qlen_last_fqs_check trigger if enough CBs have drained. */
+ if (rdp->qlen == 0 && rdp->qlen_last_fqs_check != 0) {
+ rdp->qlen_last_fqs_check = 0;
+ rdp->n_force_qs_snap = rsp->n_force_qs;
+ } else if (rdp->qlen < rdp->qlen_last_fqs_check - qhimark)
+ rdp->qlen_last_fqs_check = rdp->qlen;
+
local_irq_restore(flags);
/* Re-raise the RCU softirq if there are callbacks remaining. */
@@ -1085,7 +1159,7 @@ static int rcu_process_dyntick(struct rcu_state *rsp, long lastcomp,
rcu_for_each_leaf_node(rsp, rnp) {
mask = 0;
spin_lock_irqsave(&rnp->lock, flags);
- if (rsp->completed != lastcomp) {
+ if (rnp->completed != lastcomp) {
spin_unlock_irqrestore(&rnp->lock, flags);
return 1;
}
@@ -1099,10 +1173,10 @@ static int rcu_process_dyntick(struct rcu_state *rsp, long lastcomp,
if ((rnp->qsmask & bit) != 0 && f(rsp->rda[cpu]))
mask |= bit;
}
- if (mask != 0 && rsp->completed == lastcomp) {
+ if (mask != 0 && rnp->completed == lastcomp) {
- /* cpu_quiet_msk() releases rnp->lock. */
- cpu_quiet_msk(mask, rsp, rnp, flags);
+ /* rcu_report_qs_rnp() releases rnp->lock. */
+ rcu_report_qs_rnp(mask, rsp, rnp, flags);
continue;
}
spin_unlock_irqrestore(&rnp->lock, flags);
@@ -1120,6 +1194,7 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
long lastcomp;
struct rcu_node *rnp = rcu_get_root(rsp);
u8 signaled;
+ u8 forcenow;
if (!rcu_gp_in_progress(rsp))
return; /* No grace period in progress, nothing to force. */
@@ -1132,19 +1207,20 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
goto unlock_ret; /* no emergency and done recently. */
rsp->n_force_qs++;
spin_lock(&rnp->lock);
- lastcomp = rsp->completed;
+ lastcomp = rsp->gpnum - 1;
signaled = rsp->signaled;
rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
- if (lastcomp == rsp->gpnum) {
+ if(!rcu_gp_in_progress(rsp)) {
rsp->n_force_qs_ngp++;
spin_unlock(&rnp->lock);
goto unlock_ret; /* no GP in progress, time updated. */
}
spin_unlock(&rnp->lock);
switch (signaled) {
+ case RCU_GP_IDLE:
case RCU_GP_INIT:
- break; /* grace period still initializing, ignore. */
+ break; /* grace period idle or initializing, ignore. */
case RCU_SAVE_DYNTICK:
@@ -1155,20 +1231,29 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
if (rcu_process_dyntick(rsp, lastcomp,
dyntick_save_progress_counter))
goto unlock_ret;
+ /* fall into next case. */
+
+ case RCU_SAVE_COMPLETED:
/* Update state, record completion counter. */
+ forcenow = 0;
spin_lock(&rnp->lock);
- if (lastcomp == rsp->completed) {
+ if (lastcomp + 1 == rsp->gpnum &&
+ lastcomp == rsp->completed &&
+ rsp->signaled == signaled) {
rsp->signaled = RCU_FORCE_QS;
- dyntick_record_completed(rsp, lastcomp);
+ rsp->completed_fqs = lastcomp;
+ forcenow = signaled == RCU_SAVE_COMPLETED;
}
spin_unlock(&rnp->lock);
- break;
+ if (!forcenow)
+ break;
+ /* fall into next case. */
case RCU_FORCE_QS:
/* Check dyntick-idle state, send IPI to laggarts. */
- if (rcu_process_dyntick(rsp, dyntick_recall_completed(rsp),
+ if (rcu_process_dyntick(rsp, rsp->completed_fqs,
rcu_implicit_dynticks_qs))
goto unlock_ret;
@@ -1224,7 +1309,7 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp)
}
/* If there are callbacks ready, invoke them. */
- rcu_do_batch(rdp);
+ rcu_do_batch(rsp, rdp);
}
/*
@@ -1288,10 +1373,20 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
rcu_start_gp(rsp, nestflag); /* releases rnp_root->lock. */
}
- /* Force the grace period if too many callbacks or too long waiting. */
- if (unlikely(++rdp->qlen > qhimark)) {
+ /*
+ * Force the grace period if too many callbacks or too long waiting.
+ * Enforce hysteresis, and don't invoke force_quiescent_state()
+ * if some other CPU has recently done so. Also, don't bother
+ * invoking force_quiescent_state() if the newly enqueued callback
+ * is the only one waiting for a grace period to complete.
+ */
+ if (unlikely(++rdp->qlen > rdp->qlen_last_fqs_check + qhimark)) {
rdp->blimit = LONG_MAX;
- force_quiescent_state(rsp, 0);
+ if (rsp->n_force_qs == rdp->n_force_qs_snap &&
+ *rdp->nxttail[RCU_DONE_TAIL] != head)
+ force_quiescent_state(rsp, 0);
+ rdp->n_force_qs_snap = rsp->n_force_qs;
+ rdp->qlen_last_fqs_check = rdp->qlen;
} else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)
force_quiescent_state(rsp, 1);
local_irq_restore(flags);
@@ -1315,6 +1410,68 @@ void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
}
EXPORT_SYMBOL_GPL(call_rcu_bh);
+/**
+ * synchronize_sched - wait until an rcu-sched grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full rcu-sched
+ * grace period has elapsed, in other words after all currently executing
+ * rcu-sched read-side critical sections have completed. These read-side
+ * critical sections are delimited by rcu_read_lock_sched() and
+ * rcu_read_unlock_sched(), and may be nested. Note that preempt_disable(),
+ * local_irq_disable(), and so on may be used in place of
+ * rcu_read_lock_sched().
+ *
+ * This means that all preempt_disable code sequences, including NMI and
+ * hardware-interrupt handlers, in progress on entry will have completed
+ * before this primitive returns. However, this does not guarantee that
+ * softirq handlers will have completed, since in some kernels, these
+ * handlers can run in process context, and can block.
+ *
+ * This primitive provides the guarantees made by the (now removed)
+ * synchronize_kernel() API. In contrast, synchronize_rcu() only
+ * guarantees that rcu_read_lock() sections will have completed.
+ * In "classic RCU", these two guarantees happen to be one and
+ * the same, but can differ in realtime RCU implementations.
+ */
+void synchronize_sched(void)
+{
+ struct rcu_synchronize rcu;
+
+ if (rcu_blocking_is_gp())
+ return;
+
+ init_completion(&rcu.completion);
+ /* Will wake me after RCU finished. */
+ call_rcu_sched(&rcu.head, wakeme_after_rcu);
+ /* Wait for it. */
+ wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(synchronize_sched);
+
+/**
+ * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full rcu_bh grace
+ * period has elapsed, in other words after all currently executing rcu_bh
+ * read-side critical sections have completed. RCU read-side critical
+ * sections are delimited by rcu_read_lock_bh() and rcu_read_unlock_bh(),
+ * and may be nested.
+ */
+void synchronize_rcu_bh(void)
+{
+ struct rcu_synchronize rcu;
+
+ if (rcu_blocking_is_gp())
+ return;
+
+ init_completion(&rcu.completion);
+ /* Will wake me after RCU finished. */
+ call_rcu_bh(&rcu.head, wakeme_after_rcu);
+ /* Wait for it. */
+ wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
+
/*
* Check to see if there is any immediate RCU-related work to be done
* by the current CPU, for the specified type of RCU, returning 1 if so.
@@ -1324,6 +1481,8 @@ EXPORT_SYMBOL_GPL(call_rcu_bh);
*/
static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
{
+ struct rcu_node *rnp = rdp->mynode;
+
rdp->n_rcu_pending++;
/* Check for CPU stalls, if enabled. */
@@ -1348,13 +1507,13 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
}
/* Has another RCU grace period completed? */
- if (ACCESS_ONCE(rsp->completed) != rdp->completed) { /* outside lock */
+ if (ACCESS_ONCE(rnp->completed) != rdp->completed) { /* outside lock */
rdp->n_rp_gp_completed++;
return 1;
}
/* Has a new RCU grace period started? */
- if (ACCESS_ONCE(rsp->gpnum) != rdp->gpnum) { /* outside lock */
+ if (ACCESS_ONCE(rnp->gpnum) != rdp->gpnum) { /* outside lock */
rdp->n_rp_gp_started++;
return 1;
}
@@ -1397,6 +1556,21 @@ int rcu_needs_cpu(int cpu)
rcu_preempt_needs_cpu(cpu);
}
+/*
+ * This function is invoked towards the end of the scheduler's initialization
+ * process. Before this is called, the idle task might contain
+ * RCU read-side critical sections (during which time, this idle
+ * task is booting the system). After this function is called, the
+ * idle tasks are prohibited from containing RCU read-side critical
+ * sections.
+ */
+void rcu_scheduler_starting(void)
+{
+ WARN_ON(num_online_cpus() != 1);
+ WARN_ON(nr_context_switches() > 0);
+ rcu_scheduler_active = 1;
+}
+
static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
static atomic_t rcu_barrier_cpu_count;
static DEFINE_MUTEX(rcu_barrier_mutex);
@@ -1508,21 +1682,18 @@ static void __cpuinit
rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable)
{
unsigned long flags;
- long lastcomp;
unsigned long mask;
struct rcu_data *rdp = rsp->rda[cpu];
struct rcu_node *rnp = rcu_get_root(rsp);
/* Set up local state, ensuring consistent view of global state. */
spin_lock_irqsave(&rnp->lock, flags);
- lastcomp = rsp->completed;
- rdp->completed = lastcomp;
- rdp->gpnum = lastcomp;
rdp->passed_quiesc = 0; /* We could be racing with new GP, */
rdp->qs_pending = 1; /* so set up to respond to current GP. */
rdp->beenonline = 1; /* We have now been online. */
rdp->preemptable = preemptable;
- rdp->passed_quiesc_completed = lastcomp - 1;
+ rdp->qlen_last_fqs_check = 0;
+ rdp->n_force_qs_snap = rsp->n_force_qs;
rdp->blimit = blimit;
spin_unlock(&rnp->lock); /* irqs remain disabled. */
@@ -1542,6 +1713,11 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable)
spin_lock(&rnp->lock); /* irqs already disabled. */
rnp->qsmaskinit |= mask;
mask = rnp->grpmask;
+ if (rnp == rdp->mynode) {
+ rdp->gpnum = rnp->completed; /* if GP in progress... */
+ rdp->completed = rnp->completed;
+ rdp->passed_quiesc_completed = rnp->completed - 1;
+ }
spin_unlock(&rnp->lock); /* irqs already disabled. */
rnp = rnp->parent;
} while (rnp != NULL && !(rnp->qsmaskinit & mask));
@@ -1559,8 +1735,8 @@ static void __cpuinit rcu_online_cpu(int cpu)
/*
* Handle CPU online/offline notification events.
*/
-int __cpuinit rcu_cpu_notify(struct notifier_block *self,
- unsigned long action, void *hcpu)
+static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
{
long cpu = (long)hcpu;
@@ -1647,8 +1823,8 @@ static void __init rcu_init_one(struct rcu_state *rsp)
cpustride *= rsp->levelspread[i];
rnp = rsp->level[i];
for (j = 0; j < rsp->levelcnt[i]; j++, rnp++) {
- if (rnp != rcu_get_root(rsp))
- spin_lock_init(&rnp->lock);
+ spin_lock_init(&rnp->lock);
+ lockdep_set_class(&rnp->lock, &rcu_node_class[i]);
rnp->gpnum = 0;
rnp->qsmask = 0;
rnp->qsmaskinit = 0;
@@ -1669,9 +1845,10 @@ static void __init rcu_init_one(struct rcu_state *rsp)
rnp->level = i;
INIT_LIST_HEAD(&rnp->blocked_tasks[0]);
INIT_LIST_HEAD(&rnp->blocked_tasks[1]);
+ INIT_LIST_HEAD(&rnp->blocked_tasks[2]);
+ INIT_LIST_HEAD(&rnp->blocked_tasks[3]);
}
}
- spin_lock_init(&rcu_get_root(rsp)->lock);
}
/*
@@ -1697,16 +1874,30 @@ do { \
} \
} while (0)
-void __init __rcu_init(void)
+void __init rcu_init(void)
{
+ int i;
+
rcu_bootup_announce();
#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n");
#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
+#if NUM_RCU_LVL_4 != 0
+ printk(KERN_INFO "Experimental four-level hierarchy is enabled.\n");
+#endif /* #if NUM_RCU_LVL_4 != 0 */
RCU_INIT_FLAVOR(&rcu_sched_state, rcu_sched_data);
RCU_INIT_FLAVOR(&rcu_bh_state, rcu_bh_data);
__rcu_init_preempt();
open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+
+ /*
+ * We don't need protection against CPU-hotplug here because
+ * this is called early in boot, before either interrupts
+ * or the scheduler are operational.
+ */
+ cpu_notifier(rcu_cpu_notify, 0);
+ for_each_online_cpu(i)
+ rcu_cpu_notify(NULL, CPU_UP_PREPARE, (void *)(long)i);
}
#include "rcutree_plugin.h"
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index b40ac5706040..d2a0046f63b2 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -34,10 +34,11 @@
* In practice, this has not been tested, so there is probably some
* bug somewhere.
*/
-#define MAX_RCU_LVLS 3
+#define MAX_RCU_LVLS 4
#define RCU_FANOUT (CONFIG_RCU_FANOUT)
#define RCU_FANOUT_SQ (RCU_FANOUT * RCU_FANOUT)
#define RCU_FANOUT_CUBE (RCU_FANOUT_SQ * RCU_FANOUT)
+#define RCU_FANOUT_FOURTH (RCU_FANOUT_CUBE * RCU_FANOUT)
#if NR_CPUS <= RCU_FANOUT
# define NUM_RCU_LVLS 1
@@ -45,23 +46,33 @@
# define NUM_RCU_LVL_1 (NR_CPUS)
# define NUM_RCU_LVL_2 0
# define NUM_RCU_LVL_3 0
+# define NUM_RCU_LVL_4 0
#elif NR_CPUS <= RCU_FANOUT_SQ
# define NUM_RCU_LVLS 2
# define NUM_RCU_LVL_0 1
# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
# define NUM_RCU_LVL_2 (NR_CPUS)
# define NUM_RCU_LVL_3 0
+# define NUM_RCU_LVL_4 0
#elif NR_CPUS <= RCU_FANOUT_CUBE
# define NUM_RCU_LVLS 3
# define NUM_RCU_LVL_0 1
# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_SQ)
# define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
# define NUM_RCU_LVL_3 NR_CPUS
+# define NUM_RCU_LVL_4 0
+#elif NR_CPUS <= RCU_FANOUT_FOURTH
+# define NUM_RCU_LVLS 4
+# define NUM_RCU_LVL_0 1
+# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_CUBE)
+# define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_SQ)
+# define NUM_RCU_LVL_3 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
+# define NUM_RCU_LVL_4 NR_CPUS
#else
# error "CONFIG_RCU_FANOUT insufficient for NR_CPUS"
#endif /* #if (NR_CPUS) <= RCU_FANOUT */
-#define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3)
+#define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4)
#define NUM_RCU_NODES (RCU_SUM - NR_CPUS)
/*
@@ -84,14 +95,21 @@ struct rcu_node {
long gpnum; /* Current grace period for this node. */
/* This will either be equal to or one */
/* behind the root rcu_node's gpnum. */
+ long completed; /* Last grace period completed for this node. */
+ /* This will either be equal to or one */
+ /* behind the root rcu_node's gpnum. */
unsigned long qsmask; /* CPUs or groups that need to switch in */
/* order for current grace period to proceed.*/
/* In leaf rcu_node, each bit corresponds to */
/* an rcu_data structure, otherwise, each */
/* bit corresponds to a child rcu_node */
/* structure. */
+ unsigned long expmask; /* Groups that have ->blocked_tasks[] */
+ /* elements that need to drain to allow the */
+ /* current expedited grace period to */
+ /* complete (only for TREE_PREEMPT_RCU). */
unsigned long qsmaskinit;
- /* Per-GP initialization for qsmask. */
+ /* Per-GP initial value for qsmask & expmask. */
unsigned long grpmask; /* Mask to apply to parent qsmask. */
/* Only one bit will be set in this mask. */
int grplo; /* lowest-numbered CPU or group here. */
@@ -99,7 +117,7 @@ struct rcu_node {
u8 grpnum; /* CPU/group number for next level up. */
u8 level; /* root is at level 0. */
struct rcu_node *parent;
- struct list_head blocked_tasks[2];
+ struct list_head blocked_tasks[4];
/* Tasks blocked in RCU read-side critsect. */
/* Grace period number (->gpnum) x blocked */
/* by tasks on the (x & 0x1) element of the */
@@ -114,6 +132,21 @@ struct rcu_node {
for ((rnp) = &(rsp)->node[0]; \
(rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++)
+/*
+ * Do a breadth-first scan of the non-leaf rcu_node structures for the
+ * specified rcu_state structure. Note that if there is a singleton
+ * rcu_node tree with but one rcu_node structure, this loop is a no-op.
+ */
+#define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \
+ for ((rnp) = &(rsp)->node[0]; \
+ (rnp) < (rsp)->level[NUM_RCU_LVLS - 1]; (rnp)++)
+
+/*
+ * Scan the leaves of the rcu_node hierarchy for the specified rcu_state
+ * structure. Note that if there is a singleton rcu_node tree with but
+ * one rcu_node structure, this loop -will- visit the rcu_node structure.
+ * It is still a leaf node, even if it is also the root node.
+ */
#define rcu_for_each_leaf_node(rsp, rnp) \
for ((rnp) = (rsp)->level[NUM_RCU_LVLS - 1]; \
(rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++)
@@ -167,6 +200,10 @@ struct rcu_data {
struct rcu_head *nxtlist;
struct rcu_head **nxttail[RCU_NEXT_SIZE];
long qlen; /* # of queued callbacks */
+ long qlen_last_fqs_check;
+ /* qlen at last check for QS forcing */
+ unsigned long n_force_qs_snap;
+ /* did other CPU force QS recently? */
long blimit; /* Upper limit on a processed batch */
#ifdef CONFIG_NO_HZ
@@ -197,13 +234,15 @@ struct rcu_data {
};
/* Values for signaled field in struct rcu_state. */
-#define RCU_GP_INIT 0 /* Grace period being initialized. */
-#define RCU_SAVE_DYNTICK 1 /* Need to scan dyntick state. */
-#define RCU_FORCE_QS 2 /* Need to force quiescent state. */
+#define RCU_GP_IDLE 0 /* No grace period in progress. */
+#define RCU_GP_INIT 1 /* Grace period being initialized. */
+#define RCU_SAVE_DYNTICK 2 /* Need to scan dyntick state. */
+#define RCU_SAVE_COMPLETED 3 /* Need to save rsp->completed. */
+#define RCU_FORCE_QS 4 /* Need to force quiescent state. */
#ifdef CONFIG_NO_HZ
#define RCU_SIGNAL_INIT RCU_SAVE_DYNTICK
#else /* #ifdef CONFIG_NO_HZ */
-#define RCU_SIGNAL_INIT RCU_FORCE_QS
+#define RCU_SIGNAL_INIT RCU_SAVE_COMPLETED
#endif /* #else #ifdef CONFIG_NO_HZ */
#define RCU_JIFFIES_TILL_FORCE_QS 3 /* for rsp->jiffies_force_qs */
@@ -241,7 +280,7 @@ struct rcu_state {
long gpnum; /* Current gp number. */
long completed; /* # of last completed gp. */
- /* End of fields guarded by root rcu_node's lock. */
+ /* End of fields guarded by root rcu_node's lock. */
spinlock_t onofflock; /* exclude on/offline and */
/* starting new GP. Also */
@@ -255,6 +294,8 @@ struct rcu_state {
long orphan_qlen; /* Number of orphaned cbs. */
spinlock_t fqslock; /* Only one task forcing */
/* quiescent states. */
+ long completed_fqs; /* Value of completed @ snap. */
+ /* Protected by fqslock. */
unsigned long jiffies_force_qs; /* Time at which to invoke */
/* force_quiescent_state(). */
unsigned long n_force_qs; /* Number of calls to */
@@ -269,11 +310,15 @@ struct rcu_state {
unsigned long jiffies_stall; /* Time at which to check */
/* for CPU stalls. */
#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
-#ifdef CONFIG_NO_HZ
- long dynticks_completed; /* Value of completed @ snap. */
-#endif /* #ifdef CONFIG_NO_HZ */
};
+/* Return values for rcu_preempt_offline_tasks(). */
+
+#define RCU_OFL_TASKS_NORM_GP 0x1 /* Tasks blocking normal */
+ /* GP were moved to root. */
+#define RCU_OFL_TASKS_EXP_GP 0x2 /* Tasks blocking expedited */
+ /* GP were moved to root. */
+
#ifdef RCU_TREE_NONCORE
/*
@@ -293,23 +338,30 @@ DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data);
#else /* #ifdef RCU_TREE_NONCORE */
/* Forward declarations for rcutree_plugin.h */
-static inline void rcu_bootup_announce(void);
+static void rcu_bootup_announce(void);
long rcu_batches_completed(void);
static void rcu_preempt_note_context_switch(int cpu);
static int rcu_preempted_readers(struct rcu_node *rnp);
+#ifdef CONFIG_HOTPLUG_CPU
+static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp,
+ unsigned long flags);
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
static void rcu_print_task_stall(struct rcu_node *rnp);
#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
#ifdef CONFIG_HOTPLUG_CPU
-static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
- struct rcu_node *rnp,
- struct rcu_data *rdp);
+static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
+ struct rcu_node *rnp,
+ struct rcu_data *rdp);
static void rcu_preempt_offline_cpu(int cpu);
#endif /* #ifdef CONFIG_HOTPLUG_CPU */
static void rcu_preempt_check_callbacks(int cpu);
static void rcu_preempt_process_callbacks(void);
void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU)
+static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp);
+#endif /* #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) */
static int rcu_preempt_pending(int cpu);
static int rcu_preempt_needs_cpu(int cpu);
static void __cpuinit rcu_preempt_init_percpu_data(int cpu);
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index c0cb783aa16a..37fbccdf41d5 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -24,16 +24,19 @@
* Paul E. McKenney <paulmck@linux.vnet.ibm.com>
*/
+#include <linux/delay.h>
#ifdef CONFIG_TREE_PREEMPT_RCU
struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt_state);
DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data);
+static int rcu_preempted_readers_exp(struct rcu_node *rnp);
+
/*
* Tell them what RCU they are running.
*/
-static inline void rcu_bootup_announce(void)
+static void __init rcu_bootup_announce(void)
{
printk(KERN_INFO
"Experimental preemptable hierarchical RCU implementation.\n");
@@ -67,7 +70,7 @@ EXPORT_SYMBOL_GPL(rcu_batches_completed);
static void rcu_preempt_qs(int cpu)
{
struct rcu_data *rdp = &per_cpu(rcu_preempt_data, cpu);
- rdp->passed_quiesc_completed = rdp->completed;
+ rdp->passed_quiesc_completed = rdp->gpnum - 1;
barrier();
rdp->passed_quiesc = 1;
}
@@ -157,14 +160,58 @@ EXPORT_SYMBOL_GPL(__rcu_read_lock);
*/
static int rcu_preempted_readers(struct rcu_node *rnp)
{
- return !list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]);
+ int phase = rnp->gpnum & 0x1;
+
+ return !list_empty(&rnp->blocked_tasks[phase]) ||
+ !list_empty(&rnp->blocked_tasks[phase + 2]);
+}
+
+/*
+ * Record a quiescent state for all tasks that were previously queued
+ * on the specified rcu_node structure and that were blocking the current
+ * RCU grace period. The caller must hold the specified rnp->lock with
+ * irqs disabled, and this lock is released upon return, but irqs remain
+ * disabled.
+ */
+static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags)
+ __releases(rnp->lock)
+{
+ unsigned long mask;
+ struct rcu_node *rnp_p;
+
+ if (rnp->qsmask != 0 || rcu_preempted_readers(rnp)) {
+ spin_unlock_irqrestore(&rnp->lock, flags);
+ return; /* Still need more quiescent states! */
+ }
+
+ rnp_p = rnp->parent;
+ if (rnp_p == NULL) {
+ /*
+ * Either there is only one rcu_node in the tree,
+ * or tasks were kicked up to root rcu_node due to
+ * CPUs going offline.
+ */
+ rcu_report_qs_rsp(&rcu_preempt_state, flags);
+ return;
+ }
+
+ /* Report up the rest of the hierarchy. */
+ mask = rnp->grpmask;
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
+ spin_lock(&rnp_p->lock); /* irqs already disabled. */
+ rcu_report_qs_rnp(mask, &rcu_preempt_state, rnp_p, flags);
}
+/*
+ * Handle special cases during rcu_read_unlock(), such as needing to
+ * notify RCU core processing or task having blocked during the RCU
+ * read-side critical section.
+ */
static void rcu_read_unlock_special(struct task_struct *t)
{
int empty;
+ int empty_exp;
unsigned long flags;
- unsigned long mask;
struct rcu_node *rnp;
int special;
@@ -207,36 +254,30 @@ static void rcu_read_unlock_special(struct task_struct *t)
spin_unlock(&rnp->lock); /* irqs remain disabled. */
}
empty = !rcu_preempted_readers(rnp);
+ empty_exp = !rcu_preempted_readers_exp(rnp);
+ smp_mb(); /* ensure expedited fastpath sees end of RCU c-s. */
list_del_init(&t->rcu_node_entry);
t->rcu_blocked_node = NULL;
/*
* If this was the last task on the current list, and if
* we aren't waiting on any CPUs, report the quiescent state.
- * Note that both cpu_quiet_msk_finish() and cpu_quiet_msk()
- * drop rnp->lock and restore irq.
+ * Note that rcu_report_unblock_qs_rnp() releases rnp->lock.
*/
- if (!empty && rnp->qsmask == 0 &&
- !rcu_preempted_readers(rnp)) {
- struct rcu_node *rnp_p;
-
- if (rnp->parent == NULL) {
- /* Only one rcu_node in the tree. */
- cpu_quiet_msk_finish(&rcu_preempt_state, flags);
- return;
- }
- /* Report up the rest of the hierarchy. */
- mask = rnp->grpmask;
+ if (empty)
spin_unlock_irqrestore(&rnp->lock, flags);
- rnp_p = rnp->parent;
- spin_lock_irqsave(&rnp_p->lock, flags);
- WARN_ON_ONCE(rnp->qsmask);
- cpu_quiet_msk(mask, &rcu_preempt_state, rnp_p, flags);
- return;
- }
- spin_unlock(&rnp->lock);
+ else
+ rcu_report_unblock_qs_rnp(rnp, flags);
+
+ /*
+ * If this was the last task on the expedited lists,
+ * then we need to report up the rcu_node hierarchy.
+ */
+ if (!empty_exp && !rcu_preempted_readers_exp(rnp))
+ rcu_report_exp_rnp(&rcu_preempt_state, rnp);
+ } else {
+ local_irq_restore(flags);
}
- local_irq_restore(flags);
}
/*
@@ -303,26 +344,34 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
* rcu_node. The reason for not just moving them to the immediate
* parent is to remove the need for rcu_read_unlock_special() to
* make more than two attempts to acquire the target rcu_node's lock.
+ * Returns true if there were tasks blocking the current RCU grace
+ * period.
+ *
+ * Returns 1 if there was previously a task blocking the current grace
+ * period on the specified rcu_node structure.
*
* The caller must hold rnp->lock with irqs disabled.
*/
-static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
- struct rcu_node *rnp,
- struct rcu_data *rdp)
+static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
+ struct rcu_node *rnp,
+ struct rcu_data *rdp)
{
int i;
struct list_head *lp;
struct list_head *lp_root;
+ int retval = 0;
struct rcu_node *rnp_root = rcu_get_root(rsp);
struct task_struct *tp;
if (rnp == rnp_root) {
WARN_ONCE(1, "Last CPU thought to be offlined?");
- return; /* Shouldn't happen: at least one CPU online. */
+ return 0; /* Shouldn't happen: at least one CPU online. */
}
WARN_ON_ONCE(rnp != rdp->mynode &&
(!list_empty(&rnp->blocked_tasks[0]) ||
- !list_empty(&rnp->blocked_tasks[1])));
+ !list_empty(&rnp->blocked_tasks[1]) ||
+ !list_empty(&rnp->blocked_tasks[2]) ||
+ !list_empty(&rnp->blocked_tasks[3])));
/*
* Move tasks up to root rcu_node. Rely on the fact that the
@@ -330,7 +379,11 @@ static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
* rcu_nodes in terms of gp_num value. This fact allows us to
* move the blocked_tasks[] array directly, element by element.
*/
- for (i = 0; i < 2; i++) {
+ if (rcu_preempted_readers(rnp))
+ retval |= RCU_OFL_TASKS_NORM_GP;
+ if (rcu_preempted_readers_exp(rnp))
+ retval |= RCU_OFL_TASKS_EXP_GP;
+ for (i = 0; i < 4; i++) {
lp = &rnp->blocked_tasks[i];
lp_root = &rnp_root->blocked_tasks[i];
while (!list_empty(lp)) {
@@ -342,6 +395,7 @@ static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
spin_unlock(&rnp_root->lock); /* irqs remain disabled */
}
}
+ return retval;
}
/*
@@ -392,6 +446,186 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
}
EXPORT_SYMBOL_GPL(call_rcu);
+/**
+ * synchronize_rcu - wait until a grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full grace
+ * period has elapsed, in other words after all currently executing RCU
+ * read-side critical sections have completed. RCU read-side critical
+ * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
+ * and may be nested.
+ */
+void synchronize_rcu(void)
+{
+ struct rcu_synchronize rcu;
+
+ if (!rcu_scheduler_active)
+ return;
+
+ init_completion(&rcu.completion);
+ /* Will wake me after RCU finished. */
+ call_rcu(&rcu.head, wakeme_after_rcu);
+ /* Wait for it. */
+ wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu);
+
+static DECLARE_WAIT_QUEUE_HEAD(sync_rcu_preempt_exp_wq);
+static long sync_rcu_preempt_exp_count;
+static DEFINE_MUTEX(sync_rcu_preempt_exp_mutex);
+
+/*
+ * Return non-zero if there are any tasks in RCU read-side critical
+ * sections blocking the current preemptible-RCU expedited grace period.
+ * If there is no preemptible-RCU expedited grace period currently in
+ * progress, returns zero unconditionally.
+ */
+static int rcu_preempted_readers_exp(struct rcu_node *rnp)
+{
+ return !list_empty(&rnp->blocked_tasks[2]) ||
+ !list_empty(&rnp->blocked_tasks[3]);
+}
+
+/*
+ * return non-zero if there is no RCU expedited grace period in progress
+ * for the specified rcu_node structure, in other words, if all CPUs and
+ * tasks covered by the specified rcu_node structure have done their bit
+ * for the current expedited grace period. Works only for preemptible
+ * RCU -- other RCU implementation use other means.
+ *
+ * Caller must hold sync_rcu_preempt_exp_mutex.
+ */
+static int sync_rcu_preempt_exp_done(struct rcu_node *rnp)
+{
+ return !rcu_preempted_readers_exp(rnp) &&
+ ACCESS_ONCE(rnp->expmask) == 0;
+}
+
+/*
+ * Report the exit from RCU read-side critical section for the last task
+ * that queued itself during or before the current expedited preemptible-RCU
+ * grace period. This event is reported either to the rcu_node structure on
+ * which the task was queued or to one of that rcu_node structure's ancestors,
+ * recursively up the tree. (Calm down, calm down, we do the recursion
+ * iteratively!)
+ *
+ * Caller must hold sync_rcu_preempt_exp_mutex.
+ */
+static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+ unsigned long flags;
+ unsigned long mask;
+
+ spin_lock_irqsave(&rnp->lock, flags);
+ for (;;) {
+ if (!sync_rcu_preempt_exp_done(rnp))
+ break;
+ if (rnp->parent == NULL) {
+ wake_up(&sync_rcu_preempt_exp_wq);
+ break;
+ }
+ mask = rnp->grpmask;
+ spin_unlock(&rnp->lock); /* irqs remain disabled */
+ rnp = rnp->parent;
+ spin_lock(&rnp->lock); /* irqs already disabled */
+ rnp->expmask &= ~mask;
+ }
+ spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+/*
+ * Snapshot the tasks blocking the newly started preemptible-RCU expedited
+ * grace period for the specified rcu_node structure. If there are no such
+ * tasks, report it up the rcu_node hierarchy.
+ *
+ * Caller must hold sync_rcu_preempt_exp_mutex and rsp->onofflock.
+ */
+static void
+sync_rcu_preempt_exp_init(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+ int must_wait;
+
+ spin_lock(&rnp->lock); /* irqs already disabled */
+ list_splice_init(&rnp->blocked_tasks[0], &rnp->blocked_tasks[2]);
+ list_splice_init(&rnp->blocked_tasks[1], &rnp->blocked_tasks[3]);
+ must_wait = rcu_preempted_readers_exp(rnp);
+ spin_unlock(&rnp->lock); /* irqs remain disabled */
+ if (!must_wait)
+ rcu_report_exp_rnp(rsp, rnp);
+}
+
+/*
+ * Wait for an rcu-preempt grace period, but expedite it. The basic idea
+ * is to invoke synchronize_sched_expedited() to push all the tasks to
+ * the ->blocked_tasks[] lists, move all entries from the first set of
+ * ->blocked_tasks[] lists to the second set, and finally wait for this
+ * second set to drain.
+ */
+void synchronize_rcu_expedited(void)
+{
+ unsigned long flags;
+ struct rcu_node *rnp;
+ struct rcu_state *rsp = &rcu_preempt_state;
+ long snap;
+ int trycount = 0;
+
+ smp_mb(); /* Caller's modifications seen first by other CPUs. */
+ snap = ACCESS_ONCE(sync_rcu_preempt_exp_count) + 1;
+ smp_mb(); /* Above access cannot bleed into critical section. */
+
+ /*
+ * Acquire lock, falling back to synchronize_rcu() if too many
+ * lock-acquisition failures. Of course, if someone does the
+ * expedited grace period for us, just leave.
+ */
+ while (!mutex_trylock(&sync_rcu_preempt_exp_mutex)) {
+ if (trycount++ < 10)
+ udelay(trycount * num_online_cpus());
+ else {
+ synchronize_rcu();
+ return;
+ }
+ if ((ACCESS_ONCE(sync_rcu_preempt_exp_count) - snap) > 0)
+ goto mb_ret; /* Others did our work for us. */
+ }
+ if ((ACCESS_ONCE(sync_rcu_preempt_exp_count) - snap) > 0)
+ goto unlock_mb_ret; /* Others did our work for us. */
+
+ /* force all RCU readers onto blocked_tasks[]. */
+ synchronize_sched_expedited();
+
+ spin_lock_irqsave(&rsp->onofflock, flags);
+
+ /* Initialize ->expmask for all non-leaf rcu_node structures. */
+ rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) {
+ spin_lock(&rnp->lock); /* irqs already disabled. */
+ rnp->expmask = rnp->qsmaskinit;
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
+ }
+
+ /* Snapshot current state of ->blocked_tasks[] lists. */
+ rcu_for_each_leaf_node(rsp, rnp)
+ sync_rcu_preempt_exp_init(rsp, rnp);
+ if (NUM_RCU_NODES > 1)
+ sync_rcu_preempt_exp_init(rsp, rcu_get_root(rsp));
+
+ spin_unlock_irqrestore(&rsp->onofflock, flags);
+
+ /* Wait for snapshotted ->blocked_tasks[] lists to drain. */
+ rnp = rcu_get_root(rsp);
+ wait_event(sync_rcu_preempt_exp_wq,
+ sync_rcu_preempt_exp_done(rnp));
+
+ /* Clean up and exit. */
+ smp_mb(); /* ensure expedited GP seen before counter increment. */
+ ACCESS_ONCE(sync_rcu_preempt_exp_count)++;
+unlock_mb_ret:
+ mutex_unlock(&sync_rcu_preempt_exp_mutex);
+mb_ret:
+ smp_mb(); /* ensure subsequent action seen after grace period. */
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
+
/*
* Check to see if there is any immediate preemptable-RCU-related work
* to be done.
@@ -464,7 +698,7 @@ void exit_rcu(void)
/*
* Tell them what RCU they are running.
*/
-static inline void rcu_bootup_announce(void)
+static void __init rcu_bootup_announce(void)
{
printk(KERN_INFO "Hierarchical RCU implementation.\n");
}
@@ -495,6 +729,16 @@ static int rcu_preempted_readers(struct rcu_node *rnp)
return 0;
}
+#ifdef CONFIG_HOTPLUG_CPU
+
+/* Because preemptible RCU does not exist, no quieting of tasks. */
+static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags)
+{
+ spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
/*
@@ -521,12 +765,15 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
/*
* Because preemptable RCU does not exist, it never needs to migrate
- * tasks that were blocked within RCU read-side critical sections.
+ * tasks that were blocked within RCU read-side critical sections, and
+ * such non-existent tasks cannot possibly have been blocking the current
+ * grace period.
*/
-static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
- struct rcu_node *rnp,
- struct rcu_data *rdp)
+static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
+ struct rcu_node *rnp,
+ struct rcu_data *rdp)
{
+ return 0;
}
/*
@@ -565,6 +812,30 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
EXPORT_SYMBOL_GPL(call_rcu);
/*
+ * Wait for an rcu-preempt grace period, but make it happen quickly.
+ * But because preemptable RCU does not exist, map to rcu-sched.
+ */
+void synchronize_rcu_expedited(void)
+{
+ synchronize_sched_expedited();
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * Because preemptable RCU does not exist, there is never any need to
+ * report on tasks preempted in RCU read-side critical sections during
+ * expedited RCU grace periods.
+ */
+static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+ return;
+}
+
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
+/*
* Because preemptable RCU does not exist, it never has any work to do.
*/
static int rcu_preempt_pending(int cpu)
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
index 4b31c779e62e..9d2c88423b31 100644
--- a/kernel/rcutree_trace.c
+++ b/kernel/rcutree_trace.c
@@ -155,12 +155,15 @@ static const struct file_operations rcudata_csv_fops = {
static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
{
+ long gpnum;
int level = 0;
+ int phase;
struct rcu_node *rnp;
+ gpnum = rsp->gpnum;
seq_printf(m, "c=%ld g=%ld s=%d jfq=%ld j=%x "
"nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld\n",
- rsp->completed, rsp->gpnum, rsp->signaled,
+ rsp->completed, gpnum, rsp->signaled,
(long)(rsp->jiffies_force_qs - jiffies),
(int)(jiffies & 0xffff),
rsp->n_force_qs, rsp->n_force_qs_ngp,
@@ -171,8 +174,13 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
seq_puts(m, "\n");
level = rnp->level;
}
- seq_printf(m, "%lx/%lx %d:%d ^%d ",
+ phase = gpnum & 0x1;
+ seq_printf(m, "%lx/%lx %c%c>%c%c %d:%d ^%d ",
rnp->qsmask, rnp->qsmaskinit,
+ "T."[list_empty(&rnp->blocked_tasks[phase])],
+ "E."[list_empty(&rnp->blocked_tasks[phase + 2])],
+ "T."[list_empty(&rnp->blocked_tasks[!phase])],
+ "E."[list_empty(&rnp->blocked_tasks[!phase + 2])],
rnp->grplo, rnp->grphi, rnp->grpnum);
}
seq_puts(m, "\n");
diff --git a/kernel/sched.c b/kernel/sched.c
index 8d25be06db62..aa31244caa9f 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -309,6 +309,8 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct rt_rq, init_rt_rq);
*/
static DEFINE_SPINLOCK(task_group_lock);
+#ifdef CONFIG_FAIR_GROUP_SCHED
+
#ifdef CONFIG_SMP
static int root_task_group_empty(void)
{
@@ -316,7 +318,6 @@ static int root_task_group_empty(void)
}
#endif
-#ifdef CONFIG_FAIR_GROUP_SCHED
#ifdef CONFIG_USER_SCHED
# define INIT_TASK_GROUP_LOAD (2*NICE_0_LOAD)
#else /* !CONFIG_USER_SCHED */
@@ -534,14 +535,12 @@ struct rq {
#define CPU_LOAD_IDX_MAX 5
unsigned long cpu_load[CPU_LOAD_IDX_MAX];
#ifdef CONFIG_NO_HZ
- unsigned long last_tick_seen;
unsigned char in_nohz_recently;
#endif
/* capture load from *all* tasks on this cpu: */
struct load_weight load;
unsigned long nr_load_updates;
u64 nr_switches;
- u64 nr_migrations_in;
struct cfs_rq cfs;
struct rt_rq rt;
@@ -590,6 +589,8 @@ struct rq {
u64 rt_avg;
u64 age_stamp;
+ u64 idle_stamp;
+ u64 avg_idle;
#endif
/* calc_load related fields */
@@ -676,6 +677,7 @@ inline void update_rq_clock(struct rq *rq)
/**
* runqueue_is_locked
+ * @cpu: the processor in question.
*
* Returns true if the current cpu runqueue is locked.
* This interface allows printk to be called with the runqueue lock
@@ -770,7 +772,7 @@ sched_feat_write(struct file *filp, const char __user *ubuf,
if (!sched_feat_names[i])
return -EINVAL;
- filp->f_pos += cnt;
+ *ppos += cnt;
return cnt;
}
@@ -1563,11 +1565,7 @@ static unsigned long cpu_avg_load_per_task(int cpu)
#ifdef CONFIG_FAIR_GROUP_SCHED
-struct update_shares_data {
- unsigned long rq_weight[NR_CPUS];
-};
-
-static DEFINE_PER_CPU(struct update_shares_data, update_shares_data);
+static __read_mostly unsigned long *update_shares_data;
static void __set_se_shares(struct sched_entity *se, unsigned long shares);
@@ -1577,12 +1575,12 @@ static void __set_se_shares(struct sched_entity *se, unsigned long shares);
static void update_group_shares_cpu(struct task_group *tg, int cpu,
unsigned long sd_shares,
unsigned long sd_rq_weight,
- struct update_shares_data *usd)
+ unsigned long *usd_rq_weight)
{
unsigned long shares, rq_weight;
int boost = 0;
- rq_weight = usd->rq_weight[cpu];
+ rq_weight = usd_rq_weight[cpu];
if (!rq_weight) {
boost = 1;
rq_weight = NICE_0_LOAD;
@@ -1617,7 +1615,7 @@ static void update_group_shares_cpu(struct task_group *tg, int cpu,
static int tg_shares_up(struct task_group *tg, void *data)
{
unsigned long weight, rq_weight = 0, shares = 0;
- struct update_shares_data *usd;
+ unsigned long *usd_rq_weight;
struct sched_domain *sd = data;
unsigned long flags;
int i;
@@ -1626,11 +1624,11 @@ static int tg_shares_up(struct task_group *tg, void *data)
return 0;
local_irq_save(flags);
- usd = &__get_cpu_var(update_shares_data);
+ usd_rq_weight = per_cpu_ptr(update_shares_data, smp_processor_id());
for_each_cpu(i, sched_domain_span(sd)) {
weight = tg->cfs_rq[i]->load.weight;
- usd->rq_weight[i] = weight;
+ usd_rq_weight[i] = weight;
/*
* If there are currently no tasks on the cpu pretend there
@@ -1651,7 +1649,7 @@ static int tg_shares_up(struct task_group *tg, void *data)
shares = tg->shares;
for_each_cpu(i, sched_domain_span(sd))
- update_group_shares_cpu(tg, i, shares, rq_weight, usd);
+ update_group_shares_cpu(tg, i, shares, rq_weight, usd_rq_weight);
local_irq_restore(flags);
@@ -1995,6 +1993,39 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p,
p->sched_class->prio_changed(rq, p, oldprio, running);
}
+/**
+ * kthread_bind - bind a just-created kthread to a cpu.
+ * @p: thread created by kthread_create().
+ * @cpu: cpu (might not be online, must be possible) for @k to run on.
+ *
+ * Description: This function is equivalent to set_cpus_allowed(),
+ * except that @cpu doesn't need to be online, and the thread must be
+ * stopped (i.e., just returned from kthread_create()).
+ *
+ * Function lives here instead of kthread.c because it messes with
+ * scheduler internals which require locking.
+ */
+void kthread_bind(struct task_struct *p, unsigned int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+ unsigned long flags;
+
+ /* Must have done schedule() in kthread() before we set_task_cpu */
+ if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) {
+ WARN_ON(1);
+ return;
+ }
+
+ spin_lock_irqsave(&rq->lock, flags);
+ update_rq_clock(rq);
+ set_task_cpu(p, cpu);
+ p->cpus_allowed = cpumask_of_cpu(cpu);
+ p->rt.nr_cpus_allowed = 1;
+ p->flags |= PF_THREAD_BOUND;
+ spin_unlock_irqrestore(&rq->lock, flags);
+}
+EXPORT_SYMBOL(kthread_bind);
+
#ifdef CONFIG_SMP
/*
* Is this task likely cache-hot:
@@ -2007,7 +2038,7 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
/*
* Buddy candidates are cache hot:
*/
- if (sched_feat(CACHE_HOT_BUDDY) &&
+ if (sched_feat(CACHE_HOT_BUDDY) && this_rq()->nr_running &&
(&p->se == cfs_rq_of(&p->se)->next ||
&p->se == cfs_rq_of(&p->se)->last))
return 1;
@@ -2048,7 +2079,6 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
#endif
if (old_cpu != new_cpu) {
p->se.nr_migrations++;
- new_rq->nr_migrations_in++;
#ifdef CONFIG_SCHEDSTATS
if (task_hot(p, old_rq->clock, NULL))
schedstat_inc(p, se.nr_forced2_migrations);
@@ -2085,6 +2115,7 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
* it is sufficient to simply update the task's cpu field.
*/
if (!p->se.on_rq && !task_running(rq, p)) {
+ update_rq_clock(rq);
set_task_cpu(p, dest_cpu);
return 0;
}
@@ -2311,7 +2342,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
{
int cpu, orig_cpu, this_cpu, success = 0;
unsigned long flags;
- struct rq *rq;
+ struct rq *rq, *orig_rq;
if (!sched_feat(SYNC_WAKEUPS))
wake_flags &= ~WF_SYNC;
@@ -2319,7 +2350,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
this_cpu = get_cpu();
smp_wmb();
- rq = task_rq_lock(p, &flags);
+ rq = orig_rq = task_rq_lock(p, &flags);
update_rq_clock(rq);
if (!(p->state & state))
goto out;
@@ -2346,10 +2377,15 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
task_rq_unlock(rq, &flags);
cpu = p->sched_class->select_task_rq(p, SD_BALANCE_WAKE, wake_flags);
- if (cpu != orig_cpu)
+ if (cpu != orig_cpu) {
+ local_irq_save(flags);
+ rq = cpu_rq(cpu);
+ update_rq_clock(rq);
set_task_cpu(p, cpu);
-
+ local_irq_restore(flags);
+ }
rq = task_rq_lock(p, &flags);
+
WARN_ON(p->state != TASK_WAKING);
cpu = task_cpu(p);
@@ -2406,6 +2442,17 @@ out_running:
#ifdef CONFIG_SMP
if (p->sched_class->task_wake_up)
p->sched_class->task_wake_up(rq, p);
+
+ if (unlikely(rq->idle_stamp)) {
+ u64 delta = rq->clock - rq->idle_stamp;
+ u64 max = 2*sysctl_sched_migration_cost;
+
+ if (delta > max)
+ rq->avg_idle = max;
+ else
+ update_avg(&rq->avg_idle, delta);
+ rq->idle_stamp = 0;
+ }
#endif
out:
task_rq_unlock(rq, &flags);
@@ -2511,6 +2558,7 @@ static void __sched_fork(struct task_struct *p)
void sched_fork(struct task_struct *p, int clone_flags)
{
int cpu = get_cpu();
+ unsigned long flags;
__sched_fork(p);
@@ -2547,7 +2595,10 @@ void sched_fork(struct task_struct *p, int clone_flags)
#ifdef CONFIG_SMP
cpu = p->sched_class->select_task_rq(p, SD_BALANCE_FORK, 0);
#endif
+ local_irq_save(flags);
+ update_rq_clock(cpu_rq(cpu));
set_task_cpu(p, cpu);
+ local_irq_restore(flags);
#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
if (likely(sched_info_on()))
@@ -2814,14 +2865,14 @@ context_switch(struct rq *rq, struct task_struct *prev,
*/
arch_start_context_switch(prev);
- if (unlikely(!mm)) {
+ if (likely(!mm)) {
next->active_mm = oldmm;
atomic_inc(&oldmm->mm_count);
enter_lazy_tlb(oldmm, next);
} else
switch_mm(oldmm, mm, next);
- if (unlikely(!prev->mm)) {
+ if (likely(!prev->mm)) {
prev->active_mm = NULL;
rq->prev_mm = oldmm;
}
@@ -2984,15 +3035,6 @@ static void calc_load_account_active(struct rq *this_rq)
}
/*
- * Externally visible per-cpu scheduler statistics:
- * cpu_nr_migrations(cpu) - number of migrations into that cpu
- */
-u64 cpu_nr_migrations(int cpu)
-{
- return cpu_rq(cpu)->nr_migrations_in;
-}
-
-/*
* Update rq->cpu_load[] statistics. This function is usually called every
* scheduler tick (TICK_NSEC).
*/
@@ -3656,6 +3698,7 @@ static void update_group_power(struct sched_domain *sd, int cpu)
/**
* update_sg_lb_stats - Update sched_group's statistics for load balancing.
+ * @sd: The sched_domain whose statistics are to be updated.
* @group: sched_group whose statistics are to be updated.
* @this_cpu: Cpu for which load balance is currently performed.
* @idle: Idle status of this_cpu
@@ -4091,7 +4134,7 @@ static int load_balance(int this_cpu, struct rq *this_rq,
unsigned long flags;
struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask);
- cpumask_setall(cpus);
+ cpumask_copy(cpus, cpu_online_mask);
/*
* When power savings policy is enabled for the parent domain, idle
@@ -4254,7 +4297,7 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
int all_pinned = 0;
struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask);
- cpumask_setall(cpus);
+ cpumask_copy(cpus, cpu_online_mask);
/*
* When power savings policy is enabled for the parent domain, idle
@@ -4394,6 +4437,11 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
int pulled_task = 0;
unsigned long next_balance = jiffies + HZ;
+ this_rq->idle_stamp = this_rq->clock;
+
+ if (this_rq->avg_idle < sysctl_sched_migration_cost)
+ return;
+
for_each_domain(this_cpu, sd) {
unsigned long interval;
@@ -4408,8 +4456,10 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
interval = msecs_to_jiffies(sd->balance_interval);
if (time_after(next_balance, sd->last_balance + interval))
next_balance = sd->last_balance + interval;
- if (pulled_task)
+ if (pulled_task) {
+ this_rq->idle_stamp = 0;
break;
+ }
}
if (pulled_task || time_after(jiffies, this_rq->next_balance)) {
/*
@@ -5011,8 +5061,13 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime,
p->gtime = cputime_add(p->gtime, cputime);
/* Add guest time to cpustat. */
- cpustat->user = cputime64_add(cpustat->user, tmp);
- cpustat->guest = cputime64_add(cpustat->guest, tmp);
+ if (TASK_NICE(p) > 0) {
+ cpustat->nice = cputime64_add(cpustat->nice, tmp);
+ cpustat->guest_nice = cputime64_add(cpustat->guest_nice, tmp);
+ } else {
+ cpustat->user = cputime64_add(cpustat->user, tmp);
+ cpustat->guest = cputime64_add(cpustat->guest, tmp);
+ }
}
/*
@@ -5127,60 +5182,86 @@ void account_idle_ticks(unsigned long ticks)
* Use precise platform statistics if available:
*/
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-cputime_t task_utime(struct task_struct *p)
+void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
{
- return p->utime;
+ *ut = p->utime;
+ *st = p->stime;
}
-cputime_t task_stime(struct task_struct *p)
+void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
{
- return p->stime;
+ struct task_cputime cputime;
+
+ thread_group_cputime(p, &cputime);
+
+ *ut = cputime.utime;
+ *st = cputime.stime;
}
#else
-cputime_t task_utime(struct task_struct *p)
+
+#ifndef nsecs_to_cputime
+# define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs)
+#endif
+
+void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
{
- clock_t utime = cputime_to_clock_t(p->utime),
- total = utime + cputime_to_clock_t(p->stime);
- u64 temp;
+ cputime_t rtime, utime = p->utime, total = cputime_add(utime, p->stime);
/*
* Use CFS's precise accounting:
*/
- temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime);
+ rtime = nsecs_to_cputime(p->se.sum_exec_runtime);
if (total) {
- temp *= utime;
+ u64 temp;
+
+ temp = (u64)(rtime * utime);
do_div(temp, total);
- }
- utime = (clock_t)temp;
+ utime = (cputime_t)temp;
+ } else
+ utime = rtime;
+
+ /*
+ * Compare with previous values, to keep monotonicity:
+ */
+ p->prev_utime = max(p->prev_utime, utime);
+ p->prev_stime = max(p->prev_stime, cputime_sub(rtime, p->prev_utime));
- p->prev_utime = max(p->prev_utime, clock_t_to_cputime(utime));
- return p->prev_utime;
+ *ut = p->prev_utime;
+ *st = p->prev_stime;
}
-cputime_t task_stime(struct task_struct *p)
+/*
+ * Must be called with siglock held.
+ */
+void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
{
- clock_t stime;
+ struct signal_struct *sig = p->signal;
+ struct task_cputime cputime;
+ cputime_t rtime, utime, total;
- /*
- * Use CFS's precise accounting. (we subtract utime from
- * the total, to make sure the total observed by userspace
- * grows monotonically - apps rely on that):
- */
- stime = nsec_to_clock_t(p->se.sum_exec_runtime) -
- cputime_to_clock_t(task_utime(p));
+ thread_group_cputime(p, &cputime);
- if (stime >= 0)
- p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime));
+ total = cputime_add(cputime.utime, cputime.stime);
+ rtime = nsecs_to_cputime(cputime.sum_exec_runtime);
- return p->prev_stime;
-}
-#endif
+ if (total) {
+ u64 temp;
-inline cputime_t task_gtime(struct task_struct *p)
-{
- return p->gtime;
+ temp = (u64)(rtime * cputime.utime);
+ do_div(temp, total);
+ utime = (cputime_t)temp;
+ } else
+ utime = rtime;
+
+ sig->prev_utime = max(sig->prev_utime, utime);
+ sig->prev_stime = max(sig->prev_stime,
+ cputime_sub(rtime, sig->prev_utime));
+
+ *ut = sig->prev_utime;
+ *st = sig->prev_stime;
}
+#endif
/*
* This function gets called by the timer code, with HZ frequency.
@@ -5446,7 +5527,7 @@ need_resched_nonpreemptible:
}
EXPORT_SYMBOL(schedule);
-#ifdef CONFIG_SMP
+#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
/*
* Look out! "owner" is an entirely speculative pointer
* access and not reliable.
@@ -6140,22 +6221,14 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
BUG_ON(p->se.on_rq);
p->policy = policy;
- switch (p->policy) {
- case SCHED_NORMAL:
- case SCHED_BATCH:
- case SCHED_IDLE:
- p->sched_class = &fair_sched_class;
- break;
- case SCHED_FIFO:
- case SCHED_RR:
- p->sched_class = &rt_sched_class;
- break;
- }
-
p->rt_priority = prio;
p->normal_prio = normal_prio(p);
/* we are holding p->pi_lock already */
p->prio = rt_mutex_getprio(p);
+ if (rt_prio(p->prio))
+ p->sched_class = &rt_sched_class;
+ else
+ p->sched_class = &fair_sched_class;
set_load_weight(p);
}
@@ -6900,7 +6973,7 @@ void show_state_filter(unsigned long state_filter)
/*
* Only show locks if all tasks are dumped:
*/
- if (state_filter == -1)
+ if (!state_filter)
debug_show_all_locks();
}
@@ -7705,6 +7778,16 @@ early_initcall(migration_init);
#ifdef CONFIG_SCHED_DEBUG
+static __read_mostly int sched_domain_debug_enabled;
+
+static int __init sched_domain_debug_setup(char *str)
+{
+ sched_domain_debug_enabled = 1;
+
+ return 0;
+}
+early_param("sched_debug", sched_domain_debug_setup);
+
static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level,
struct cpumask *groupmask)
{
@@ -7791,6 +7874,9 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu)
cpumask_var_t groupmask;
int level = 0;
+ if (!sched_domain_debug_enabled)
+ return;
+
if (!sd) {
printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu);
return;
@@ -7870,6 +7956,8 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent)
static void free_rootdomain(struct root_domain *rd)
{
+ synchronize_sched();
+
cpupri_cleanup(&rd->cpupri);
free_cpumask_var(rd->rto_mask);
@@ -8010,6 +8098,7 @@ static cpumask_var_t cpu_isolated_map;
/* Setup the mask of cpus configured for isolated domains */
static int __init isolated_cpu_setup(char *str)
{
+ alloc_bootmem_cpumask_var(&cpu_isolated_map);
cpulist_parse(str, cpu_isolated_map);
return 1;
}
@@ -8846,7 +8935,7 @@ static int build_sched_domains(const struct cpumask *cpu_map)
return __build_sched_domains(cpu_map, NULL);
}
-static struct cpumask *doms_cur; /* current sched domains */
+static cpumask_var_t *doms_cur; /* current sched domains */
static int ndoms_cur; /* number of sched domains in 'doms_cur' */
static struct sched_domain_attr *dattr_cur;
/* attribues of custom domains in 'doms_cur' */
@@ -8868,6 +8957,31 @@ int __attribute__((weak)) arch_update_cpu_topology(void)
return 0;
}
+cpumask_var_t *alloc_sched_domains(unsigned int ndoms)
+{
+ int i;
+ cpumask_var_t *doms;
+
+ doms = kmalloc(sizeof(*doms) * ndoms, GFP_KERNEL);
+ if (!doms)
+ return NULL;
+ for (i = 0; i < ndoms; i++) {
+ if (!alloc_cpumask_var(&doms[i], GFP_KERNEL)) {
+ free_sched_domains(doms, i);
+ return NULL;
+ }
+ }
+ return doms;
+}
+
+void free_sched_domains(cpumask_var_t doms[], unsigned int ndoms)
+{
+ unsigned int i;
+ for (i = 0; i < ndoms; i++)
+ free_cpumask_var(doms[i]);
+ kfree(doms);
+}
+
/*
* Set up scheduler domains and groups. Callers must hold the hotplug lock.
* For now this just excludes isolated cpus, but could be used to
@@ -8879,12 +8993,12 @@ static int arch_init_sched_domains(const struct cpumask *cpu_map)
arch_update_cpu_topology();
ndoms_cur = 1;
- doms_cur = kmalloc(cpumask_size(), GFP_KERNEL);
+ doms_cur = alloc_sched_domains(ndoms_cur);
if (!doms_cur)
- doms_cur = fallback_doms;
- cpumask_andnot(doms_cur, cpu_map, cpu_isolated_map);
+ doms_cur = &fallback_doms;
+ cpumask_andnot(doms_cur[0], cpu_map, cpu_isolated_map);
dattr_cur = NULL;
- err = build_sched_domains(doms_cur);
+ err = build_sched_domains(doms_cur[0]);
register_sched_domain_sysctl();
return err;
@@ -8934,19 +9048,19 @@ static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur,
* doms_new[] to the current sched domain partitioning, doms_cur[].
* It destroys each deleted domain and builds each new domain.
*
- * 'doms_new' is an array of cpumask's of length 'ndoms_new'.
+ * 'doms_new' is an array of cpumask_var_t's of length 'ndoms_new'.
* The masks don't intersect (don't overlap.) We should setup one
* sched domain for each mask. CPUs not in any of the cpumasks will
* not be load balanced. If the same cpumask appears both in the
* current 'doms_cur' domains and in the new 'doms_new', we can leave
* it as it is.
*
- * The passed in 'doms_new' should be kmalloc'd. This routine takes
- * ownership of it and will kfree it when done with it. If the caller
- * failed the kmalloc call, then it can pass in doms_new == NULL &&
- * ndoms_new == 1, and partition_sched_domains() will fallback to
- * the single partition 'fallback_doms', it also forces the domains
- * to be rebuilt.
+ * The passed in 'doms_new' should be allocated using
+ * alloc_sched_domains. This routine takes ownership of it and will
+ * free_sched_domains it when done with it. If the caller failed the
+ * alloc call, then it can pass in doms_new == NULL && ndoms_new == 1,
+ * and partition_sched_domains() will fallback to the single partition
+ * 'fallback_doms', it also forces the domains to be rebuilt.
*
* If doms_new == NULL it will be replaced with cpu_online_mask.
* ndoms_new == 0 is a special case for destroying existing domains,
@@ -8954,8 +9068,7 @@ static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur,
*
* Call with hotplug lock held
*/
-/* FIXME: Change to struct cpumask *doms_new[] */
-void partition_sched_domains(int ndoms_new, struct cpumask *doms_new,
+void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
struct sched_domain_attr *dattr_new)
{
int i, j, n;
@@ -8974,40 +9087,40 @@ void partition_sched_domains(int ndoms_new, struct cpumask *doms_new,
/* Destroy deleted domains */
for (i = 0; i < ndoms_cur; i++) {
for (j = 0; j < n && !new_topology; j++) {
- if (cpumask_equal(&doms_cur[i], &doms_new[j])
+ if (cpumask_equal(doms_cur[i], doms_new[j])
&& dattrs_equal(dattr_cur, i, dattr_new, j))
goto match1;
}
/* no match - a current sched domain not in new doms_new[] */
- detach_destroy_domains(doms_cur + i);
+ detach_destroy_domains(doms_cur[i]);
match1:
;
}
if (doms_new == NULL) {
ndoms_cur = 0;
- doms_new = fallback_doms;
- cpumask_andnot(&doms_new[0], cpu_online_mask, cpu_isolated_map);
+ doms_new = &fallback_doms;
+ cpumask_andnot(doms_new[0], cpu_online_mask, cpu_isolated_map);
WARN_ON_ONCE(dattr_new);
}
/* Build new domains */
for (i = 0; i < ndoms_new; i++) {
for (j = 0; j < ndoms_cur && !new_topology; j++) {
- if (cpumask_equal(&doms_new[i], &doms_cur[j])
+ if (cpumask_equal(doms_new[i], doms_cur[j])
&& dattrs_equal(dattr_new, i, dattr_cur, j))
goto match2;
}
/* no match - add a new doms_new */
- __build_sched_domains(doms_new + i,
+ __build_sched_domains(doms_new[i],
dattr_new ? dattr_new + i : NULL);
match2:
;
}
/* Remember the new sched domains */
- if (doms_cur != fallback_doms)
- kfree(doms_cur);
+ if (doms_cur != &fallback_doms)
+ free_sched_domains(doms_cur, ndoms_cur);
kfree(dattr_cur); /* kfree(NULL) is safe */
doms_cur = doms_new;
dattr_cur = dattr_new;
@@ -9329,10 +9442,6 @@ void __init sched_init(void)
#ifdef CONFIG_CPUMASK_OFFSTACK
alloc_size += num_possible_cpus() * cpumask_size();
#endif
- /*
- * As sched_init() is called before page_alloc is setup,
- * we use alloc_bootmem().
- */
if (alloc_size) {
ptr = (unsigned long)kzalloc(alloc_size, GFP_NOWAIT);
@@ -9401,6 +9510,10 @@ void __init sched_init(void)
#endif /* CONFIG_USER_SCHED */
#endif /* CONFIG_GROUP_SCHED */
+#if defined CONFIG_FAIR_GROUP_SCHED && defined CONFIG_SMP
+ update_shares_data = __alloc_percpu(nr_cpu_ids * sizeof(unsigned long),
+ __alignof__(unsigned long));
+#endif
for_each_possible_cpu(i) {
struct rq *rq;
@@ -9483,6 +9596,8 @@ void __init sched_init(void)
rq->cpu = i;
rq->online = 0;
rq->migration_thread = NULL;
+ rq->idle_stamp = 0;
+ rq->avg_idle = 2*sysctl_sched_migration_cost;
INIT_LIST_HEAD(&rq->migration_queue);
rq_attach_root(rq, &def_root_domain);
#endif
@@ -9526,13 +9641,15 @@ void __init sched_init(void)
current->sched_class = &fair_sched_class;
/* Allocate the nohz_cpu_mask if CONFIG_CPUMASK_OFFSTACK */
- alloc_cpumask_var(&nohz_cpu_mask, GFP_NOWAIT);
+ zalloc_cpumask_var(&nohz_cpu_mask, GFP_NOWAIT);
#ifdef CONFIG_SMP
#ifdef CONFIG_NO_HZ
- alloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT);
+ zalloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT);
alloc_cpumask_var(&nohz.ilb_grp_nohz_mask, GFP_NOWAIT);
#endif
- alloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
+ /* May be allocated at isolcpus cmdline parse time */
+ if (cpu_isolated_map == NULL)
+ zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
#endif /* SMP */
perf_event_init();
@@ -10862,6 +10979,7 @@ void synchronize_sched_expedited(void)
spin_unlock_irqrestore(&rq->lock, flags);
}
rcu_expedited_state = RCU_EXPEDITED_STATE_IDLE;
+ synchronize_sched_expedited_count++;
mutex_unlock(&rcu_sched_expedited_mutex);
put_online_cpus();
if (need_full_sync)
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index efb84409bc43..6988cf08f705 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -285,12 +285,16 @@ static void print_cpu(struct seq_file *m, int cpu)
#ifdef CONFIG_SCHEDSTATS
#define P(n) SEQ_printf(m, " .%-30s: %d\n", #n, rq->n);
+#define P64(n) SEQ_printf(m, " .%-30s: %Ld\n", #n, rq->n);
P(yld_count);
P(sched_switch);
P(sched_count);
P(sched_goidle);
+#ifdef CONFIG_SMP
+ P64(avg_idle);
+#endif
P(ttwu_count);
P(ttwu_local);
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 4e777b47eeda..f61837ad336d 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -822,6 +822,26 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
* re-elected due to buddy favours.
*/
clear_buddies(cfs_rq, curr);
+ return;
+ }
+
+ /*
+ * Ensure that a task that missed wakeup preemption by a
+ * narrow margin doesn't have to wait for a full slice.
+ * This also mitigates buddy induced latencies under load.
+ */
+ if (!sched_feat(WAKEUP_PREEMPT))
+ return;
+
+ if (delta_exec < sysctl_sched_min_granularity)
+ return;
+
+ if (cfs_rq->nr_running > 1) {
+ struct sched_entity *se = __pick_next_entity(cfs_rq);
+ s64 delta = curr->vruntime - se->vruntime;
+
+ if (delta > ideal_runtime)
+ resched_task(rq_of(cfs_rq)->curr);
}
}
@@ -861,12 +881,18 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se);
static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq)
{
struct sched_entity *se = __pick_next_entity(cfs_rq);
+ struct sched_entity *left = se;
- if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, se) < 1)
- return cfs_rq->next;
+ if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, left) < 1)
+ se = cfs_rq->next;
- if (cfs_rq->last && wakeup_preempt_entity(cfs_rq->last, se) < 1)
- return cfs_rq->last;
+ /*
+ * Prefer last buddy, try to return the CPU to a preempted task.
+ */
+ if (cfs_rq->last && wakeup_preempt_entity(cfs_rq->last, left) < 1)
+ se = cfs_rq->last;
+
+ clear_buddies(cfs_rq, se);
return se;
}
@@ -1319,6 +1345,37 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
}
/*
+ * Try and locate an idle CPU in the sched_domain.
+ */
+static int
+select_idle_sibling(struct task_struct *p, struct sched_domain *sd, int target)
+{
+ int cpu = smp_processor_id();
+ int prev_cpu = task_cpu(p);
+ int i;
+
+ /*
+ * If this domain spans both cpu and prev_cpu (see the SD_WAKE_AFFINE
+ * test in select_task_rq_fair) and the prev_cpu is idle then that's
+ * always a better target than the current cpu.
+ */
+ if (target == cpu && !cpu_rq(prev_cpu)->cfs.nr_running)
+ return prev_cpu;
+
+ /*
+ * Otherwise, iterate the domain and find an elegible idle cpu.
+ */
+ for_each_cpu_and(i, sched_domain_span(sd), &p->cpus_allowed) {
+ if (!cpu_rq(i)->cfs.nr_running) {
+ target = i;
+ break;
+ }
+ }
+
+ return target;
+}
+
+/*
* sched_balance_self: balance the current task (running on cpu) in domains
* that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and
* SD_BALANCE_EXEC.
@@ -1372,11 +1429,35 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
want_sd = 0;
}
- if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
- cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
+ /*
+ * While iterating the domains looking for a spanning
+ * WAKE_AFFINE domain, adjust the affine target to any idle cpu
+ * in cache sharing domains along the way.
+ */
+ if (want_affine) {
+ int target = -1;
- affine_sd = tmp;
- want_affine = 0;
+ /*
+ * If both cpu and prev_cpu are part of this domain,
+ * cpu is a valid SD_WAKE_AFFINE target.
+ */
+ if (cpumask_test_cpu(prev_cpu, sched_domain_span(tmp)))
+ target = cpu;
+
+ /*
+ * If there's an idle sibling in this domain, make that
+ * the wake_affine target instead of the current cpu.
+ */
+ if (tmp->flags & SD_PREFER_SIBLING)
+ target = select_idle_sibling(p, tmp, target);
+
+ if (target >= 0) {
+ if (tmp->flags & SD_WAKE_AFFINE) {
+ affine_sd = tmp;
+ want_affine = 0;
+ }
+ cpu = target;
+ }
}
if (!want_sd && !want_affine)
@@ -1568,6 +1649,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
struct sched_entity *se = &curr->se, *pse = &p->se;
struct cfs_rq *cfs_rq = task_cfs_rq(curr);
int sync = wake_flags & WF_SYNC;
+ int scale = cfs_rq->nr_running >= sched_nr_latency;
update_curr(cfs_rq);
@@ -1582,18 +1664,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
if (unlikely(se == pse))
return;
- /*
- * Only set the backward buddy when the current task is still on the
- * rq. This can happen when a wakeup gets interleaved with schedule on
- * the ->pre_schedule() or idle_balance() point, either of which can
- * drop the rq lock.
- *
- * Also, during early boot the idle thread is in the fair class, for
- * obvious reasons its a bad idea to schedule back to the idle thread.
- */
- if (sched_feat(LAST_BUDDY) && likely(se->on_rq && curr != rq->idle))
- set_last_buddy(se);
- if (sched_feat(NEXT_BUDDY) && !(wake_flags & WF_FORK))
+ if (sched_feat(NEXT_BUDDY) && scale && !(wake_flags & WF_FORK))
set_next_buddy(pse);
/*
@@ -1639,8 +1710,22 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
BUG_ON(!pse);
- if (wakeup_preempt_entity(se, pse) == 1)
+ if (wakeup_preempt_entity(se, pse) == 1) {
resched_task(curr);
+ /*
+ * Only set the backward buddy when the current task is still
+ * on the rq. This can happen when a wakeup gets interleaved
+ * with schedule on the ->pre_schedule() or idle_balance()
+ * point, either of which can * drop the rq lock.
+ *
+ * Also, during early boot the idle thread is in the fair class,
+ * for obvious reasons its a bad idea to schedule back to it.
+ */
+ if (unlikely(!se->on_rq || curr == rq->idle))
+ return;
+ if (sched_feat(LAST_BUDDY) && scale && entity_is_task(se))
+ set_last_buddy(se);
+ }
}
static struct task_struct *pick_next_task_fair(struct rq *rq)
@@ -1649,21 +1734,11 @@ static struct task_struct *pick_next_task_fair(struct rq *rq)
struct cfs_rq *cfs_rq = &rq->cfs;
struct sched_entity *se;
- if (unlikely(!cfs_rq->nr_running))
+ if (!cfs_rq->nr_running)
return NULL;
do {
se = pick_next_entity(cfs_rq);
- /*
- * If se was a buddy, clear it so that it will have to earn
- * the favour again.
- *
- * If se was not a buddy, clear the buddies because neither
- * was elegible to run, let them earn it again.
- *
- * IOW. unconditionally clear buddies.
- */
- __clear_buddies(cfs_rq, NULL);
set_next_entity(cfs_rq, se);
cfs_rq = group_cfs_rq(se);
} while (cfs_rq);
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index a4d790cddb19..5c5fef378415 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -1153,29 +1153,12 @@ static struct task_struct *pick_next_highest_task_rt(struct rq *rq, int cpu)
static DEFINE_PER_CPU(cpumask_var_t, local_cpu_mask);
-static inline int pick_optimal_cpu(int this_cpu,
- const struct cpumask *mask)
-{
- int first;
-
- /* "this_cpu" is cheaper to preempt than a remote processor */
- if ((this_cpu != -1) && cpumask_test_cpu(this_cpu, mask))
- return this_cpu;
-
- first = cpumask_first(mask);
- if (first < nr_cpu_ids)
- return first;
-
- return -1;
-}
-
static int find_lowest_rq(struct task_struct *task)
{
struct sched_domain *sd;
struct cpumask *lowest_mask = __get_cpu_var(local_cpu_mask);
int this_cpu = smp_processor_id();
int cpu = task_cpu(task);
- cpumask_var_t domain_mask;
if (task->rt.nr_cpus_allowed == 1)
return -1; /* No other targets possible */
@@ -1198,28 +1181,26 @@ static int find_lowest_rq(struct task_struct *task)
* Otherwise, we consult the sched_domains span maps to figure
* out which cpu is logically closest to our hot cache data.
*/
- if (this_cpu == cpu)
- this_cpu = -1; /* Skip this_cpu opt if the same */
-
- if (alloc_cpumask_var(&domain_mask, GFP_ATOMIC)) {
- for_each_domain(cpu, sd) {
- if (sd->flags & SD_WAKE_AFFINE) {
- int best_cpu;
+ if (!cpumask_test_cpu(this_cpu, lowest_mask))
+ this_cpu = -1; /* Skip this_cpu opt if not among lowest */
- cpumask_and(domain_mask,
- sched_domain_span(sd),
- lowest_mask);
+ for_each_domain(cpu, sd) {
+ if (sd->flags & SD_WAKE_AFFINE) {
+ int best_cpu;
- best_cpu = pick_optimal_cpu(this_cpu,
- domain_mask);
-
- if (best_cpu != -1) {
- free_cpumask_var(domain_mask);
- return best_cpu;
- }
- }
+ /*
+ * "this_cpu" is cheaper to preempt than a
+ * remote processor.
+ */
+ if (this_cpu != -1 &&
+ cpumask_test_cpu(this_cpu, sched_domain_span(sd)))
+ return this_cpu;
+
+ best_cpu = cpumask_first_and(lowest_mask,
+ sched_domain_span(sd));
+ if (best_cpu < nr_cpu_ids)
+ return best_cpu;
}
- free_cpumask_var(domain_mask);
}
/*
@@ -1227,7 +1208,13 @@ static int find_lowest_rq(struct task_struct *task)
* just give the caller *something* to work with from the compatible
* locations.
*/
- return pick_optimal_cpu(this_cpu, lowest_mask);
+ if (this_cpu != -1)
+ return this_cpu;
+
+ cpu = cpumask_any(lowest_mask);
+ if (cpu < nr_cpu_ids)
+ return cpu;
+ return -1;
}
/* Will lock the rq it finds */
diff --git a/kernel/signal.c b/kernel/signal.c
index 6705320784fd..6b982f2cf524 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -22,12 +22,14 @@
#include <linux/ptrace.h>
#include <linux/signal.h>
#include <linux/signalfd.h>
+#include <linux/ratelimit.h>
#include <linux/tracehook.h>
#include <linux/capability.h>
#include <linux/freezer.h>
#include <linux/pid_namespace.h>
#include <linux/nsproxy.h>
-#include <trace/events/sched.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/signal.h>
#include <asm/param.h>
#include <asm/uaccess.h>
@@ -41,6 +43,8 @@
static struct kmem_cache *sigqueue_cachep;
+int print_fatal_signals __read_mostly;
+
static void __user *sig_handler(struct task_struct *t, int sig)
{
return t->sighand->action[sig - 1].sa.sa_handler;
@@ -159,7 +163,7 @@ int next_signal(struct sigpending *pending, sigset_t *mask)
{
unsigned long i, *s, *m, x;
int sig = 0;
-
+
s = pending->signal.sig;
m = mask->sig;
switch (_NSIG_WORDS) {
@@ -184,17 +188,31 @@ int next_signal(struct sigpending *pending, sigset_t *mask)
sig = ffz(~x) + 1;
break;
}
-
+
return sig;
}
+static inline void print_dropped_signal(int sig)
+{
+ static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
+
+ if (!print_fatal_signals)
+ return;
+
+ if (!__ratelimit(&ratelimit_state))
+ return;
+
+ printk(KERN_INFO "%s/%d: reached RLIMIT_SIGPENDING, dropped signal %d\n",
+ current->comm, current->pid, sig);
+}
+
/*
* allocate a new signal queue record
* - this may be called without locks if and only if t == current, otherwise an
* appopriate lock must be held to stop the target task from exiting
*/
-static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
- int override_rlimit)
+static struct sigqueue *
+__sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimit)
{
struct sigqueue *q = NULL;
struct user_struct *user;
@@ -207,10 +225,15 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
*/
user = get_uid(__task_cred(t)->user);
atomic_inc(&user->sigpending);
+
if (override_rlimit ||
atomic_read(&user->sigpending) <=
- t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
+ t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) {
q = kmem_cache_alloc(sigqueue_cachep, flags);
+ } else {
+ print_dropped_signal(sig);
+ }
+
if (unlikely(q == NULL)) {
atomic_dec(&user->sigpending);
free_uid(user);
@@ -834,7 +857,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
struct sigqueue *q;
int override_rlimit;
- trace_sched_signal_send(sig, t);
+ trace_signal_generate(sig, info, t);
assert_spin_locked(&t->sighand->siglock);
@@ -869,7 +892,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
else
override_rlimit = 0;
- q = __sigqueue_alloc(t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE,
+ q = __sigqueue_alloc(sig, t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE,
override_rlimit);
if (q) {
list_add_tail(&q->list, &pending->list);
@@ -896,12 +919,21 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
break;
}
} else if (!is_si_special(info)) {
- if (sig >= SIGRTMIN && info->si_code != SI_USER)
- /*
- * Queue overflow, abort. We may abort if the signal was rt
- * and sent by user using something other than kill().
- */
+ if (sig >= SIGRTMIN && info->si_code != SI_USER) {
+ /*
+ * Queue overflow, abort. We may abort if the
+ * signal was rt and sent by user using something
+ * other than kill().
+ */
+ trace_signal_overflow_fail(sig, group, info);
return -EAGAIN;
+ } else {
+ /*
+ * This is a silent loss of information. We still
+ * send the signal, but the *info bits are lost.
+ */
+ trace_signal_lose_info(sig, group, info);
+ }
}
out_set:
@@ -925,8 +957,6 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
return __send_signal(sig, info, t, group, from_ancestor_ns);
}
-int print_fatal_signals;
-
static void print_fatal_signal(struct pt_regs *regs, int signr)
{
printk("%s/%d: potentially unexpected fatal signal %d.\n",
@@ -1293,19 +1323,19 @@ EXPORT_SYMBOL(kill_pid);
* These functions support sending signals using preallocated sigqueue
* structures. This is needed "because realtime applications cannot
* afford to lose notifications of asynchronous events, like timer
- * expirations or I/O completions". In the case of Posix Timers
+ * expirations or I/O completions". In the case of Posix Timers
* we allocate the sigqueue structure from the timer_create. If this
* allocation fails we are able to report the failure to the application
* with an EAGAIN error.
*/
-
struct sigqueue *sigqueue_alloc(void)
{
- struct sigqueue *q;
+ struct sigqueue *q = __sigqueue_alloc(-1, current, GFP_KERNEL, 0);
- if ((q = __sigqueue_alloc(current, GFP_KERNEL, 0)))
+ if (q)
q->flags |= SIGQUEUE_PREALLOC;
- return(q);
+
+ return q;
}
void sigqueue_free(struct sigqueue *q)
@@ -1839,6 +1869,9 @@ relock:
ka = &sighand->action[signr-1];
}
+ /* Trace actually delivered signals. */
+ trace_signal_deliver(signr, info, ka);
+
if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */
continue;
if (ka->sa.sa_handler != SIG_DFL) {
diff --git a/kernel/slow-work-debugfs.c b/kernel/slow-work-debugfs.c
new file mode 100644
index 000000000000..e45c43645298
--- /dev/null
+++ b/kernel/slow-work-debugfs.c
@@ -0,0 +1,227 @@
+/* Slow work debugging
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/slow-work.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/seq_file.h>
+#include "slow-work.h"
+
+#define ITERATOR_SHIFT (BITS_PER_LONG - 4)
+#define ITERATOR_SELECTOR (0xfUL << ITERATOR_SHIFT)
+#define ITERATOR_COUNTER (~ITERATOR_SELECTOR)
+
+void slow_work_new_thread_desc(struct slow_work *work, struct seq_file *m)
+{
+ seq_puts(m, "Slow-work: New thread");
+}
+
+/*
+ * Render the time mark field on a work item into a 5-char time with units plus
+ * a space
+ */
+static void slow_work_print_mark(struct seq_file *m, struct slow_work *work)
+{
+ struct timespec now, diff;
+
+ now = CURRENT_TIME;
+ diff = timespec_sub(now, work->mark);
+
+ if (diff.tv_sec < 0)
+ seq_puts(m, " -ve ");
+ else if (diff.tv_sec == 0 && diff.tv_nsec < 1000)
+ seq_printf(m, "%3luns ", diff.tv_nsec);
+ else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000)
+ seq_printf(m, "%3luus ", diff.tv_nsec / 1000);
+ else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000000)
+ seq_printf(m, "%3lums ", diff.tv_nsec / 1000000);
+ else if (diff.tv_sec <= 1)
+ seq_puts(m, " 1s ");
+ else if (diff.tv_sec < 60)
+ seq_printf(m, "%4lus ", diff.tv_sec);
+ else if (diff.tv_sec < 60 * 60)
+ seq_printf(m, "%4lum ", diff.tv_sec / 60);
+ else if (diff.tv_sec < 60 * 60 * 24)
+ seq_printf(m, "%4luh ", diff.tv_sec / 3600);
+ else
+ seq_puts(m, "exces ");
+}
+
+/*
+ * Describe a slow work item for debugfs
+ */
+static int slow_work_runqueue_show(struct seq_file *m, void *v)
+{
+ struct slow_work *work;
+ struct list_head *p = v;
+ unsigned long id;
+
+ switch ((unsigned long) v) {
+ case 1:
+ seq_puts(m, "THR PID ITEM ADDR FL MARK DESC\n");
+ return 0;
+ case 2:
+ seq_puts(m, "=== ===== ================ == ===== ==========\n");
+ return 0;
+
+ case 3 ... 3 + SLOW_WORK_THREAD_LIMIT - 1:
+ id = (unsigned long) v - 3;
+
+ read_lock(&slow_work_execs_lock);
+ work = slow_work_execs[id];
+ if (work) {
+ smp_read_barrier_depends();
+
+ seq_printf(m, "%3lu %5d %16p %2lx ",
+ id, slow_work_pids[id], work, work->flags);
+ slow_work_print_mark(m, work);
+
+ if (work->ops->desc)
+ work->ops->desc(work, m);
+ seq_putc(m, '\n');
+ }
+ read_unlock(&slow_work_execs_lock);
+ return 0;
+
+ default:
+ work = list_entry(p, struct slow_work, link);
+ seq_printf(m, "%3s - %16p %2lx ",
+ work->flags & SLOW_WORK_VERY_SLOW ? "vsq" : "sq",
+ work, work->flags);
+ slow_work_print_mark(m, work);
+
+ if (work->ops->desc)
+ work->ops->desc(work, m);
+ seq_putc(m, '\n');
+ return 0;
+ }
+}
+
+/*
+ * map the iterator to a work item
+ */
+static void *slow_work_runqueue_index(struct seq_file *m, loff_t *_pos)
+{
+ struct list_head *p;
+ unsigned long count, id;
+
+ switch (*_pos >> ITERATOR_SHIFT) {
+ case 0x0:
+ if (*_pos == 0)
+ *_pos = 1;
+ if (*_pos < 3)
+ return (void *)(unsigned long) *_pos;
+ if (*_pos < 3 + SLOW_WORK_THREAD_LIMIT)
+ for (id = *_pos - 3;
+ id < SLOW_WORK_THREAD_LIMIT;
+ id++, (*_pos)++)
+ if (slow_work_execs[id])
+ return (void *)(unsigned long) *_pos;
+ *_pos = 0x1UL << ITERATOR_SHIFT;
+
+ case 0x1:
+ count = *_pos & ITERATOR_COUNTER;
+ list_for_each(p, &slow_work_queue) {
+ if (count == 0)
+ return p;
+ count--;
+ }
+ *_pos = 0x2UL << ITERATOR_SHIFT;
+
+ case 0x2:
+ count = *_pos & ITERATOR_COUNTER;
+ list_for_each(p, &vslow_work_queue) {
+ if (count == 0)
+ return p;
+ count--;
+ }
+ *_pos = 0x3UL << ITERATOR_SHIFT;
+
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *slow_work_runqueue_start(struct seq_file *m, loff_t *_pos)
+{
+ spin_lock_irq(&slow_work_queue_lock);
+ return slow_work_runqueue_index(m, _pos);
+}
+
+/*
+ * move to the next line
+ */
+static void *slow_work_runqueue_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+ struct list_head *p = v;
+ unsigned long selector = *_pos >> ITERATOR_SHIFT;
+
+ (*_pos)++;
+ switch (selector) {
+ case 0x0:
+ return slow_work_runqueue_index(m, _pos);
+
+ case 0x1:
+ if (*_pos >> ITERATOR_SHIFT == 0x1) {
+ p = p->next;
+ if (p != &slow_work_queue)
+ return p;
+ }
+ *_pos = 0x2UL << ITERATOR_SHIFT;
+ p = &vslow_work_queue;
+
+ case 0x2:
+ if (*_pos >> ITERATOR_SHIFT == 0x2) {
+ p = p->next;
+ if (p != &vslow_work_queue)
+ return p;
+ }
+ *_pos = 0x3UL << ITERATOR_SHIFT;
+
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * clean up after reading
+ */
+static void slow_work_runqueue_stop(struct seq_file *m, void *v)
+{
+ spin_unlock_irq(&slow_work_queue_lock);
+}
+
+static const struct seq_operations slow_work_runqueue_ops = {
+ .start = slow_work_runqueue_start,
+ .stop = slow_work_runqueue_stop,
+ .next = slow_work_runqueue_next,
+ .show = slow_work_runqueue_show,
+};
+
+/*
+ * open "/sys/kernel/debug/slow_work/runqueue" to list queue contents
+ */
+static int slow_work_runqueue_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &slow_work_runqueue_ops);
+}
+
+const struct file_operations slow_work_runqueue_fops = {
+ .owner = THIS_MODULE,
+ .open = slow_work_runqueue_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
diff --git a/kernel/slow-work.c b/kernel/slow-work.c
index 0d31135efbf4..00889bd3c590 100644
--- a/kernel/slow-work.c
+++ b/kernel/slow-work.c
@@ -16,11 +16,8 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/wait.h>
-
-#define SLOW_WORK_CULL_TIMEOUT (5 * HZ) /* cull threads 5s after running out of
- * things to do */
-#define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after
- * OOM */
+#include <linux/debugfs.h>
+#include "slow-work.h"
static void slow_work_cull_timeout(unsigned long);
static void slow_work_oom_timeout(unsigned long);
@@ -46,7 +43,7 @@ static unsigned vslow_work_proportion = 50; /* % of threads that may process
#ifdef CONFIG_SYSCTL
static const int slow_work_min_min_threads = 2;
-static int slow_work_max_max_threads = 255;
+static int slow_work_max_max_threads = SLOW_WORK_THREAD_LIMIT;
static const int slow_work_min_vslow = 1;
static const int slow_work_max_vslow = 99;
@@ -98,6 +95,56 @@ static DEFINE_TIMER(slow_work_oom_timer, slow_work_oom_timeout, 0, 0);
static struct slow_work slow_work_new_thread; /* new thread starter */
/*
+ * slow work ID allocation (use slow_work_queue_lock)
+ */
+static DECLARE_BITMAP(slow_work_ids, SLOW_WORK_THREAD_LIMIT);
+
+/*
+ * Unregistration tracking to prevent put_ref() from disappearing during module
+ * unload
+ */
+#ifdef CONFIG_MODULES
+static struct module *slow_work_thread_processing[SLOW_WORK_THREAD_LIMIT];
+static struct module *slow_work_unreg_module;
+static struct slow_work *slow_work_unreg_work_item;
+static DECLARE_WAIT_QUEUE_HEAD(slow_work_unreg_wq);
+static DEFINE_MUTEX(slow_work_unreg_sync_lock);
+
+static void slow_work_set_thread_processing(int id, struct slow_work *work)
+{
+ if (work)
+ slow_work_thread_processing[id] = work->owner;
+}
+static void slow_work_done_thread_processing(int id, struct slow_work *work)
+{
+ struct module *module = slow_work_thread_processing[id];
+
+ slow_work_thread_processing[id] = NULL;
+ smp_mb();
+ if (slow_work_unreg_work_item == work ||
+ slow_work_unreg_module == module)
+ wake_up_all(&slow_work_unreg_wq);
+}
+static void slow_work_clear_thread_processing(int id)
+{
+ slow_work_thread_processing[id] = NULL;
+}
+#else
+static void slow_work_set_thread_processing(int id, struct slow_work *work) {}
+static void slow_work_done_thread_processing(int id, struct slow_work *work) {}
+static void slow_work_clear_thread_processing(int id) {}
+#endif
+
+/*
+ * Data for tracking currently executing items for indication through /proc
+ */
+#ifdef CONFIG_SLOW_WORK_DEBUG
+struct slow_work *slow_work_execs[SLOW_WORK_THREAD_LIMIT];
+pid_t slow_work_pids[SLOW_WORK_THREAD_LIMIT];
+DEFINE_RWLOCK(slow_work_execs_lock);
+#endif
+
+/*
* The queues of work items and the lock governing access to them. These are
* shared between all the CPUs. It doesn't make sense to have per-CPU queues
* as the number of threads bears no relation to the number of CPUs.
@@ -105,9 +152,18 @@ static struct slow_work slow_work_new_thread; /* new thread starter */
* There are two queues of work items: one for slow work items, and one for
* very slow work items.
*/
-static LIST_HEAD(slow_work_queue);
-static LIST_HEAD(vslow_work_queue);
-static DEFINE_SPINLOCK(slow_work_queue_lock);
+LIST_HEAD(slow_work_queue);
+LIST_HEAD(vslow_work_queue);
+DEFINE_SPINLOCK(slow_work_queue_lock);
+
+/*
+ * The following are two wait queues that get pinged when a work item is placed
+ * on an empty queue. These allow work items that are hogging a thread by
+ * sleeping in a way that could be deferred to yield their thread and enqueue
+ * themselves.
+ */
+static DECLARE_WAIT_QUEUE_HEAD(slow_work_queue_waits_for_occupation);
+static DECLARE_WAIT_QUEUE_HEAD(vslow_work_queue_waits_for_occupation);
/*
* The thread controls. A variable used to signal to the threads that they
@@ -126,6 +182,20 @@ static DECLARE_COMPLETION(slow_work_last_thread_exited);
static int slow_work_user_count;
static DEFINE_MUTEX(slow_work_user_lock);
+static inline int slow_work_get_ref(struct slow_work *work)
+{
+ if (work->ops->get_ref)
+ return work->ops->get_ref(work);
+
+ return 0;
+}
+
+static inline void slow_work_put_ref(struct slow_work *work)
+{
+ if (work->ops->put_ref)
+ work->ops->put_ref(work);
+}
+
/*
* Calculate the maximum number of active threads in the pool that are
* permitted to process very slow work items.
@@ -149,7 +219,7 @@ static unsigned slow_work_calc_vsmax(void)
* Attempt to execute stuff queued on a slow thread. Return true if we managed
* it, false if there was nothing to do.
*/
-static bool slow_work_execute(void)
+static noinline bool slow_work_execute(int id)
{
struct slow_work *work = NULL;
unsigned vsmax;
@@ -186,6 +256,13 @@ static bool slow_work_execute(void)
} else {
very_slow = false; /* avoid the compiler warning */
}
+
+ slow_work_set_thread_processing(id, work);
+ if (work) {
+ slow_work_mark_time(work);
+ slow_work_begin_exec(id, work);
+ }
+
spin_unlock_irq(&slow_work_queue_lock);
if (!work)
@@ -194,12 +271,19 @@ static bool slow_work_execute(void)
if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags))
BUG();
- work->ops->execute(work);
+ /* don't execute if the work is in the process of being cancelled */
+ if (!test_bit(SLOW_WORK_CANCELLING, &work->flags))
+ work->ops->execute(work);
if (very_slow)
atomic_dec(&vslow_work_executing_count);
clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags);
+ /* wake up anyone waiting for this work to be complete */
+ wake_up_bit(&work->flags, SLOW_WORK_EXECUTING);
+
+ slow_work_end_exec(id, work);
+
/* if someone tried to enqueue the item whilst we were executing it,
* then it'll be left unenqueued to avoid multiple threads trying to
* execute it simultaneously
@@ -219,7 +303,10 @@ static bool slow_work_execute(void)
spin_unlock_irq(&slow_work_queue_lock);
}
- work->ops->put_ref(work);
+ /* sort out the race between module unloading and put_ref() */
+ slow_work_put_ref(work);
+ slow_work_done_thread_processing(id, work);
+
return true;
auto_requeue:
@@ -227,15 +314,61 @@ auto_requeue:
* - we transfer our ref on the item back to the appropriate queue
* - don't wake another thread up as we're awake already
*/
+ slow_work_mark_time(work);
if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
list_add_tail(&work->link, &vslow_work_queue);
else
list_add_tail(&work->link, &slow_work_queue);
spin_unlock_irq(&slow_work_queue_lock);
+ slow_work_clear_thread_processing(id);
return true;
}
/**
+ * slow_work_sleep_till_thread_needed - Sleep till thread needed by other work
+ * work: The work item under execution that wants to sleep
+ * _timeout: Scheduler sleep timeout
+ *
+ * Allow a requeueable work item to sleep on a slow-work processor thread until
+ * that thread is needed to do some other work or the sleep is interrupted by
+ * some other event.
+ *
+ * The caller must set up a wake up event before calling this and must have set
+ * the appropriate sleep mode (such as TASK_UNINTERRUPTIBLE) and tested its own
+ * condition before calling this function as no test is made here.
+ *
+ * False is returned if there is nothing on the queue; true is returned if the
+ * work item should be requeued
+ */
+bool slow_work_sleep_till_thread_needed(struct slow_work *work,
+ signed long *_timeout)
+{
+ wait_queue_head_t *wfo_wq;
+ struct list_head *queue;
+
+ DEFINE_WAIT(wait);
+
+ if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
+ wfo_wq = &vslow_work_queue_waits_for_occupation;
+ queue = &vslow_work_queue;
+ } else {
+ wfo_wq = &slow_work_queue_waits_for_occupation;
+ queue = &slow_work_queue;
+ }
+
+ if (!list_empty(queue))
+ return true;
+
+ add_wait_queue_exclusive(wfo_wq, &wait);
+ if (list_empty(queue))
+ *_timeout = schedule_timeout(*_timeout);
+ finish_wait(wfo_wq, &wait);
+
+ return !list_empty(queue);
+}
+EXPORT_SYMBOL(slow_work_sleep_till_thread_needed);
+
+/**
* slow_work_enqueue - Schedule a slow work item for processing
* @work: The work item to queue
*
@@ -260,16 +393,22 @@ auto_requeue:
* allowed to pick items to execute. This ensures that very slow items won't
* overly block ones that are just ordinarily slow.
*
- * Returns 0 if successful, -EAGAIN if not.
+ * Returns 0 if successful, -EAGAIN if not (or -ECANCELED if cancelled work is
+ * attempted queued)
*/
int slow_work_enqueue(struct slow_work *work)
{
+ wait_queue_head_t *wfo_wq;
+ struct list_head *queue;
unsigned long flags;
+ int ret;
+
+ if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
+ return -ECANCELED;
BUG_ON(slow_work_user_count <= 0);
BUG_ON(!work);
BUG_ON(!work->ops);
- BUG_ON(!work->ops->get_ref);
/* when honouring an enqueue request, we only promise that we will run
* the work function in the future; we do not promise to run it once
@@ -280,8 +419,19 @@ int slow_work_enqueue(struct slow_work *work)
* maintaining our promise
*/
if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
+ if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
+ wfo_wq = &vslow_work_queue_waits_for_occupation;
+ queue = &vslow_work_queue;
+ } else {
+ wfo_wq = &slow_work_queue_waits_for_occupation;
+ queue = &slow_work_queue;
+ }
+
spin_lock_irqsave(&slow_work_queue_lock, flags);
+ if (unlikely(test_bit(SLOW_WORK_CANCELLING, &work->flags)))
+ goto cancelled;
+
/* we promise that we will not attempt to execute the work
* function in more than one thread simultaneously
*
@@ -299,25 +449,221 @@ int slow_work_enqueue(struct slow_work *work)
if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
} else {
- if (work->ops->get_ref(work) < 0)
- goto cant_get_ref;
- if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
- list_add_tail(&work->link, &vslow_work_queue);
- else
- list_add_tail(&work->link, &slow_work_queue);
+ ret = slow_work_get_ref(work);
+ if (ret < 0)
+ goto failed;
+ slow_work_mark_time(work);
+ list_add_tail(&work->link, queue);
wake_up(&slow_work_thread_wq);
+
+ /* if someone who could be requeued is sleeping on a
+ * thread, then ask them to yield their thread */
+ if (work->link.prev == queue)
+ wake_up(wfo_wq);
}
spin_unlock_irqrestore(&slow_work_queue_lock, flags);
}
return 0;
-cant_get_ref:
+cancelled:
+ ret = -ECANCELED;
+failed:
spin_unlock_irqrestore(&slow_work_queue_lock, flags);
- return -EAGAIN;
+ return ret;
}
EXPORT_SYMBOL(slow_work_enqueue);
+static int slow_work_wait(void *word)
+{
+ schedule();
+ return 0;
+}
+
+/**
+ * slow_work_cancel - Cancel a slow work item
+ * @work: The work item to cancel
+ *
+ * This function will cancel a previously enqueued work item. If we cannot
+ * cancel the work item, it is guarenteed to have run when this function
+ * returns.
+ */
+void slow_work_cancel(struct slow_work *work)
+{
+ bool wait = true, put = false;
+
+ set_bit(SLOW_WORK_CANCELLING, &work->flags);
+ smp_mb();
+
+ /* if the work item is a delayed work item with an active timer, we
+ * need to wait for the timer to finish _before_ getting the spinlock,
+ * lest we deadlock against the timer routine
+ *
+ * the timer routine will leave DELAYED set if it notices the
+ * CANCELLING flag in time
+ */
+ if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
+ struct delayed_slow_work *dwork =
+ container_of(work, struct delayed_slow_work, work);
+ del_timer_sync(&dwork->timer);
+ }
+
+ spin_lock_irq(&slow_work_queue_lock);
+
+ if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
+ /* the timer routine aborted or never happened, so we are left
+ * holding the timer's reference on the item and should just
+ * drop the pending flag and wait for any ongoing execution to
+ * finish */
+ struct delayed_slow_work *dwork =
+ container_of(work, struct delayed_slow_work, work);
+
+ BUG_ON(timer_pending(&dwork->timer));
+ BUG_ON(!list_empty(&work->link));
+
+ clear_bit(SLOW_WORK_DELAYED, &work->flags);
+ put = true;
+ clear_bit(SLOW_WORK_PENDING, &work->flags);
+
+ } else if (test_bit(SLOW_WORK_PENDING, &work->flags) &&
+ !list_empty(&work->link)) {
+ /* the link in the pending queue holds a reference on the item
+ * that we will need to release */
+ list_del_init(&work->link);
+ wait = false;
+ put = true;
+ clear_bit(SLOW_WORK_PENDING, &work->flags);
+
+ } else if (test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags)) {
+ /* the executor is holding our only reference on the item, so
+ * we merely need to wait for it to finish executing */
+ clear_bit(SLOW_WORK_PENDING, &work->flags);
+ }
+
+ spin_unlock_irq(&slow_work_queue_lock);
+
+ /* the EXECUTING flag is set by the executor whilst the spinlock is set
+ * and before the item is dequeued - so assuming the above doesn't
+ * actually dequeue it, simply waiting for the EXECUTING flag to be
+ * released here should be sufficient */
+ if (wait)
+ wait_on_bit(&work->flags, SLOW_WORK_EXECUTING, slow_work_wait,
+ TASK_UNINTERRUPTIBLE);
+
+ clear_bit(SLOW_WORK_CANCELLING, &work->flags);
+ if (put)
+ slow_work_put_ref(work);
+}
+EXPORT_SYMBOL(slow_work_cancel);
+
+/*
+ * Handle expiry of the delay timer, indicating that a delayed slow work item
+ * should now be queued if not cancelled
+ */
+static void delayed_slow_work_timer(unsigned long data)
+{
+ wait_queue_head_t *wfo_wq;
+ struct list_head *queue;
+ struct slow_work *work = (struct slow_work *) data;
+ unsigned long flags;
+ bool queued = false, put = false, first = false;
+
+ if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
+ wfo_wq = &vslow_work_queue_waits_for_occupation;
+ queue = &vslow_work_queue;
+ } else {
+ wfo_wq = &slow_work_queue_waits_for_occupation;
+ queue = &slow_work_queue;
+ }
+
+ spin_lock_irqsave(&slow_work_queue_lock, flags);
+ if (likely(!test_bit(SLOW_WORK_CANCELLING, &work->flags))) {
+ clear_bit(SLOW_WORK_DELAYED, &work->flags);
+
+ if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
+ /* we discard the reference the timer was holding in
+ * favour of the one the executor holds */
+ set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
+ put = true;
+ } else {
+ slow_work_mark_time(work);
+ list_add_tail(&work->link, queue);
+ queued = true;
+ if (work->link.prev == queue)
+ first = true;
+ }
+ }
+
+ spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+ if (put)
+ slow_work_put_ref(work);
+ if (first)
+ wake_up(wfo_wq);
+ if (queued)
+ wake_up(&slow_work_thread_wq);
+}
+
+/**
+ * delayed_slow_work_enqueue - Schedule a delayed slow work item for processing
+ * @dwork: The delayed work item to queue
+ * @delay: When to start executing the work, in jiffies from now
+ *
+ * This is similar to slow_work_enqueue(), but it adds a delay before the work
+ * is actually queued for processing.
+ *
+ * The item can have delayed processing requested on it whilst it is being
+ * executed. The delay will begin immediately, and if it expires before the
+ * item finishes executing, the item will be placed back on the queue when it
+ * has done executing.
+ */
+int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
+ unsigned long delay)
+{
+ struct slow_work *work = &dwork->work;
+ unsigned long flags;
+ int ret;
+
+ if (delay == 0)
+ return slow_work_enqueue(&dwork->work);
+
+ BUG_ON(slow_work_user_count <= 0);
+ BUG_ON(!work);
+ BUG_ON(!work->ops);
+
+ if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
+ return -ECANCELED;
+
+ if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
+ spin_lock_irqsave(&slow_work_queue_lock, flags);
+
+ if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
+ goto cancelled;
+
+ /* the timer holds a reference whilst it is pending */
+ ret = work->ops->get_ref(work);
+ if (ret < 0)
+ goto cant_get_ref;
+
+ if (test_and_set_bit(SLOW_WORK_DELAYED, &work->flags))
+ BUG();
+ dwork->timer.expires = jiffies + delay;
+ dwork->timer.data = (unsigned long) work;
+ dwork->timer.function = delayed_slow_work_timer;
+ add_timer(&dwork->timer);
+
+ spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+ }
+
+ return 0;
+
+cancelled:
+ ret = -ECANCELED;
+cant_get_ref:
+ spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(delayed_slow_work_enqueue);
+
/*
* Schedule a cull of the thread pool at some time in the near future
*/
@@ -368,13 +714,23 @@ static inline bool slow_work_available(int vsmax)
*/
static int slow_work_thread(void *_data)
{
- int vsmax;
+ int vsmax, id;
DEFINE_WAIT(wait);
set_freezable();
set_user_nice(current, -5);
+ /* allocate ourselves an ID */
+ spin_lock_irq(&slow_work_queue_lock);
+ id = find_first_zero_bit(slow_work_ids, SLOW_WORK_THREAD_LIMIT);
+ BUG_ON(id < 0 || id >= SLOW_WORK_THREAD_LIMIT);
+ __set_bit(id, slow_work_ids);
+ slow_work_set_thread_pid(id, current->pid);
+ spin_unlock_irq(&slow_work_queue_lock);
+
+ sprintf(current->comm, "kslowd%03u", id);
+
for (;;) {
vsmax = vslow_work_proportion;
vsmax *= atomic_read(&slow_work_thread_count);
@@ -395,7 +751,7 @@ static int slow_work_thread(void *_data)
vsmax *= atomic_read(&slow_work_thread_count);
vsmax /= 100;
- if (slow_work_available(vsmax) && slow_work_execute()) {
+ if (slow_work_available(vsmax) && slow_work_execute(id)) {
cond_resched();
if (list_empty(&slow_work_queue) &&
list_empty(&vslow_work_queue) &&
@@ -412,6 +768,11 @@ static int slow_work_thread(void *_data)
break;
}
+ spin_lock_irq(&slow_work_queue_lock);
+ slow_work_set_thread_pid(id, 0);
+ __clear_bit(id, slow_work_ids);
+ spin_unlock_irq(&slow_work_queue_lock);
+
if (atomic_dec_and_test(&slow_work_thread_count))
complete_and_exit(&slow_work_last_thread_exited, 0);
return 0;
@@ -427,21 +788,6 @@ static void slow_work_cull_timeout(unsigned long data)
}
/*
- * Get a reference on slow work thread starter
- */
-static int slow_work_new_thread_get_ref(struct slow_work *work)
-{
- return 0;
-}
-
-/*
- * Drop a reference on slow work thread starter
- */
-static void slow_work_new_thread_put_ref(struct slow_work *work)
-{
-}
-
-/*
* Start a new slow work thread
*/
static void slow_work_new_thread_execute(struct slow_work *work)
@@ -475,9 +821,11 @@ static void slow_work_new_thread_execute(struct slow_work *work)
}
static const struct slow_work_ops slow_work_new_thread_ops = {
- .get_ref = slow_work_new_thread_get_ref,
- .put_ref = slow_work_new_thread_put_ref,
+ .owner = THIS_MODULE,
.execute = slow_work_new_thread_execute,
+#ifdef CONFIG_SLOW_WORK_DEBUG
+ .desc = slow_work_new_thread_desc,
+#endif
};
/*
@@ -546,12 +894,13 @@ static int slow_work_max_threads_sysctl(struct ctl_table *table, int write,
/**
* slow_work_register_user - Register a user of the facility
+ * @module: The module about to make use of the facility
*
* Register a user of the facility, starting up the initial threads if there
* aren't any other users at this point. This will return 0 if successful, or
* an error if not.
*/
-int slow_work_register_user(void)
+int slow_work_register_user(struct module *module)
{
struct task_struct *p;
int loop;
@@ -598,14 +947,81 @@ error:
}
EXPORT_SYMBOL(slow_work_register_user);
+/*
+ * wait for all outstanding items from the calling module to complete
+ * - note that more items may be queued whilst we're waiting
+ */
+static void slow_work_wait_for_items(struct module *module)
+{
+#ifdef CONFIG_MODULES
+ DECLARE_WAITQUEUE(myself, current);
+ struct slow_work *work;
+ int loop;
+
+ mutex_lock(&slow_work_unreg_sync_lock);
+ add_wait_queue(&slow_work_unreg_wq, &myself);
+
+ for (;;) {
+ spin_lock_irq(&slow_work_queue_lock);
+
+ /* first of all, we wait for the last queued item in each list
+ * to be processed */
+ list_for_each_entry_reverse(work, &vslow_work_queue, link) {
+ if (work->owner == module) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ slow_work_unreg_work_item = work;
+ goto do_wait;
+ }
+ }
+ list_for_each_entry_reverse(work, &slow_work_queue, link) {
+ if (work->owner == module) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ slow_work_unreg_work_item = work;
+ goto do_wait;
+ }
+ }
+
+ /* then we wait for the items being processed to finish */
+ slow_work_unreg_module = module;
+ smp_mb();
+ for (loop = 0; loop < SLOW_WORK_THREAD_LIMIT; loop++) {
+ if (slow_work_thread_processing[loop] == module)
+ goto do_wait;
+ }
+ spin_unlock_irq(&slow_work_queue_lock);
+ break; /* okay, we're done */
+
+ do_wait:
+ spin_unlock_irq(&slow_work_queue_lock);
+ schedule();
+ slow_work_unreg_work_item = NULL;
+ slow_work_unreg_module = NULL;
+ }
+
+ remove_wait_queue(&slow_work_unreg_wq, &myself);
+ mutex_unlock(&slow_work_unreg_sync_lock);
+#endif /* CONFIG_MODULES */
+}
+
/**
* slow_work_unregister_user - Unregister a user of the facility
+ * @module: The module whose items should be cleared
*
* Unregister a user of the facility, killing all the threads if this was the
* last one.
+ *
+ * This waits for all the work items belonging to the nominated module to go
+ * away before proceeding.
*/
-void slow_work_unregister_user(void)
+void slow_work_unregister_user(struct module *module)
{
+ /* first of all, wait for all outstanding items from the calling module
+ * to complete */
+ if (module)
+ slow_work_wait_for_items(module);
+
+ /* then we can actually go about shutting down the facility if need
+ * be */
mutex_lock(&slow_work_user_lock);
BUG_ON(slow_work_user_count <= 0);
@@ -639,6 +1055,16 @@ static int __init init_slow_work(void)
if (slow_work_max_max_threads < nr_cpus * 2)
slow_work_max_max_threads = nr_cpus * 2;
#endif
+#ifdef CONFIG_SLOW_WORK_DEBUG
+ {
+ struct dentry *dbdir;
+
+ dbdir = debugfs_create_dir("slow_work", NULL);
+ if (dbdir && !IS_ERR(dbdir))
+ debugfs_create_file("runqueue", S_IFREG | 0400, dbdir,
+ NULL, &slow_work_runqueue_fops);
+ }
+#endif
return 0;
}
diff --git a/kernel/slow-work.h b/kernel/slow-work.h
new file mode 100644
index 000000000000..321f3c59d732
--- /dev/null
+++ b/kernel/slow-work.h
@@ -0,0 +1,72 @@
+/* Slow work private definitions
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define SLOW_WORK_CULL_TIMEOUT (5 * HZ) /* cull threads 5s after running out of
+ * things to do */
+#define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after
+ * OOM */
+
+#define SLOW_WORK_THREAD_LIMIT 255 /* abs maximum number of slow-work threads */
+
+/*
+ * slow-work.c
+ */
+#ifdef CONFIG_SLOW_WORK_DEBUG
+extern struct slow_work *slow_work_execs[];
+extern pid_t slow_work_pids[];
+extern rwlock_t slow_work_execs_lock;
+#endif
+
+extern struct list_head slow_work_queue;
+extern struct list_head vslow_work_queue;
+extern spinlock_t slow_work_queue_lock;
+
+/*
+ * slow-work-debugfs.c
+ */
+#ifdef CONFIG_SLOW_WORK_DEBUG
+extern const struct file_operations slow_work_runqueue_fops;
+
+extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *);
+#endif
+
+/*
+ * Helper functions
+ */
+static inline void slow_work_set_thread_pid(int id, pid_t pid)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+ slow_work_pids[id] = pid;
+#endif
+}
+
+static inline void slow_work_mark_time(struct slow_work *work)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+ work->mark = CURRENT_TIME;
+#endif
+}
+
+static inline void slow_work_begin_exec(int id, struct slow_work *work)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+ slow_work_execs[id] = work;
+#endif
+}
+
+static inline void slow_work_end_exec(int id, struct slow_work *work)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+ write_lock(&slow_work_execs_lock);
+ slow_work_execs[id] = NULL;
+ write_unlock(&slow_work_execs_lock);
+#endif
+}
diff --git a/kernel/smp.c b/kernel/smp.c
index c9d1c7835c2f..a8c76069cf50 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -265,9 +265,7 @@ static DEFINE_PER_CPU(struct call_single_data, csd_data);
* @info: An arbitrary pointer to pass to the function.
* @wait: If true, wait until function has completed on other CPUs.
*
- * Returns 0 on success, else a negative status code. Note that @wait
- * will be implicitly turned on in case of allocation failures, since
- * we fall back to on-stack allocation.
+ * Returns 0 on success, else a negative status code.
*/
int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
int wait)
@@ -321,6 +319,51 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
}
EXPORT_SYMBOL(smp_call_function_single);
+/*
+ * smp_call_function_any - Run a function on any of the given cpus
+ * @mask: The mask of cpus it can run on.
+ * @func: The function to run. This must be fast and non-blocking.
+ * @info: An arbitrary pointer to pass to the function.
+ * @wait: If true, wait until function has completed.
+ *
+ * Returns 0 on success, else a negative status code (if no cpus were online).
+ * Note that @wait will be implicitly turned on in case of allocation failures,
+ * since we fall back to on-stack allocation.
+ *
+ * Selection preference:
+ * 1) current cpu if in @mask
+ * 2) any cpu of current node if in @mask
+ * 3) any other online cpu in @mask
+ */
+int smp_call_function_any(const struct cpumask *mask,
+ void (*func)(void *info), void *info, int wait)
+{
+ unsigned int cpu;
+ const struct cpumask *nodemask;
+ int ret;
+
+ /* Try for same CPU (cheapest) */
+ cpu = get_cpu();
+ if (cpumask_test_cpu(cpu, mask))
+ goto call;
+
+ /* Try for same node. */
+ nodemask = cpumask_of_node(cpu);
+ for (cpu = cpumask_first_and(nodemask, mask); cpu < nr_cpu_ids;
+ cpu = cpumask_next_and(cpu, nodemask, mask)) {
+ if (cpu_online(cpu))
+ goto call;
+ }
+
+ /* Any online will do: smp_call_function_single handles nr_cpu_ids. */
+ cpu = cpumask_any_and(mask, cpu_online_mask);
+call:
+ ret = smp_call_function_single(cpu, func, info, wait);
+ put_cpu();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(smp_call_function_any);
+
/**
* __smp_call_function_single(): Run a function on another CPU
* @cpu: The CPU to run on.
@@ -355,9 +398,7 @@ void __smp_call_function_single(int cpu, struct call_single_data *data,
* @wait: If true, wait (atomically) until function has completed
* on other CPUs.
*
- * If @wait is true, then returns once @func has returned. Note that @wait
- * will be implicitly turned on in case of allocation failures, since
- * we fall back to on-stack allocation.
+ * If @wait is true, then returns once @func has returned.
*
* You must not call this function with disabled interrupts or from a
* hardware interrupt handler or from a bottom half handler. Preemption
@@ -443,8 +484,7 @@ EXPORT_SYMBOL(smp_call_function_many);
* Returns 0.
*
* If @wait is true, then returns once @func has returned; otherwise
- * it returns just before the target cpu calls @func. In case of allocation
- * failure, @wait will be implicitly turned on.
+ * it returns just before the target cpu calls @func.
*
* You must not call this function with disabled interrupts or from a
* hardware interrupt handler or from a bottom half handler.
diff --git a/kernel/softirq.c b/kernel/softirq.c
index f8749e5216e0..21939d9e830e 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -302,9 +302,9 @@ void irq_exit(void)
if (!in_interrupt() && local_softirq_pending())
invoke_softirq();
+ rcu_irq_exit();
#ifdef CONFIG_NO_HZ
/* Make sure that timer wheel updates are propagated */
- rcu_irq_exit();
if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched())
tick_nohz_stop_sched_tick(0);
#endif
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index 5ddab730cb2f..41e042219ff6 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -21,145 +21,28 @@
#include <linux/debug_locks.h>
#include <linux/module.h>
-#ifndef _spin_trylock
-int __lockfunc _spin_trylock(spinlock_t *lock)
-{
- return __spin_trylock(lock);
-}
-EXPORT_SYMBOL(_spin_trylock);
-#endif
-
-#ifndef _read_trylock
-int __lockfunc _read_trylock(rwlock_t *lock)
-{
- return __read_trylock(lock);
-}
-EXPORT_SYMBOL(_read_trylock);
-#endif
-
-#ifndef _write_trylock
-int __lockfunc _write_trylock(rwlock_t *lock)
-{
- return __write_trylock(lock);
-}
-EXPORT_SYMBOL(_write_trylock);
-#endif
-
/*
* If lockdep is enabled then we use the non-preemption spin-ops
* even on CONFIG_PREEMPT, because lockdep assumes that interrupts are
* not re-enabled during lock-acquire (which the preempt-spin-ops do):
*/
#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)
-
-#ifndef _read_lock
-void __lockfunc _read_lock(rwlock_t *lock)
-{
- __read_lock(lock);
-}
-EXPORT_SYMBOL(_read_lock);
-#endif
-
-#ifndef _spin_lock_irqsave
-unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
-{
- return __spin_lock_irqsave(lock);
-}
-EXPORT_SYMBOL(_spin_lock_irqsave);
-#endif
-
-#ifndef _spin_lock_irq
-void __lockfunc _spin_lock_irq(spinlock_t *lock)
-{
- __spin_lock_irq(lock);
-}
-EXPORT_SYMBOL(_spin_lock_irq);
-#endif
-
-#ifndef _spin_lock_bh
-void __lockfunc _spin_lock_bh(spinlock_t *lock)
-{
- __spin_lock_bh(lock);
-}
-EXPORT_SYMBOL(_spin_lock_bh);
-#endif
-
-#ifndef _read_lock_irqsave
-unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
-{
- return __read_lock_irqsave(lock);
-}
-EXPORT_SYMBOL(_read_lock_irqsave);
-#endif
-
-#ifndef _read_lock_irq
-void __lockfunc _read_lock_irq(rwlock_t *lock)
-{
- __read_lock_irq(lock);
-}
-EXPORT_SYMBOL(_read_lock_irq);
-#endif
-
-#ifndef _read_lock_bh
-void __lockfunc _read_lock_bh(rwlock_t *lock)
-{
- __read_lock_bh(lock);
-}
-EXPORT_SYMBOL(_read_lock_bh);
-#endif
-
-#ifndef _write_lock_irqsave
-unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
-{
- return __write_lock_irqsave(lock);
-}
-EXPORT_SYMBOL(_write_lock_irqsave);
-#endif
-
-#ifndef _write_lock_irq
-void __lockfunc _write_lock_irq(rwlock_t *lock)
-{
- __write_lock_irq(lock);
-}
-EXPORT_SYMBOL(_write_lock_irq);
-#endif
-
-#ifndef _write_lock_bh
-void __lockfunc _write_lock_bh(rwlock_t *lock)
-{
- __write_lock_bh(lock);
-}
-EXPORT_SYMBOL(_write_lock_bh);
-#endif
-
-#ifndef _spin_lock
-void __lockfunc _spin_lock(spinlock_t *lock)
-{
- __spin_lock(lock);
-}
-EXPORT_SYMBOL(_spin_lock);
-#endif
-
-#ifndef _write_lock
-void __lockfunc _write_lock(rwlock_t *lock)
-{
- __write_lock(lock);
-}
-EXPORT_SYMBOL(_write_lock);
-#endif
-
-#else /* CONFIG_PREEMPT: */
-
/*
+ * The __lock_function inlines are taken from
+ * include/linux/spinlock_api_smp.h
+ */
+#else
+/*
+ * We build the __lock_function inlines here. They are too large for
+ * inlining all over the place, but here is only one user per function
+ * which embedds them into the calling _lock_function below.
+ *
* This could be a long-held lock. We both prepare to spin for a long
* time (making _this_ CPU preemptable if possible), and we also signal
* towards that other CPU that it should break the lock ASAP.
- *
- * (We do this in a function because inlining it would be excessive.)
*/
-
#define BUILD_LOCK_OPS(op, locktype) \
-void __lockfunc _##op##_lock(locktype##_t *lock) \
+void __lockfunc __##op##_lock(locktype##_t *lock) \
{ \
for (;;) { \
preempt_disable(); \
@@ -175,9 +58,7 @@ void __lockfunc _##op##_lock(locktype##_t *lock) \
(lock)->break_lock = 0; \
} \
\
-EXPORT_SYMBOL(_##op##_lock); \
- \
-unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock) \
+unsigned long __lockfunc __##op##_lock_irqsave(locktype##_t *lock) \
{ \
unsigned long flags; \
\
@@ -198,16 +79,12 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock) \
return flags; \
} \
\
-EXPORT_SYMBOL(_##op##_lock_irqsave); \
- \
-void __lockfunc _##op##_lock_irq(locktype##_t *lock) \
+void __lockfunc __##op##_lock_irq(locktype##_t *lock) \
{ \
_##op##_lock_irqsave(lock); \
} \
\
-EXPORT_SYMBOL(_##op##_lock_irq); \
- \
-void __lockfunc _##op##_lock_bh(locktype##_t *lock) \
+void __lockfunc __##op##_lock_bh(locktype##_t *lock) \
{ \
unsigned long flags; \
\
@@ -220,23 +97,21 @@ void __lockfunc _##op##_lock_bh(locktype##_t *lock) \
local_bh_disable(); \
local_irq_restore(flags); \
} \
- \
-EXPORT_SYMBOL(_##op##_lock_bh)
/*
* Build preemption-friendly versions of the following
* lock-spinning functions:
*
- * _[spin|read|write]_lock()
- * _[spin|read|write]_lock_irq()
- * _[spin|read|write]_lock_irqsave()
- * _[spin|read|write]_lock_bh()
+ * __[spin|read|write]_lock()
+ * __[spin|read|write]_lock_irq()
+ * __[spin|read|write]_lock_irqsave()
+ * __[spin|read|write]_lock_bh()
*/
BUILD_LOCK_OPS(spin, spinlock);
BUILD_LOCK_OPS(read, rwlock);
BUILD_LOCK_OPS(write, rwlock);
-#endif /* CONFIG_PREEMPT */
+#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -248,7 +123,8 @@ void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass)
}
EXPORT_SYMBOL(_spin_lock_nested);
-unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass)
+unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock,
+ int subclass)
{
unsigned long flags;
@@ -272,7 +148,127 @@ EXPORT_SYMBOL(_spin_lock_nest_lock);
#endif
-#ifndef _spin_unlock
+#ifndef CONFIG_INLINE_SPIN_TRYLOCK
+int __lockfunc _spin_trylock(spinlock_t *lock)
+{
+ return __spin_trylock(lock);
+}
+EXPORT_SYMBOL(_spin_trylock);
+#endif
+
+#ifndef CONFIG_INLINE_READ_TRYLOCK
+int __lockfunc _read_trylock(rwlock_t *lock)
+{
+ return __read_trylock(lock);
+}
+EXPORT_SYMBOL(_read_trylock);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_TRYLOCK
+int __lockfunc _write_trylock(rwlock_t *lock)
+{
+ return __write_trylock(lock);
+}
+EXPORT_SYMBOL(_write_trylock);
+#endif
+
+#ifndef CONFIG_INLINE_READ_LOCK
+void __lockfunc _read_lock(rwlock_t *lock)
+{
+ __read_lock(lock);
+}
+EXPORT_SYMBOL(_read_lock);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_LOCK_IRQSAVE
+unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
+{
+ return __spin_lock_irqsave(lock);
+}
+EXPORT_SYMBOL(_spin_lock_irqsave);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_LOCK_IRQ
+void __lockfunc _spin_lock_irq(spinlock_t *lock)
+{
+ __spin_lock_irq(lock);
+}
+EXPORT_SYMBOL(_spin_lock_irq);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_LOCK_BH
+void __lockfunc _spin_lock_bh(spinlock_t *lock)
+{
+ __spin_lock_bh(lock);
+}
+EXPORT_SYMBOL(_spin_lock_bh);
+#endif
+
+#ifndef CONFIG_INLINE_READ_LOCK_IRQSAVE
+unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
+{
+ return __read_lock_irqsave(lock);
+}
+EXPORT_SYMBOL(_read_lock_irqsave);
+#endif
+
+#ifndef CONFIG_INLINE_READ_LOCK_IRQ
+void __lockfunc _read_lock_irq(rwlock_t *lock)
+{
+ __read_lock_irq(lock);
+}
+EXPORT_SYMBOL(_read_lock_irq);
+#endif
+
+#ifndef CONFIG_INLINE_READ_LOCK_BH
+void __lockfunc _read_lock_bh(rwlock_t *lock)
+{
+ __read_lock_bh(lock);
+}
+EXPORT_SYMBOL(_read_lock_bh);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_LOCK_IRQSAVE
+unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
+{
+ return __write_lock_irqsave(lock);
+}
+EXPORT_SYMBOL(_write_lock_irqsave);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_LOCK_IRQ
+void __lockfunc _write_lock_irq(rwlock_t *lock)
+{
+ __write_lock_irq(lock);
+}
+EXPORT_SYMBOL(_write_lock_irq);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_LOCK_BH
+void __lockfunc _write_lock_bh(rwlock_t *lock)
+{
+ __write_lock_bh(lock);
+}
+EXPORT_SYMBOL(_write_lock_bh);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_LOCK
+void __lockfunc _spin_lock(spinlock_t *lock)
+{
+ __spin_lock(lock);
+}
+EXPORT_SYMBOL(_spin_lock);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_LOCK
+void __lockfunc _write_lock(rwlock_t *lock)
+{
+ __write_lock(lock);
+}
+EXPORT_SYMBOL(_write_lock);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_UNLOCK
void __lockfunc _spin_unlock(spinlock_t *lock)
{
__spin_unlock(lock);
@@ -280,7 +276,7 @@ void __lockfunc _spin_unlock(spinlock_t *lock)
EXPORT_SYMBOL(_spin_unlock);
#endif
-#ifndef _write_unlock
+#ifndef CONFIG_INLINE_WRITE_UNLOCK
void __lockfunc _write_unlock(rwlock_t *lock)
{
__write_unlock(lock);
@@ -288,7 +284,7 @@ void __lockfunc _write_unlock(rwlock_t *lock)
EXPORT_SYMBOL(_write_unlock);
#endif
-#ifndef _read_unlock
+#ifndef CONFIG_INLINE_READ_UNLOCK
void __lockfunc _read_unlock(rwlock_t *lock)
{
__read_unlock(lock);
@@ -296,7 +292,7 @@ void __lockfunc _read_unlock(rwlock_t *lock)
EXPORT_SYMBOL(_read_unlock);
#endif
-#ifndef _spin_unlock_irqrestore
+#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE
void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
{
__spin_unlock_irqrestore(lock, flags);
@@ -304,7 +300,7 @@ void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
EXPORT_SYMBOL(_spin_unlock_irqrestore);
#endif
-#ifndef _spin_unlock_irq
+#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQ
void __lockfunc _spin_unlock_irq(spinlock_t *lock)
{
__spin_unlock_irq(lock);
@@ -312,7 +308,7 @@ void __lockfunc _spin_unlock_irq(spinlock_t *lock)
EXPORT_SYMBOL(_spin_unlock_irq);
#endif
-#ifndef _spin_unlock_bh
+#ifndef CONFIG_INLINE_SPIN_UNLOCK_BH
void __lockfunc _spin_unlock_bh(spinlock_t *lock)
{
__spin_unlock_bh(lock);
@@ -320,7 +316,7 @@ void __lockfunc _spin_unlock_bh(spinlock_t *lock)
EXPORT_SYMBOL(_spin_unlock_bh);
#endif
-#ifndef _read_unlock_irqrestore
+#ifndef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE
void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
{
__read_unlock_irqrestore(lock, flags);
@@ -328,7 +324,7 @@ void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
EXPORT_SYMBOL(_read_unlock_irqrestore);
#endif
-#ifndef _read_unlock_irq
+#ifndef CONFIG_INLINE_READ_UNLOCK_IRQ
void __lockfunc _read_unlock_irq(rwlock_t *lock)
{
__read_unlock_irq(lock);
@@ -336,7 +332,7 @@ void __lockfunc _read_unlock_irq(rwlock_t *lock)
EXPORT_SYMBOL(_read_unlock_irq);
#endif
-#ifndef _read_unlock_bh
+#ifndef CONFIG_INLINE_READ_UNLOCK_BH
void __lockfunc _read_unlock_bh(rwlock_t *lock)
{
__read_unlock_bh(lock);
@@ -344,7 +340,7 @@ void __lockfunc _read_unlock_bh(rwlock_t *lock)
EXPORT_SYMBOL(_read_unlock_bh);
#endif
-#ifndef _write_unlock_irqrestore
+#ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE
void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
{
__write_unlock_irqrestore(lock, flags);
@@ -352,7 +348,7 @@ void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
EXPORT_SYMBOL(_write_unlock_irqrestore);
#endif
-#ifndef _write_unlock_irq
+#ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQ
void __lockfunc _write_unlock_irq(rwlock_t *lock)
{
__write_unlock_irq(lock);
@@ -360,7 +356,7 @@ void __lockfunc _write_unlock_irq(rwlock_t *lock)
EXPORT_SYMBOL(_write_unlock_irq);
#endif
-#ifndef _write_unlock_bh
+#ifndef CONFIG_INLINE_WRITE_UNLOCK_BH
void __lockfunc _write_unlock_bh(rwlock_t *lock)
{
__write_unlock_bh(lock);
@@ -368,7 +364,7 @@ void __lockfunc _write_unlock_bh(rwlock_t *lock)
EXPORT_SYMBOL(_write_unlock_bh);
#endif
-#ifndef _spin_trylock_bh
+#ifndef CONFIG_INLINE_SPIN_TRYLOCK_BH
int __lockfunc _spin_trylock_bh(spinlock_t *lock)
{
return __spin_trylock_bh(lock);
diff --git a/kernel/srcu.c b/kernel/srcu.c
index b0aeeaf22ce4..818d7d9aa03c 100644
--- a/kernel/srcu.c
+++ b/kernel/srcu.c
@@ -49,6 +49,7 @@ int init_srcu_struct(struct srcu_struct *sp)
sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array);
return (sp->per_cpu_ref ? 0 : -ENOMEM);
}
+EXPORT_SYMBOL_GPL(init_srcu_struct);
/*
* srcu_readers_active_idx -- returns approximate number of readers
@@ -97,6 +98,7 @@ void cleanup_srcu_struct(struct srcu_struct *sp)
free_percpu(sp->per_cpu_ref);
sp->per_cpu_ref = NULL;
}
+EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
/**
* srcu_read_lock - register a new reader for an SRCU-protected structure.
@@ -118,6 +120,7 @@ int srcu_read_lock(struct srcu_struct *sp)
preempt_enable();
return idx;
}
+EXPORT_SYMBOL_GPL(srcu_read_lock);
/**
* srcu_read_unlock - unregister a old reader from an SRCU-protected structure.
@@ -136,22 +139,12 @@ void srcu_read_unlock(struct srcu_struct *sp, int idx)
per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]--;
preempt_enable();
}
+EXPORT_SYMBOL_GPL(srcu_read_unlock);
-/**
- * synchronize_srcu - wait for prior SRCU read-side critical-section completion
- * @sp: srcu_struct with which to synchronize.
- *
- * Flip the completed counter, and wait for the old count to drain to zero.
- * As with classic RCU, the updater must use some separate means of
- * synchronizing concurrent updates. Can block; must be called from
- * process context.
- *
- * Note that it is illegal to call synchornize_srcu() from the corresponding
- * SRCU read-side critical section; doing so will result in deadlock.
- * However, it is perfectly legal to call synchronize_srcu() on one
- * srcu_struct from some other srcu_struct's read-side critical section.
+/*
+ * Helper function for synchronize_srcu() and synchronize_srcu_expedited().
*/
-void synchronize_srcu(struct srcu_struct *sp)
+void __synchronize_srcu(struct srcu_struct *sp, void (*sync_func)(void))
{
int idx;
@@ -173,7 +166,7 @@ void synchronize_srcu(struct srcu_struct *sp)
return;
}
- synchronize_sched(); /* Force memory barrier on all CPUs. */
+ sync_func(); /* Force memory barrier on all CPUs. */
/*
* The preceding synchronize_sched() ensures that any CPU that
@@ -190,7 +183,7 @@ void synchronize_srcu(struct srcu_struct *sp)
idx = sp->completed & 0x1;
sp->completed++;
- synchronize_sched(); /* Force memory barrier on all CPUs. */
+ sync_func(); /* Force memory barrier on all CPUs. */
/*
* At this point, because of the preceding synchronize_sched(),
@@ -203,7 +196,7 @@ void synchronize_srcu(struct srcu_struct *sp)
while (srcu_readers_active_idx(sp, idx))
schedule_timeout_interruptible(1);
- synchronize_sched(); /* Force memory barrier on all CPUs. */
+ sync_func(); /* Force memory barrier on all CPUs. */
/*
* The preceding synchronize_sched() forces all srcu_read_unlock()
@@ -237,6 +230,47 @@ void synchronize_srcu(struct srcu_struct *sp)
}
/**
+ * synchronize_srcu - wait for prior SRCU read-side critical-section completion
+ * @sp: srcu_struct with which to synchronize.
+ *
+ * Flip the completed counter, and wait for the old count to drain to zero.
+ * As with classic RCU, the updater must use some separate means of
+ * synchronizing concurrent updates. Can block; must be called from
+ * process context.
+ *
+ * Note that it is illegal to call synchronize_srcu() from the corresponding
+ * SRCU read-side critical section; doing so will result in deadlock.
+ * However, it is perfectly legal to call synchronize_srcu() on one
+ * srcu_struct from some other srcu_struct's read-side critical section.
+ */
+void synchronize_srcu(struct srcu_struct *sp)
+{
+ __synchronize_srcu(sp, synchronize_sched);
+}
+EXPORT_SYMBOL_GPL(synchronize_srcu);
+
+/**
+ * synchronize_srcu_expedited - like synchronize_srcu, but less patient
+ * @sp: srcu_struct with which to synchronize.
+ *
+ * Flip the completed counter, and wait for the old count to drain to zero.
+ * As with classic RCU, the updater must use some separate means of
+ * synchronizing concurrent updates. Can block; must be called from
+ * process context.
+ *
+ * Note that it is illegal to call synchronize_srcu_expedited()
+ * from the corresponding SRCU read-side critical section; doing so
+ * will result in deadlock. However, it is perfectly legal to call
+ * synchronize_srcu_expedited() on one srcu_struct from some other
+ * srcu_struct's read-side critical section.
+ */
+void synchronize_srcu_expedited(struct srcu_struct *sp)
+{
+ __synchronize_srcu(sp, synchronize_sched_expedited);
+}
+EXPORT_SYMBOL_GPL(synchronize_srcu_expedited);
+
+/**
* srcu_batches_completed - return batches completed.
* @sp: srcu_struct on which to report batch completion.
*
@@ -248,10 +282,4 @@ long srcu_batches_completed(struct srcu_struct *sp)
{
return sp->completed;
}
-
-EXPORT_SYMBOL_GPL(init_srcu_struct);
-EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
-EXPORT_SYMBOL_GPL(srcu_read_lock);
-EXPORT_SYMBOL_GPL(srcu_read_unlock);
-EXPORT_SYMBOL_GPL(synchronize_srcu);
EXPORT_SYMBOL_GPL(srcu_batches_completed);
diff --git a/kernel/sys.c b/kernel/sys.c
index 255475d163e0..9968c5fb55b9 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -911,16 +911,15 @@ change_okay:
void do_sys_times(struct tms *tms)
{
- struct task_cputime cputime;
- cputime_t cutime, cstime;
+ cputime_t tgutime, tgstime, cutime, cstime;
- thread_group_cputime(current, &cputime);
spin_lock_irq(&current->sighand->siglock);
+ thread_group_times(current, &tgutime, &tgstime);
cutime = current->signal->cutime;
cstime = current->signal->cstime;
spin_unlock_irq(&current->sighand->siglock);
- tms->tms_utime = cputime_to_clock_t(cputime.utime);
- tms->tms_stime = cputime_to_clock_t(cputime.stime);
+ tms->tms_utime = cputime_to_clock_t(tgutime);
+ tms->tms_stime = cputime_to_clock_t(tgstime);
tms->tms_cutime = cputime_to_clock_t(cutime);
tms->tms_cstime = cputime_to_clock_t(cstime);
}
@@ -1110,6 +1109,8 @@ SYSCALL_DEFINE0(setsid)
err = session;
out:
write_unlock_irq(&tasklist_lock);
+ if (err > 0)
+ proc_sid_connector(group_leader);
return err;
}
@@ -1336,16 +1337,14 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
{
struct task_struct *t;
unsigned long flags;
- cputime_t utime, stime;
- struct task_cputime cputime;
+ cputime_t tgutime, tgstime, utime, stime;
unsigned long maxrss = 0;
memset((char *) r, 0, sizeof *r);
utime = stime = cputime_zero;
if (who == RUSAGE_THREAD) {
- utime = task_utime(current);
- stime = task_stime(current);
+ task_times(current, &utime, &stime);
accumulate_thread_rusage(p, r);
maxrss = p->signal->maxrss;
goto out;
@@ -1371,9 +1370,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
break;
case RUSAGE_SELF:
- thread_group_cputime(p, &cputime);
- utime = cputime_add(utime, cputime.utime);
- stime = cputime_add(stime, cputime.stime);
+ thread_group_times(p, &tgutime, &tgstime);
+ utime = cputime_add(utime, tgutime);
+ stime = cputime_add(stime, tgstime);
r->ru_nvcsw += p->signal->nvcsw;
r->ru_nivcsw += p->signal->nivcsw;
r->ru_minflt += p->signal->min_flt;
@@ -1546,24 +1545,37 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
if (arg4 | arg5)
return -EINVAL;
switch (arg2) {
- case 0:
+ case PR_MCE_KILL_CLEAR:
if (arg3 != 0)
return -EINVAL;
current->flags &= ~PF_MCE_PROCESS;
break;
- case 1:
+ case PR_MCE_KILL_SET:
current->flags |= PF_MCE_PROCESS;
- if (arg3 != 0)
+ if (arg3 == PR_MCE_KILL_EARLY)
current->flags |= PF_MCE_EARLY;
- else
+ else if (arg3 == PR_MCE_KILL_LATE)
current->flags &= ~PF_MCE_EARLY;
+ else if (arg3 == PR_MCE_KILL_DEFAULT)
+ current->flags &=
+ ~(PF_MCE_EARLY|PF_MCE_PROCESS);
+ else
+ return -EINVAL;
break;
default:
return -EINVAL;
}
error = 0;
break;
-
+ case PR_MCE_KILL_GET:
+ if (arg2 | arg3 | arg4 | arg5)
+ return -EINVAL;
+ if (current->flags & PF_MCE_PROCESS)
+ error = (current->flags & PF_MCE_EARLY) ?
+ PR_MCE_KILL_EARLY : PR_MCE_KILL_LATE;
+ else
+ error = PR_MCE_KILL_DEFAULT;
+ break;
default:
error = -EINVAL;
break;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 0d949c517412..4dbf93a52ee9 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -36,6 +36,7 @@
#include <linux/sysrq.h>
#include <linux/highuid.h>
#include <linux/writeback.h>
+#include <linux/ratelimit.h>
#include <linux/hugetlb.h>
#include <linux/initrd.h>
#include <linux/key.h>
@@ -158,6 +159,8 @@ extern int no_unaligned_warning;
extern int unaligned_dump_stack;
#endif
+extern struct ratelimit_state printk_ratelimit_state;
+
#ifdef CONFIG_RT_MUTEXES
extern int max_lock_depth;
#endif
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
index b38423ca711a..b6e7aaea4604 100644
--- a/kernel/sysctl_check.c
+++ b/kernel/sysctl_check.c
@@ -1521,7 +1521,7 @@ int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table)
if (!table->ctl_name && table->strategy)
set_fail(&fail, table, "Strategy without ctl_name");
#endif
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_PROC_SYSCTL
if (table->procname && !table->proc_handler)
set_fail(&fail, table, "No proc_handler");
#endif
diff --git a/kernel/time.c b/kernel/time.c
index 2e2e469a7fec..804798005d19 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -662,6 +662,36 @@ u64 nsec_to_clock_t(u64 x)
#endif
}
+/**
+ * nsecs_to_jiffies - Convert nsecs in u64 to jiffies
+ *
+ * @n: nsecs in u64
+ *
+ * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64.
+ * And this doesn't return MAX_JIFFY_OFFSET since this function is designed
+ * for scheduler, not for use in device drivers to calculate timeout value.
+ *
+ * note:
+ * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
+ * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
+ */
+unsigned long nsecs_to_jiffies(u64 n)
+{
+#if (NSEC_PER_SEC % HZ) == 0
+ /* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */
+ return div_u64(n, NSEC_PER_SEC / HZ);
+#elif (HZ % 512) == 0
+ /* overflow after 292 years if HZ = 1024 */
+ return div_u64(n * HZ / 512, NSEC_PER_SEC / 512);
+#else
+ /*
+ * Generic case - optimized for cases where HZ is a multiple of 3.
+ * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc.
+ */
+ return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ);
+#endif
+}
+
#if (BITS_PER_LONG < 64)
u64 get_jiffies_64(void)
{
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index b416512ad17f..d006554888dc 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -339,6 +339,27 @@ config POWER_TRACER
power management decisions, specifically the C-state and P-state
behavior.
+config KSYM_TRACER
+ bool "Trace read and write access on kernel memory locations"
+ depends on HAVE_HW_BREAKPOINT
+ select TRACING
+ help
+ This tracer helps find read and write operations on any given kernel
+ symbol i.e. /proc/kallsyms.
+
+config PROFILE_KSYM_TRACER
+ bool "Profile all kernel memory accesses on 'watched' variables"
+ depends on KSYM_TRACER
+ help
+ This tracer profiles kernel accesses on variables watched through the
+ ksym tracer ftrace plugin. Depending upon the hardware, all read
+ and write operations on kernel variables can be monitored for
+ accesses.
+
+ The results will be displayed in:
+ /debugfs/tracing/profile_ksym
+
+ Say N if unsure.
config STACK_TRACER
bool "Trace max stack"
@@ -428,6 +449,23 @@ config BLK_DEV_IO_TRACE
If unsure, say N.
+config KPROBE_EVENT
+ depends on KPROBES
+ depends on X86
+ bool "Enable kprobes-based dynamic events"
+ select TRACING
+ default y
+ help
+ This allows the user to add tracing events (similar to tracepoints) on the fly
+ via the ftrace interface. See Documentation/trace/kprobetrace.txt
+ for more details.
+
+ Those events can be inserted wherever kprobes can probe, and record
+ various register and memory values.
+
+ This option is also required by perf-probe subcommand of perf tools. If
+ you want to use perf tools, this option is strongly recommended.
+
config DYNAMIC_FTRACE
bool "enable/disable ftrace tracepoints dynamically"
depends on FUNCTION_TRACER
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 26f03ac07c2b..cd9ecd89ec77 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -53,6 +53,8 @@ obj-$(CONFIG_EVENT_TRACING) += trace_export.o
obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o
obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
+obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o
+obj-$(CONFIG_KSYM_TRACER) += trace_ksym.o
obj-$(CONFIG_EVENT_TRACING) += power-traces.o
libftrace-y := ftrace.o
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 37ba67e33265..e51a1bcb7bed 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -60,6 +60,13 @@ static int last_ftrace_enabled;
/* Quick disabling of function tracer. */
int function_trace_stop;
+/* List for set_ftrace_pid's pids. */
+LIST_HEAD(ftrace_pids);
+struct ftrace_pid {
+ struct list_head list;
+ struct pid *pid;
+};
+
/*
* ftrace_disabled is set when an anomaly is discovered.
* ftrace_disabled is much stronger than ftrace_enabled.
@@ -78,6 +85,10 @@ ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub;
ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static int ftrace_set_func(unsigned long *array, int *idx, char *buffer);
+#endif
+
static void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
{
struct ftrace_ops *op = ftrace_list;
@@ -155,7 +166,7 @@ static int __register_ftrace_function(struct ftrace_ops *ops)
else
func = ftrace_list_func;
- if (ftrace_pid_trace) {
+ if (!list_empty(&ftrace_pids)) {
set_ftrace_pid_function(func);
func = ftrace_pid_func;
}
@@ -203,7 +214,7 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
if (ftrace_list->next == &ftrace_list_end) {
ftrace_func_t func = ftrace_list->func;
- if (ftrace_pid_trace) {
+ if (!list_empty(&ftrace_pids)) {
set_ftrace_pid_function(func);
func = ftrace_pid_func;
}
@@ -231,7 +242,7 @@ static void ftrace_update_pid_func(void)
func = __ftrace_trace_function;
#endif
- if (ftrace_pid_trace) {
+ if (!list_empty(&ftrace_pids)) {
set_ftrace_pid_function(func);
func = ftrace_pid_func;
} else {
@@ -740,7 +751,7 @@ ftrace_profile_write(struct file *filp, const char __user *ubuf,
out:
mutex_unlock(&ftrace_profile_lock);
- filp->f_pos += cnt;
+ *ppos += cnt;
return cnt;
}
@@ -821,8 +832,6 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
}
#endif /* CONFIG_FUNCTION_PROFILER */
-/* set when tracing only a pid */
-struct pid *ftrace_pid_trace;
static struct pid * const ftrace_swapper_pid = &init_struct_pid;
#ifdef CONFIG_DYNAMIC_FTRACE
@@ -1261,12 +1270,34 @@ static int ftrace_update_code(struct module *mod)
ftrace_new_addrs = p->newlist;
p->flags = 0L;
- /* convert record (i.e, patch mcount-call with NOP) */
- if (ftrace_code_disable(mod, p)) {
- p->flags |= FTRACE_FL_CONVERTED;
- ftrace_update_cnt++;
- } else
+ /*
+ * Do the initial record convertion from mcount jump
+ * to the NOP instructions.
+ */
+ if (!ftrace_code_disable(mod, p)) {
ftrace_free_rec(p);
+ continue;
+ }
+
+ p->flags |= FTRACE_FL_CONVERTED;
+ ftrace_update_cnt++;
+
+ /*
+ * If the tracing is enabled, go ahead and enable the record.
+ *
+ * The reason not to enable the record immediatelly is the
+ * inherent check of ftrace_make_nop/ftrace_make_call for
+ * correct previous instructions. Making first the NOP
+ * conversion puts the module to the correct state, thus
+ * passing the ftrace_make_call check.
+ */
+ if (ftrace_start_up) {
+ int failed = __ftrace_replace_code(p, 1);
+ if (failed) {
+ ftrace_bug(failed, p->ip);
+ ftrace_free_rec(p);
+ }
+ }
}
stop = ftrace_now(raw_smp_processor_id());
@@ -1656,60 +1687,6 @@ ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
return ret;
}
-enum {
- MATCH_FULL,
- MATCH_FRONT_ONLY,
- MATCH_MIDDLE_ONLY,
- MATCH_END_ONLY,
-};
-
-/*
- * (static function - no need for kernel doc)
- *
- * Pass in a buffer containing a glob and this function will
- * set search to point to the search part of the buffer and
- * return the type of search it is (see enum above).
- * This does modify buff.
- *
- * Returns enum type.
- * search returns the pointer to use for comparison.
- * not returns 1 if buff started with a '!'
- * 0 otherwise.
- */
-static int
-ftrace_setup_glob(char *buff, int len, char **search, int *not)
-{
- int type = MATCH_FULL;
- int i;
-
- if (buff[0] == '!') {
- *not = 1;
- buff++;
- len--;
- } else
- *not = 0;
-
- *search = buff;
-
- for (i = 0; i < len; i++) {
- if (buff[i] == '*') {
- if (!i) {
- *search = buff + 1;
- type = MATCH_END_ONLY;
- } else {
- if (type == MATCH_END_ONLY)
- type = MATCH_MIDDLE_ONLY;
- else
- type = MATCH_FRONT_ONLY;
- buff[i] = 0;
- break;
- }
- }
- }
-
- return type;
-}
-
static int ftrace_match(char *str, char *regex, int len, int type)
{
int matched = 0;
@@ -1758,7 +1735,7 @@ static void ftrace_match_records(char *buff, int len, int enable)
int not;
flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
- type = ftrace_setup_glob(buff, len, &search, &not);
+ type = filter_parse_regex(buff, len, &search, &not);
search_len = strlen(search);
@@ -1826,7 +1803,7 @@ static void ftrace_match_module_records(char *buff, char *mod, int enable)
}
if (strlen(buff)) {
- type = ftrace_setup_glob(buff, strlen(buff), &search, &not);
+ type = filter_parse_regex(buff, strlen(buff), &search, &not);
search_len = strlen(search);
}
@@ -1991,7 +1968,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
int count = 0;
char *search;
- type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
+ type = filter_parse_regex(glob, strlen(glob), &search, &not);
len = strlen(search);
/* we do not support '!' for function probes */
@@ -2068,7 +2045,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
else if (glob) {
int not;
- type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
+ type = filter_parse_regex(glob, strlen(glob), &search, &not);
len = strlen(search);
/* we do not support '!' for function probes */
@@ -2222,15 +2199,15 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
ret = ftrace_process_regex(parser->buffer,
parser->idx, enable);
if (ret)
- goto out;
+ goto out_unlock;
trace_parser_clear(parser);
}
ret = read;
-
+out_unlock:
mutex_unlock(&ftrace_regex_lock);
-out:
+
return ret;
}
@@ -2312,6 +2289,32 @@ static int __init set_ftrace_filter(char *str)
}
__setup("ftrace_filter=", set_ftrace_filter);
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata;
+static int __init set_graph_function(char *str)
+{
+ strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE);
+ return 1;
+}
+__setup("ftrace_graph_filter=", set_graph_function);
+
+static void __init set_ftrace_early_graph(char *buf)
+{
+ int ret;
+ char *func;
+
+ while (buf) {
+ func = strsep(&buf, ",");
+ /* we allow only one expression at a time */
+ ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count,
+ func);
+ if (ret)
+ printk(KERN_DEBUG "ftrace: function %s not "
+ "traceable\n", func);
+ }
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
static void __init set_ftrace_early_filter(char *buf, int enable)
{
char *func;
@@ -2328,6 +2331,10 @@ static void __init set_ftrace_early_filters(void)
set_ftrace_early_filter(ftrace_filter_buf, 1);
if (ftrace_notrace_buf[0])
set_ftrace_early_filter(ftrace_notrace_buf, 0);
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ if (ftrace_graph_buf[0])
+ set_ftrace_early_graph(ftrace_graph_buf);
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
}
static int
@@ -2513,7 +2520,7 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
return -ENODEV;
/* decode regex */
- type = ftrace_setup_glob(buffer, strlen(buffer), &search, &not);
+ type = filter_parse_regex(buffer, strlen(buffer), &search, &not);
if (not)
return -EINVAL;
@@ -2624,7 +2631,7 @@ static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
return 0;
}
-static int ftrace_convert_nops(struct module *mod,
+static int ftrace_process_locs(struct module *mod,
unsigned long *start,
unsigned long *end)
{
@@ -2684,7 +2691,7 @@ static void ftrace_init_module(struct module *mod,
{
if (ftrace_disabled || start == end)
return;
- ftrace_convert_nops(mod, start, end);
+ ftrace_process_locs(mod, start, end);
}
static int ftrace_module_notify(struct notifier_block *self,
@@ -2745,7 +2752,7 @@ void __init ftrace_init(void)
last_ftrace_enabled = ftrace_enabled = 1;
- ret = ftrace_convert_nops(NULL,
+ ret = ftrace_process_locs(NULL,
__start_mcount_loc,
__stop_mcount_loc);
@@ -2778,23 +2785,6 @@ static inline void ftrace_startup_enable(int command) { }
# define ftrace_shutdown_sysctl() do { } while (0)
#endif /* CONFIG_DYNAMIC_FTRACE */
-static ssize_t
-ftrace_pid_read(struct file *file, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- char buf[64];
- int r;
-
- if (ftrace_pid_trace == ftrace_swapper_pid)
- r = sprintf(buf, "swapper tasks\n");
- else if (ftrace_pid_trace)
- r = sprintf(buf, "%u\n", pid_vnr(ftrace_pid_trace));
- else
- r = sprintf(buf, "no pid\n");
-
- return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
-}
-
static void clear_ftrace_swapper(void)
{
struct task_struct *p;
@@ -2845,14 +2835,12 @@ static void set_ftrace_pid(struct pid *pid)
rcu_read_unlock();
}
-static void clear_ftrace_pid_task(struct pid **pid)
+static void clear_ftrace_pid_task(struct pid *pid)
{
- if (*pid == ftrace_swapper_pid)
+ if (pid == ftrace_swapper_pid)
clear_ftrace_swapper();
else
- clear_ftrace_pid(*pid);
-
- *pid = NULL;
+ clear_ftrace_pid(pid);
}
static void set_ftrace_pid_task(struct pid *pid)
@@ -2863,74 +2851,184 @@ static void set_ftrace_pid_task(struct pid *pid)
set_ftrace_pid(pid);
}
-static ssize_t
-ftrace_pid_write(struct file *filp, const char __user *ubuf,
- size_t cnt, loff_t *ppos)
+static int ftrace_pid_add(int p)
{
struct pid *pid;
- char buf[64];
- long val;
- int ret;
+ struct ftrace_pid *fpid;
+ int ret = -EINVAL;
- if (cnt >= sizeof(buf))
- return -EINVAL;
+ mutex_lock(&ftrace_lock);
- if (copy_from_user(&buf, ubuf, cnt))
- return -EFAULT;
+ if (!p)
+ pid = ftrace_swapper_pid;
+ else
+ pid = find_get_pid(p);
- buf[cnt] = 0;
+ if (!pid)
+ goto out;
- ret = strict_strtol(buf, 10, &val);
- if (ret < 0)
- return ret;
+ ret = 0;
- mutex_lock(&ftrace_lock);
- if (val < 0) {
- /* disable pid tracing */
- if (!ftrace_pid_trace)
- goto out;
+ list_for_each_entry(fpid, &ftrace_pids, list)
+ if (fpid->pid == pid)
+ goto out_put;
- clear_ftrace_pid_task(&ftrace_pid_trace);
+ ret = -ENOMEM;
- } else {
- /* swapper task is special */
- if (!val) {
- pid = ftrace_swapper_pid;
- if (pid == ftrace_pid_trace)
- goto out;
- } else {
- pid = find_get_pid(val);
+ fpid = kmalloc(sizeof(*fpid), GFP_KERNEL);
+ if (!fpid)
+ goto out_put;
- if (pid == ftrace_pid_trace) {
- put_pid(pid);
- goto out;
- }
- }
+ list_add(&fpid->list, &ftrace_pids);
+ fpid->pid = pid;
- if (ftrace_pid_trace)
- clear_ftrace_pid_task(&ftrace_pid_trace);
+ set_ftrace_pid_task(pid);
- if (!pid)
- goto out;
+ ftrace_update_pid_func();
+ ftrace_startup_enable(0);
+
+ mutex_unlock(&ftrace_lock);
+ return 0;
+
+out_put:
+ if (pid != ftrace_swapper_pid)
+ put_pid(pid);
+
+out:
+ mutex_unlock(&ftrace_lock);
+ return ret;
+}
+
+static void ftrace_pid_reset(void)
+{
+ struct ftrace_pid *fpid, *safe;
+
+ mutex_lock(&ftrace_lock);
+ list_for_each_entry_safe(fpid, safe, &ftrace_pids, list) {
+ struct pid *pid = fpid->pid;
- ftrace_pid_trace = pid;
+ clear_ftrace_pid_task(pid);
- set_ftrace_pid_task(ftrace_pid_trace);
+ list_del(&fpid->list);
+ kfree(fpid);
}
- /* update the function call */
ftrace_update_pid_func();
ftrace_startup_enable(0);
- out:
mutex_unlock(&ftrace_lock);
+}
- return cnt;
+static void *fpid_start(struct seq_file *m, loff_t *pos)
+{
+ mutex_lock(&ftrace_lock);
+
+ if (list_empty(&ftrace_pids) && (!*pos))
+ return (void *) 1;
+
+ return seq_list_start(&ftrace_pids, *pos);
+}
+
+static void *fpid_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ if (v == (void *)1)
+ return NULL;
+
+ return seq_list_next(v, &ftrace_pids, pos);
+}
+
+static void fpid_stop(struct seq_file *m, void *p)
+{
+ mutex_unlock(&ftrace_lock);
+}
+
+static int fpid_show(struct seq_file *m, void *v)
+{
+ const struct ftrace_pid *fpid = list_entry(v, struct ftrace_pid, list);
+
+ if (v == (void *)1) {
+ seq_printf(m, "no pid\n");
+ return 0;
+ }
+
+ if (fpid->pid == ftrace_swapper_pid)
+ seq_printf(m, "swapper tasks\n");
+ else
+ seq_printf(m, "%u\n", pid_vnr(fpid->pid));
+
+ return 0;
+}
+
+static const struct seq_operations ftrace_pid_sops = {
+ .start = fpid_start,
+ .next = fpid_next,
+ .stop = fpid_stop,
+ .show = fpid_show,
+};
+
+static int
+ftrace_pid_open(struct inode *inode, struct file *file)
+{
+ int ret = 0;
+
+ if ((file->f_mode & FMODE_WRITE) &&
+ (file->f_flags & O_TRUNC))
+ ftrace_pid_reset();
+
+ if (file->f_mode & FMODE_READ)
+ ret = seq_open(file, &ftrace_pid_sops);
+
+ return ret;
+}
+
+static ssize_t
+ftrace_pid_write(struct file *filp, const char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char buf[64], *tmp;
+ long val;
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+
+ buf[cnt] = 0;
+
+ /*
+ * Allow "echo > set_ftrace_pid" or "echo -n '' > set_ftrace_pid"
+ * to clean the filter quietly.
+ */
+ tmp = strstrip(buf);
+ if (strlen(tmp) == 0)
+ return 1;
+
+ ret = strict_strtol(tmp, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ ret = ftrace_pid_add(val);
+
+ return ret ? ret : cnt;
+}
+
+static int
+ftrace_pid_release(struct inode *inode, struct file *file)
+{
+ if (file->f_mode & FMODE_READ)
+ seq_release(inode, file);
+
+ return 0;
}
static const struct file_operations ftrace_pid_fops = {
- .read = ftrace_pid_read,
- .write = ftrace_pid_write,
+ .open = ftrace_pid_open,
+ .write = ftrace_pid_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = ftrace_pid_release,
};
static __init int ftrace_init_debugfs(void)
@@ -3293,4 +3391,3 @@ void ftrace_graph_stop(void)
ftrace_stop();
}
#endif
-
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index d4ff01970547..a1ca4956ab5e 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -397,18 +397,21 @@ int ring_buffer_print_page_header(struct trace_seq *s)
int ret;
ret = trace_seq_printf(s, "\tfield: u64 timestamp;\t"
- "offset:0;\tsize:%u;\n",
- (unsigned int)sizeof(field.time_stamp));
+ "offset:0;\tsize:%u;\tsigned:%u;\n",
+ (unsigned int)sizeof(field.time_stamp),
+ (unsigned int)is_signed_type(u64));
ret = trace_seq_printf(s, "\tfield: local_t commit;\t"
- "offset:%u;\tsize:%u;\n",
+ "offset:%u;\tsize:%u;\tsigned:%u;\n",
(unsigned int)offsetof(typeof(field), commit),
- (unsigned int)sizeof(field.commit));
+ (unsigned int)sizeof(field.commit),
+ (unsigned int)is_signed_type(long));
ret = trace_seq_printf(s, "\tfield: char data;\t"
- "offset:%u;\tsize:%u;\n",
+ "offset:%u;\tsize:%u;\tsigned:%u;\n",
(unsigned int)offsetof(typeof(field), data),
- (unsigned int)BUF_PAGE_SIZE);
+ (unsigned int)BUF_PAGE_SIZE,
+ (unsigned int)is_signed_type(char));
return ret;
}
@@ -483,7 +486,7 @@ struct ring_buffer_iter {
/* Up this if you want to test the TIME_EXTENTS and normalization */
#define DEBUG_SHIFT 0
-static inline u64 rb_time_stamp(struct ring_buffer *buffer, int cpu)
+static inline u64 rb_time_stamp(struct ring_buffer *buffer)
{
/* shift to debug/test normalization and TIME_EXTENTS */
return buffer->clock() << DEBUG_SHIFT;
@@ -494,7 +497,7 @@ u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu)
u64 time;
preempt_disable_notrace();
- time = rb_time_stamp(buffer, cpu);
+ time = rb_time_stamp(buffer);
preempt_enable_no_resched_notrace();
return time;
@@ -599,7 +602,7 @@ static struct list_head *rb_list_head(struct list_head *list)
}
/*
- * rb_is_head_page - test if the give page is the head page
+ * rb_is_head_page - test if the given page is the head page
*
* Because the reader may move the head_page pointer, we can
* not trust what the head page is (it may be pointing to
@@ -1193,6 +1196,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
atomic_inc(&cpu_buffer->record_disabled);
synchronize_sched();
+ spin_lock_irq(&cpu_buffer->reader_lock);
rb_head_page_deactivate(cpu_buffer);
for (i = 0; i < nr_pages; i++) {
@@ -1207,6 +1211,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
return;
rb_reset_cpu(cpu_buffer);
+ spin_unlock_irq(&cpu_buffer->reader_lock);
rb_check_pages(cpu_buffer);
@@ -1785,9 +1790,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
static struct ring_buffer_event *
rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer,
unsigned long length, unsigned long tail,
- struct buffer_page *commit_page,
struct buffer_page *tail_page, u64 *ts)
{
+ struct buffer_page *commit_page = cpu_buffer->commit_page;
struct ring_buffer *buffer = cpu_buffer->buffer;
struct buffer_page *next_page;
int ret;
@@ -1868,7 +1873,7 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer,
* Nested commits always have zero deltas, so
* just reread the time stamp
*/
- *ts = rb_time_stamp(buffer, cpu_buffer->cpu);
+ *ts = rb_time_stamp(buffer);
next_page->page->time_stamp = *ts;
}
@@ -1890,13 +1895,10 @@ static struct ring_buffer_event *
__rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
unsigned type, unsigned long length, u64 *ts)
{
- struct buffer_page *tail_page, *commit_page;
+ struct buffer_page *tail_page;
struct ring_buffer_event *event;
unsigned long tail, write;
- commit_page = cpu_buffer->commit_page;
- /* we just need to protect against interrupts */
- barrier();
tail_page = cpu_buffer->tail_page;
write = local_add_return(length, &tail_page->write);
@@ -1907,7 +1909,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
/* See if we shot pass the end of this buffer page */
if (write > BUF_PAGE_SIZE)
return rb_move_tail(cpu_buffer, length, tail,
- commit_page, tail_page, ts);
+ tail_page, ts);
/* We reserved something on the buffer */
@@ -2111,7 +2113,7 @@ rb_reserve_next_event(struct ring_buffer *buffer,
if (RB_WARN_ON(cpu_buffer, ++nr_loops > 1000))
goto out_fail;
- ts = rb_time_stamp(cpu_buffer->buffer, cpu_buffer->cpu);
+ ts = rb_time_stamp(cpu_buffer->buffer);
/*
* Only the first commit can update the timestamp.
@@ -2681,7 +2683,7 @@ unsigned long ring_buffer_entries(struct ring_buffer *buffer)
EXPORT_SYMBOL_GPL(ring_buffer_entries);
/**
- * ring_buffer_overrun_cpu - get the number of overruns in buffer
+ * ring_buffer_overruns - get the number of overruns in buffer
* @buffer: The ring buffer
*
* Returns the total number of overruns in the ring buffer
diff --git a/kernel/trace/ring_buffer_benchmark.c b/kernel/trace/ring_buffer_benchmark.c
index 573d3cc762c3..b2477caf09c2 100644
--- a/kernel/trace/ring_buffer_benchmark.c
+++ b/kernel/trace/ring_buffer_benchmark.c
@@ -35,6 +35,28 @@ static int disable_reader;
module_param(disable_reader, uint, 0644);
MODULE_PARM_DESC(disable_reader, "only run producer");
+static int write_iteration = 50;
+module_param(write_iteration, uint, 0644);
+MODULE_PARM_DESC(write_iteration, "# of writes between timestamp readings");
+
+static int producer_nice = 19;
+static int consumer_nice = 19;
+
+static int producer_fifo = -1;
+static int consumer_fifo = -1;
+
+module_param(producer_nice, uint, 0644);
+MODULE_PARM_DESC(producer_nice, "nice prio for producer");
+
+module_param(consumer_nice, uint, 0644);
+MODULE_PARM_DESC(consumer_nice, "nice prio for consumer");
+
+module_param(producer_fifo, uint, 0644);
+MODULE_PARM_DESC(producer_fifo, "fifo prio for producer");
+
+module_param(consumer_fifo, uint, 0644);
+MODULE_PARM_DESC(consumer_fifo, "fifo prio for consumer");
+
static int read_events;
static int kill_test;
@@ -208,15 +230,18 @@ static void ring_buffer_producer(void)
do {
struct ring_buffer_event *event;
int *entry;
-
- event = ring_buffer_lock_reserve(buffer, 10);
- if (!event) {
- missed++;
- } else {
- hit++;
- entry = ring_buffer_event_data(event);
- *entry = smp_processor_id();
- ring_buffer_unlock_commit(buffer, event);
+ int i;
+
+ for (i = 0; i < write_iteration; i++) {
+ event = ring_buffer_lock_reserve(buffer, 10);
+ if (!event) {
+ missed++;
+ } else {
+ hit++;
+ entry = ring_buffer_event_data(event);
+ *entry = smp_processor_id();
+ ring_buffer_unlock_commit(buffer, event);
+ }
}
do_gettimeofday(&end_tv);
@@ -263,6 +288,27 @@ static void ring_buffer_producer(void)
if (kill_test)
trace_printk("ERROR!\n");
+
+ if (!disable_reader) {
+ if (consumer_fifo < 0)
+ trace_printk("Running Consumer at nice: %d\n",
+ consumer_nice);
+ else
+ trace_printk("Running Consumer at SCHED_FIFO %d\n",
+ consumer_fifo);
+ }
+ if (producer_fifo < 0)
+ trace_printk("Running Producer at nice: %d\n",
+ producer_nice);
+ else
+ trace_printk("Running Producer at SCHED_FIFO %d\n",
+ producer_fifo);
+
+ /* Let the user know that the test is running at low priority */
+ if (producer_fifo < 0 && consumer_fifo < 0 &&
+ producer_nice == 19 && consumer_nice == 19)
+ trace_printk("WARNING!!! This test is running at lowest priority.\n");
+
trace_printk("Time: %lld (usecs)\n", time);
trace_printk("Overruns: %lld\n", overruns);
if (disable_reader)
@@ -392,6 +438,27 @@ static int __init ring_buffer_benchmark_init(void)
if (IS_ERR(producer))
goto out_kill;
+ /*
+ * Run them as low-prio background tasks by default:
+ */
+ if (!disable_reader) {
+ if (consumer_fifo >= 0) {
+ struct sched_param param = {
+ .sched_priority = consumer_fifo
+ };
+ sched_setscheduler(consumer, SCHED_FIFO, &param);
+ } else
+ set_user_nice(consumer, consumer_nice);
+ }
+
+ if (producer_fifo >= 0) {
+ struct sched_param param = {
+ .sched_priority = consumer_fifo
+ };
+ sched_setscheduler(producer, SCHED_FIFO, &param);
+ } else
+ set_user_nice(producer, producer_nice);
+
return 0;
out_kill:
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 45068269ebb1..874f2893cff0 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -129,7 +129,7 @@ static int tracing_set_tracer(const char *buf);
static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata;
static char *default_bootup_tracer;
-static int __init set_ftrace(char *str)
+static int __init set_cmdline_ftrace(char *str)
{
strncpy(bootup_tracer_buf, str, MAX_TRACER_SIZE);
default_bootup_tracer = bootup_tracer_buf;
@@ -137,7 +137,7 @@ static int __init set_ftrace(char *str)
ring_buffer_expanded = 1;
return 1;
}
-__setup("ftrace=", set_ftrace);
+__setup("ftrace=", set_cmdline_ftrace);
static int __init set_ftrace_dump_on_oops(char *str)
{
@@ -1361,10 +1361,11 @@ int trace_array_vprintk(struct trace_array *tr,
pause_graph_tracing();
raw_local_irq_save(irq_flags);
__raw_spin_lock(&trace_buf_lock);
- len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
-
- len = min(len, TRACE_BUF_SIZE-1);
- trace_buf[len] = 0;
+ if (args == NULL) {
+ strncpy(trace_buf, fmt, TRACE_BUF_SIZE);
+ len = strlen(trace_buf);
+ } else
+ len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
size = sizeof(*entry) + len + 1;
buffer = tr->buffer;
@@ -1373,10 +1374,10 @@ int trace_array_vprintk(struct trace_array *tr,
if (!event)
goto out_unlock;
entry = ring_buffer_event_data(event);
- entry->ip = ip;
+ entry->ip = ip;
memcpy(&entry->buf, trace_buf, len);
- entry->buf[len] = 0;
+ entry->buf[len] = '\0';
if (!filter_check_discard(call, entry, buffer, event))
ring_buffer_unlock_commit(buffer, event);
@@ -1393,7 +1394,7 @@ int trace_array_vprintk(struct trace_array *tr,
int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
{
- return trace_array_printk(&global_trace, ip, fmt, args);
+ return trace_array_vprintk(&global_trace, ip, fmt, args);
}
EXPORT_SYMBOL_GPL(trace_vprintk);
@@ -2440,7 +2441,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
return ret;
}
- filp->f_pos += cnt;
+ *ppos += cnt;
return cnt;
}
@@ -2582,7 +2583,7 @@ tracing_ctrl_write(struct file *filp, const char __user *ubuf,
}
mutex_unlock(&trace_types_lock);
- filp->f_pos += cnt;
+ *ppos += cnt;
return cnt;
}
@@ -2764,7 +2765,7 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
if (err)
return err;
- filp->f_pos += ret;
+ *ppos += ret;
return ret;
}
@@ -3299,7 +3300,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
}
}
- filp->f_pos += cnt;
+ *ppos += cnt;
/* If check pages failed, return ENOMEM */
if (tracing_disabled)
@@ -3319,22 +3320,11 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
return cnt;
}
-static int mark_printk(const char *fmt, ...)
-{
- int ret;
- va_list args;
- va_start(args, fmt);
- ret = trace_vprintk(0, fmt, args);
- va_end(args);
- return ret;
-}
-
static ssize_t
tracing_mark_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *fpos)
{
char *buf;
- char *end;
if (tracing_disabled)
return -EINVAL;
@@ -3342,7 +3332,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
if (cnt > TRACE_BUF_SIZE)
cnt = TRACE_BUF_SIZE;
- buf = kmalloc(cnt + 1, GFP_KERNEL);
+ buf = kmalloc(cnt + 2, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
@@ -3350,14 +3340,13 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
kfree(buf);
return -EFAULT;
}
+ if (buf[cnt-1] != '\n') {
+ buf[cnt] = '\n';
+ buf[cnt+1] = '\0';
+ } else
+ buf[cnt] = '\0';
- /* Cut from the first nil or newline. */
- buf[cnt] = '\0';
- end = strchr(buf, '\n');
- if (end)
- *end = '\0';
-
- cnt = mark_printk("%s\n", buf);
+ cnt = trace_vprintk(0, buf, NULL);
kfree(buf);
*fpos += cnt;
@@ -3730,7 +3719,7 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s)
- return ENOMEM;
+ return -ENOMEM;
trace_seq_init(s);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 405cb850b75d..1d7f4830a80d 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -11,6 +11,7 @@
#include <linux/ftrace.h>
#include <trace/boot.h>
#include <linux/kmemtrace.h>
+#include <linux/hw_breakpoint.h>
#include <linux/trace_seq.h>
#include <linux/ftrace_event.h>
@@ -37,6 +38,7 @@ enum trace_type {
TRACE_KMEM_ALLOC,
TRACE_KMEM_FREE,
TRACE_BLK,
+ TRACE_KSYM,
__TRACE_LAST_TYPE,
};
@@ -98,9 +100,32 @@ struct syscall_trace_enter {
struct syscall_trace_exit {
struct trace_entry ent;
int nr;
- unsigned long ret;
+ long ret;
};
+struct kprobe_trace_entry {
+ struct trace_entry ent;
+ unsigned long ip;
+ int nargs;
+ unsigned long args[];
+};
+
+#define SIZEOF_KPROBE_TRACE_ENTRY(n) \
+ (offsetof(struct kprobe_trace_entry, args) + \
+ (sizeof(unsigned long) * (n)))
+
+struct kretprobe_trace_entry {
+ struct trace_entry ent;
+ unsigned long func;
+ unsigned long ret_ip;
+ int nargs;
+ unsigned long args[];
+};
+
+#define SIZEOF_KRETPROBE_TRACE_ENTRY(n) \
+ (offsetof(struct kretprobe_trace_entry, args) + \
+ (sizeof(unsigned long) * (n)))
+
/*
* trace_flag_type is an enumeration that holds different
* states when a trace occurs. These are:
@@ -209,6 +234,7 @@ extern void __ftrace_bad_type(void);
TRACE_KMEM_ALLOC); \
IF_ASSIGN(var, ent, struct kmemtrace_free_entry, \
TRACE_KMEM_FREE); \
+ IF_ASSIGN(var, ent, struct ksym_trace_entry, TRACE_KSYM);\
__ftrace_bad_type(); \
} while (0)
@@ -364,6 +390,8 @@ int register_tracer(struct tracer *type);
void unregister_tracer(struct tracer *type);
int is_tracing_stopped(void);
+extern int process_new_ksym_entry(char *ksymname, int op, unsigned long addr);
+
extern unsigned long nsecs_to_usecs(unsigned long nsecs);
#ifdef CONFIG_TRACER_MAX_TRACE
@@ -438,6 +466,8 @@ extern int trace_selftest_startup_branch(struct tracer *trace,
struct trace_array *tr);
extern int trace_selftest_startup_hw_branches(struct tracer *trace,
struct trace_array *tr);
+extern int trace_selftest_startup_ksym(struct tracer *trace,
+ struct trace_array *tr);
#endif /* CONFIG_FTRACE_STARTUP_TEST */
extern void *head_page(struct trace_array_cpu *data);
@@ -483,10 +513,6 @@ static inline int ftrace_graph_addr(unsigned long addr)
return 0;
}
#else
-static inline int ftrace_trace_addr(unsigned long addr)
-{
- return 1;
-}
static inline int ftrace_graph_addr(unsigned long addr)
{
return 1;
@@ -500,12 +526,12 @@ print_graph_function(struct trace_iterator *iter)
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-extern struct pid *ftrace_pid_trace;
+extern struct list_head ftrace_pids;
#ifdef CONFIG_FUNCTION_TRACER
static inline int ftrace_trace_task(struct task_struct *task)
{
- if (!ftrace_pid_trace)
+ if (list_empty(&ftrace_pids))
return 1;
return test_tsk_trace_trace(task);
@@ -687,7 +713,6 @@ struct event_filter {
int n_preds;
struct filter_pred **preds;
char *filter_string;
- bool no_reset;
};
struct event_subsystem {
@@ -699,22 +724,40 @@ struct event_subsystem {
};
struct filter_pred;
+struct regex;
typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event,
int val1, int val2);
+typedef int (*regex_match_func)(char *str, struct regex *r, int len);
+
+enum regex_type {
+ MATCH_FULL = 0,
+ MATCH_FRONT_ONLY,
+ MATCH_MIDDLE_ONLY,
+ MATCH_END_ONLY,
+};
+
+struct regex {
+ char pattern[MAX_FILTER_STR_VAL];
+ int len;
+ int field_len;
+ regex_match_func match;
+};
+
struct filter_pred {
- filter_pred_fn_t fn;
- u64 val;
- char str_val[MAX_FILTER_STR_VAL];
- int str_len;
- char *field_name;
- int offset;
- int not;
- int op;
- int pop_n;
+ filter_pred_fn_t fn;
+ u64 val;
+ struct regex regex;
+ char *field_name;
+ int offset;
+ int not;
+ int op;
+ int pop_n;
};
+extern enum regex_type
+filter_parse_regex(char *buff, int len, char **search, int *not);
extern void print_event_filter(struct ftrace_event_call *call,
struct trace_seq *s);
extern int apply_event_filter(struct ftrace_event_call *call,
@@ -730,7 +773,8 @@ filter_check_discard(struct ftrace_event_call *call, void *rec,
struct ring_buffer *buffer,
struct ring_buffer_event *event)
{
- if (unlikely(call->filter_active) && !filter_match_preds(call, rec)) {
+ if (unlikely(call->filter_active) &&
+ !filter_match_preds(call->filter, rec)) {
ring_buffer_discard_commit(buffer, event);
return 1;
}
diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c
index 20c5f92e28a8..878c03f386ba 100644
--- a/kernel/trace/trace_clock.c
+++ b/kernel/trace/trace_clock.c
@@ -20,6 +20,8 @@
#include <linux/ktime.h>
#include <linux/trace_clock.h>
+#include "trace.h"
+
/*
* trace_clock_local(): the simplest and least coherent tracing clock.
*
@@ -28,17 +30,17 @@
*/
u64 notrace trace_clock_local(void)
{
- unsigned long flags;
u64 clock;
+ int resched;
/*
* sched_clock() is an architecture implemented, fast, scalable,
* lockless clock. It is not guaranteed to be coherent across
* CPUs, nor across CPU idle events.
*/
- raw_local_irq_save(flags);
+ resched = ftrace_preempt_disable();
clock = sched_clock();
- raw_local_irq_restore(flags);
+ ftrace_preempt_enable(resched);
return clock;
}
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
index ead3d724599d..c16a08f399df 100644
--- a/kernel/trace/trace_entries.h
+++ b/kernel/trace/trace_entries.h
@@ -364,3 +364,19 @@ FTRACE_ENTRY(kmem_free, kmemtrace_free_entry,
F_printk("type:%u call_site:%lx ptr:%p",
__entry->type_id, __entry->call_site, __entry->ptr)
);
+
+FTRACE_ENTRY(ksym_trace, ksym_trace_entry,
+
+ TRACE_KSYM,
+
+ F_STRUCT(
+ __field( unsigned long, ip )
+ __field( unsigned char, type )
+ __array( char , cmd, TASK_COMM_LEN )
+ __field( unsigned long, addr )
+ ),
+
+ F_printk("ip: %pF type: %d ksym_name: %pS cmd: %s",
+ (void *)__entry->ip, (unsigned int)__entry->type,
+ (void *)__entry->addr, __entry->cmd)
+);
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c
index 8d5c171cc998..d9c60f80aa0d 100644
--- a/kernel/trace/trace_event_profile.c
+++ b/kernel/trace/trace_event_profile.c
@@ -8,17 +8,14 @@
#include <linux/module.h>
#include "trace.h"
-/*
- * We can't use a size but a type in alloc_percpu()
- * So let's create a dummy type that matches the desired size
- */
-typedef struct {char buf[FTRACE_MAX_PROFILE_SIZE];} profile_buf_t;
-char *trace_profile_buf;
-EXPORT_SYMBOL_GPL(trace_profile_buf);
+char *perf_trace_buf;
+EXPORT_SYMBOL_GPL(perf_trace_buf);
+
+char *perf_trace_buf_nmi;
+EXPORT_SYMBOL_GPL(perf_trace_buf_nmi);
-char *trace_profile_buf_nmi;
-EXPORT_SYMBOL_GPL(trace_profile_buf_nmi);
+typedef typeof(char [FTRACE_MAX_PROFILE_SIZE]) perf_trace_t ;
/* Count the events in use (per event id, not per instance) */
static int total_profile_count;
@@ -32,20 +29,20 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event)
return 0;
if (!total_profile_count) {
- buf = (char *)alloc_percpu(profile_buf_t);
+ buf = (char *)alloc_percpu(perf_trace_t);
if (!buf)
goto fail_buf;
- rcu_assign_pointer(trace_profile_buf, buf);
+ rcu_assign_pointer(perf_trace_buf, buf);
- buf = (char *)alloc_percpu(profile_buf_t);
+ buf = (char *)alloc_percpu(perf_trace_t);
if (!buf)
goto fail_buf_nmi;
- rcu_assign_pointer(trace_profile_buf_nmi, buf);
+ rcu_assign_pointer(perf_trace_buf_nmi, buf);
}
- ret = event->profile_enable();
+ ret = event->profile_enable(event);
if (!ret) {
total_profile_count++;
return 0;
@@ -53,10 +50,10 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event)
fail_buf_nmi:
if (!total_profile_count) {
- free_percpu(trace_profile_buf_nmi);
- free_percpu(trace_profile_buf);
- trace_profile_buf_nmi = NULL;
- trace_profile_buf = NULL;
+ free_percpu(perf_trace_buf_nmi);
+ free_percpu(perf_trace_buf);
+ perf_trace_buf_nmi = NULL;
+ perf_trace_buf = NULL;
}
fail_buf:
atomic_dec(&event->profile_count);
@@ -89,14 +86,14 @@ static void ftrace_profile_disable_event(struct ftrace_event_call *event)
if (!atomic_add_negative(-1, &event->profile_count))
return;
- event->profile_disable();
+ event->profile_disable(event);
if (!--total_profile_count) {
- buf = trace_profile_buf;
- rcu_assign_pointer(trace_profile_buf, NULL);
+ buf = perf_trace_buf;
+ rcu_assign_pointer(perf_trace_buf, NULL);
- nmi_buf = trace_profile_buf_nmi;
- rcu_assign_pointer(trace_profile_buf_nmi, NULL);
+ nmi_buf = perf_trace_buf_nmi;
+ rcu_assign_pointer(perf_trace_buf_nmi, NULL);
/*
* Ensure every events in profiling have finished before
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index d128f65778e6..1d18315dc836 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -93,9 +93,7 @@ int trace_define_common_fields(struct ftrace_event_call *call)
}
EXPORT_SYMBOL_GPL(trace_define_common_fields);
-#ifdef CONFIG_MODULES
-
-static void trace_destroy_fields(struct ftrace_event_call *call)
+void trace_destroy_fields(struct ftrace_event_call *call)
{
struct ftrace_event_field *field, *next;
@@ -107,8 +105,6 @@ static void trace_destroy_fields(struct ftrace_event_call *call)
}
}
-#endif /* CONFIG_MODULES */
-
static void ftrace_event_enable_disable(struct ftrace_event_call *call,
int enable)
{
@@ -117,14 +113,14 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call,
if (call->enabled) {
call->enabled = 0;
tracing_stop_cmdline_record();
- call->unregfunc(call->data);
+ call->unregfunc(call);
}
break;
case 1:
if (!call->enabled) {
call->enabled = 1;
tracing_start_cmdline_record();
- call->regfunc(call->data);
+ call->regfunc(call);
}
break;
}
@@ -507,7 +503,7 @@ extern char *__bad_type_size(void);
#define FIELD(type, name) \
sizeof(type) != sizeof(field.name) ? __bad_type_size() : \
#type, "common_" #name, offsetof(typeof(field), name), \
- sizeof(field.name)
+ sizeof(field.name), is_signed_type(type)
static int trace_write_header(struct trace_seq *s)
{
@@ -515,17 +511,17 @@ static int trace_write_header(struct trace_seq *s)
/* struct trace_entry */
return trace_seq_printf(s,
- "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
- "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
- "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
- "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
- "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
- "\n",
- FIELD(unsigned short, type),
- FIELD(unsigned char, flags),
- FIELD(unsigned char, preempt_count),
- FIELD(int, pid),
- FIELD(int, lock_depth));
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
+ "\n",
+ FIELD(unsigned short, type),
+ FIELD(unsigned char, flags),
+ FIELD(unsigned char, preempt_count),
+ FIELD(int, pid),
+ FIELD(int, lock_depth));
}
static ssize_t
@@ -878,9 +874,9 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
"'%s/filter' entry\n", name);
}
- entry = trace_create_file("enable", 0644, system->entry,
- (void *)system->name,
- &ftrace_system_enable_fops);
+ trace_create_file("enable", 0644, system->entry,
+ (void *)system->name,
+ &ftrace_system_enable_fops);
return system->entry;
}
@@ -892,7 +888,6 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
const struct file_operations *filter,
const struct file_operations *format)
{
- struct dentry *entry;
int ret;
/*
@@ -910,12 +905,12 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
}
if (call->regfunc)
- entry = trace_create_file("enable", 0644, call->dir, call,
- enable);
+ trace_create_file("enable", 0644, call->dir, call,
+ enable);
if (call->id && call->profile_enable)
- entry = trace_create_file("id", 0444, call->dir, call,
- id);
+ trace_create_file("id", 0444, call->dir, call,
+ id);
if (call->define_fields) {
ret = call->define_fields(call);
@@ -924,41 +919,60 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
" events/%s\n", call->name);
return ret;
}
- entry = trace_create_file("filter", 0644, call->dir, call,
- filter);
+ trace_create_file("filter", 0644, call->dir, call,
+ filter);
}
/* A trace may not want to export its format */
if (!call->show_format)
return 0;
- entry = trace_create_file("format", 0444, call->dir, call,
- format);
+ trace_create_file("format", 0444, call->dir, call,
+ format);
return 0;
}
-#define for_each_event(event, start, end) \
- for (event = start; \
- (unsigned long)event < (unsigned long)end; \
- event++)
+static int __trace_add_event_call(struct ftrace_event_call *call)
+{
+ struct dentry *d_events;
+ int ret;
-#ifdef CONFIG_MODULES
+ if (!call->name)
+ return -EINVAL;
-static LIST_HEAD(ftrace_module_file_list);
+ if (call->raw_init) {
+ ret = call->raw_init(call);
+ if (ret < 0) {
+ if (ret != -ENOSYS)
+ pr_warning("Could not initialize trace "
+ "events/%s\n", call->name);
+ return ret;
+ }
+ }
-/*
- * Modules must own their file_operations to keep up with
- * reference counting.
- */
-struct ftrace_module_file_ops {
- struct list_head list;
- struct module *mod;
- struct file_operations id;
- struct file_operations enable;
- struct file_operations format;
- struct file_operations filter;
-};
+ d_events = event_trace_events_dir();
+ if (!d_events)
+ return -ENOENT;
+
+ ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
+ &ftrace_enable_fops, &ftrace_event_filter_fops,
+ &ftrace_event_format_fops);
+ if (!ret)
+ list_add(&call->list, &ftrace_events);
+
+ return ret;
+}
+
+/* Add an additional event_call dynamically */
+int trace_add_event_call(struct ftrace_event_call *call)
+{
+ int ret;
+ mutex_lock(&event_mutex);
+ ret = __trace_add_event_call(call);
+ mutex_unlock(&event_mutex);
+ return ret;
+}
static void remove_subsystem_dir(const char *name)
{
@@ -986,6 +1000,53 @@ static void remove_subsystem_dir(const char *name)
}
}
+/*
+ * Must be called under locking both of event_mutex and trace_event_mutex.
+ */
+static void __trace_remove_event_call(struct ftrace_event_call *call)
+{
+ ftrace_event_enable_disable(call, 0);
+ if (call->event)
+ __unregister_ftrace_event(call->event);
+ debugfs_remove_recursive(call->dir);
+ list_del(&call->list);
+ trace_destroy_fields(call);
+ destroy_preds(call);
+ remove_subsystem_dir(call->system);
+}
+
+/* Remove an event_call */
+void trace_remove_event_call(struct ftrace_event_call *call)
+{
+ mutex_lock(&event_mutex);
+ down_write(&trace_event_mutex);
+ __trace_remove_event_call(call);
+ up_write(&trace_event_mutex);
+ mutex_unlock(&event_mutex);
+}
+
+#define for_each_event(event, start, end) \
+ for (event = start; \
+ (unsigned long)event < (unsigned long)end; \
+ event++)
+
+#ifdef CONFIG_MODULES
+
+static LIST_HEAD(ftrace_module_file_list);
+
+/*
+ * Modules must own their file_operations to keep up with
+ * reference counting.
+ */
+struct ftrace_module_file_ops {
+ struct list_head list;
+ struct module *mod;
+ struct file_operations id;
+ struct file_operations enable;
+ struct file_operations format;
+ struct file_operations filter;
+};
+
static struct ftrace_module_file_ops *
trace_create_file_ops(struct module *mod)
{
@@ -1043,7 +1104,7 @@ static void trace_module_add_events(struct module *mod)
if (!call->name)
continue;
if (call->raw_init) {
- ret = call->raw_init();
+ ret = call->raw_init(call);
if (ret < 0) {
if (ret != -ENOSYS)
pr_warning("Could not initialize trace "
@@ -1061,10 +1122,11 @@ static void trace_module_add_events(struct module *mod)
return;
}
call->mod = mod;
- list_add(&call->list, &ftrace_events);
- event_create_dir(call, d_events,
- &file_ops->id, &file_ops->enable,
- &file_ops->filter, &file_ops->format);
+ ret = event_create_dir(call, d_events,
+ &file_ops->id, &file_ops->enable,
+ &file_ops->filter, &file_ops->format);
+ if (!ret)
+ list_add(&call->list, &ftrace_events);
}
}
@@ -1078,14 +1140,7 @@ static void trace_module_remove_events(struct module *mod)
list_for_each_entry_safe(call, p, &ftrace_events, list) {
if (call->mod == mod) {
found = true;
- ftrace_event_enable_disable(call, 0);
- if (call->event)
- __unregister_ftrace_event(call->event);
- debugfs_remove_recursive(call->dir);
- list_del(&call->list);
- trace_destroy_fields(call);
- destroy_preds(call);
- remove_subsystem_dir(call->system);
+ __trace_remove_event_call(call);
}
}
@@ -1203,7 +1258,7 @@ static __init int event_trace_init(void)
if (!call->name)
continue;
if (call->raw_init) {
- ret = call->raw_init();
+ ret = call->raw_init(call);
if (ret < 0) {
if (ret != -ENOSYS)
pr_warning("Could not initialize trace "
@@ -1211,10 +1266,12 @@ static __init int event_trace_init(void)
continue;
}
}
- list_add(&call->list, &ftrace_events);
- event_create_dir(call, d_events, &ftrace_event_id_fops,
- &ftrace_enable_fops, &ftrace_event_filter_fops,
- &ftrace_event_format_fops);
+ ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
+ &ftrace_enable_fops,
+ &ftrace_event_filter_fops,
+ &ftrace_event_format_fops);
+ if (!ret)
+ list_add(&call->list, &ftrace_events);
}
while (true) {
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 23245785927f..50504cb228de 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -18,11 +18,10 @@
* Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
*/
-#include <linux/debugfs.h>
-#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/mutex.h>
+#include <linux/perf_event.h>
#include "trace.h"
#include "trace_output.h"
@@ -31,6 +30,7 @@ enum filter_op_ids
{
OP_OR,
OP_AND,
+ OP_GLOB,
OP_NE,
OP_EQ,
OP_LT,
@@ -48,16 +48,17 @@ struct filter_op {
};
static struct filter_op filter_ops[] = {
- { OP_OR, "||", 1 },
- { OP_AND, "&&", 2 },
- { OP_NE, "!=", 4 },
- { OP_EQ, "==", 4 },
- { OP_LT, "<", 5 },
- { OP_LE, "<=", 5 },
- { OP_GT, ">", 5 },
- { OP_GE, ">=", 5 },
- { OP_NONE, "OP_NONE", 0 },
- { OP_OPEN_PAREN, "(", 0 },
+ { OP_OR, "||", 1 },
+ { OP_AND, "&&", 2 },
+ { OP_GLOB, "~", 4 },
+ { OP_NE, "!=", 4 },
+ { OP_EQ, "==", 4 },
+ { OP_LT, "<", 5 },
+ { OP_LE, "<=", 5 },
+ { OP_GT, ">", 5 },
+ { OP_GE, ">=", 5 },
+ { OP_NONE, "OP_NONE", 0 },
+ { OP_OPEN_PAREN, "(", 0 },
};
enum {
@@ -197,9 +198,9 @@ static int filter_pred_string(struct filter_pred *pred, void *event,
char *addr = (char *)(event + pred->offset);
int cmp, match;
- cmp = strncmp(addr, pred->str_val, pred->str_len);
+ cmp = pred->regex.match(addr, &pred->regex, pred->regex.field_len);
- match = (!cmp) ^ pred->not;
+ match = cmp ^ pred->not;
return match;
}
@@ -211,9 +212,9 @@ static int filter_pred_pchar(struct filter_pred *pred, void *event,
char **addr = (char **)(event + pred->offset);
int cmp, match;
- cmp = strncmp(*addr, pred->str_val, pred->str_len);
+ cmp = pred->regex.match(*addr, &pred->regex, pred->regex.field_len);
- match = (!cmp) ^ pred->not;
+ match = cmp ^ pred->not;
return match;
}
@@ -237,9 +238,9 @@ static int filter_pred_strloc(struct filter_pred *pred, void *event,
char *addr = (char *)(event + str_loc);
int cmp, match;
- cmp = strncmp(addr, pred->str_val, str_len);
+ cmp = pred->regex.match(addr, &pred->regex, str_len);
- match = (!cmp) ^ pred->not;
+ match = cmp ^ pred->not;
return match;
}
@@ -250,10 +251,121 @@ static int filter_pred_none(struct filter_pred *pred, void *event,
return 0;
}
+/* Basic regex callbacks */
+static int regex_match_full(char *str, struct regex *r, int len)
+{
+ if (strncmp(str, r->pattern, len) == 0)
+ return 1;
+ return 0;
+}
+
+static int regex_match_front(char *str, struct regex *r, int len)
+{
+ if (strncmp(str, r->pattern, len) == 0)
+ return 1;
+ return 0;
+}
+
+static int regex_match_middle(char *str, struct regex *r, int len)
+{
+ if (strstr(str, r->pattern))
+ return 1;
+ return 0;
+}
+
+static int regex_match_end(char *str, struct regex *r, int len)
+{
+ char *ptr = strstr(str, r->pattern);
+
+ if (ptr && (ptr[r->len] == 0))
+ return 1;
+ return 0;
+}
+
+/**
+ * filter_parse_regex - parse a basic regex
+ * @buff: the raw regex
+ * @len: length of the regex
+ * @search: will point to the beginning of the string to compare
+ * @not: tell whether the match will have to be inverted
+ *
+ * This passes in a buffer containing a regex and this function will
+ * set search to point to the search part of the buffer and
+ * return the type of search it is (see enum above).
+ * This does modify buff.
+ *
+ * Returns enum type.
+ * search returns the pointer to use for comparison.
+ * not returns 1 if buff started with a '!'
+ * 0 otherwise.
+ */
+enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)
+{
+ int type = MATCH_FULL;
+ int i;
+
+ if (buff[0] == '!') {
+ *not = 1;
+ buff++;
+ len--;
+ } else
+ *not = 0;
+
+ *search = buff;
+
+ for (i = 0; i < len; i++) {
+ if (buff[i] == '*') {
+ if (!i) {
+ *search = buff + 1;
+ type = MATCH_END_ONLY;
+ } else {
+ if (type == MATCH_END_ONLY)
+ type = MATCH_MIDDLE_ONLY;
+ else
+ type = MATCH_FRONT_ONLY;
+ buff[i] = 0;
+ break;
+ }
+ }
+ }
+
+ return type;
+}
+
+static void filter_build_regex(struct filter_pred *pred)
+{
+ struct regex *r = &pred->regex;
+ char *search;
+ enum regex_type type = MATCH_FULL;
+ int not = 0;
+
+ if (pred->op == OP_GLOB) {
+ type = filter_parse_regex(r->pattern, r->len, &search, &not);
+ r->len = strlen(search);
+ memmove(r->pattern, search, r->len+1);
+ }
+
+ switch (type) {
+ case MATCH_FULL:
+ r->match = regex_match_full;
+ break;
+ case MATCH_FRONT_ONLY:
+ r->match = regex_match_front;
+ break;
+ case MATCH_MIDDLE_ONLY:
+ r->match = regex_match_middle;
+ break;
+ case MATCH_END_ONLY:
+ r->match = regex_match_end;
+ break;
+ }
+
+ pred->not ^= not;
+}
+
/* return 1 if event matches, 0 otherwise (discard) */
-int filter_match_preds(struct ftrace_event_call *call, void *rec)
+int filter_match_preds(struct event_filter *filter, void *rec)
{
- struct event_filter *filter = call->filter;
int match, top = 0, val1 = 0, val2 = 0;
int stack[MAX_FILTER_PRED];
struct filter_pred *pred;
@@ -396,7 +508,7 @@ static void filter_clear_pred(struct filter_pred *pred)
{
kfree(pred->field_name);
pred->field_name = NULL;
- pred->str_len = 0;
+ pred->regex.len = 0;
}
static int filter_set_pred(struct filter_pred *dest,
@@ -426,9 +538,8 @@ static void filter_disable_preds(struct ftrace_event_call *call)
filter->preds[i]->fn = filter_pred_none;
}
-void destroy_preds(struct ftrace_event_call *call)
+static void __free_preds(struct event_filter *filter)
{
- struct event_filter *filter = call->filter;
int i;
if (!filter)
@@ -441,21 +552,24 @@ void destroy_preds(struct ftrace_event_call *call)
kfree(filter->preds);
kfree(filter->filter_string);
kfree(filter);
+}
+
+void destroy_preds(struct ftrace_event_call *call)
+{
+ __free_preds(call->filter);
call->filter = NULL;
+ call->filter_active = 0;
}
-static int init_preds(struct ftrace_event_call *call)
+static struct event_filter *__alloc_preds(void)
{
struct event_filter *filter;
struct filter_pred *pred;
int i;
- if (call->filter)
- return 0;
-
- filter = call->filter = kzalloc(sizeof(*filter), GFP_KERNEL);
- if (!call->filter)
- return -ENOMEM;
+ filter = kzalloc(sizeof(*filter), GFP_KERNEL);
+ if (!filter)
+ return ERR_PTR(-ENOMEM);
filter->n_preds = 0;
@@ -471,12 +585,24 @@ static int init_preds(struct ftrace_event_call *call)
filter->preds[i] = pred;
}
- return 0;
+ return filter;
oom:
- destroy_preds(call);
+ __free_preds(filter);
+ return ERR_PTR(-ENOMEM);
+}
+
+static int init_preds(struct ftrace_event_call *call)
+{
+ if (call->filter)
+ return 0;
+
+ call->filter_active = 0;
+ call->filter = __alloc_preds();
+ if (IS_ERR(call->filter))
+ return PTR_ERR(call->filter);
- return -ENOMEM;
+ return 0;
}
static int init_subsystem_preds(struct event_subsystem *system)
@@ -499,14 +625,7 @@ static int init_subsystem_preds(struct event_subsystem *system)
return 0;
}
-enum {
- FILTER_DISABLE_ALL,
- FILTER_INIT_NO_RESET,
- FILTER_SKIP_NO_RESET,
-};
-
-static void filter_free_subsystem_preds(struct event_subsystem *system,
- int flag)
+static void filter_free_subsystem_preds(struct event_subsystem *system)
{
struct ftrace_event_call *call;
@@ -517,14 +636,6 @@ static void filter_free_subsystem_preds(struct event_subsystem *system,
if (strcmp(call->system, system->name) != 0)
continue;
- if (flag == FILTER_INIT_NO_RESET) {
- call->filter->no_reset = false;
- continue;
- }
-
- if (flag == FILTER_SKIP_NO_RESET && call->filter->no_reset)
- continue;
-
filter_disable_preds(call);
remove_filter_string(call->filter);
}
@@ -532,10 +643,10 @@ static void filter_free_subsystem_preds(struct event_subsystem *system,
static int filter_add_pred_fn(struct filter_parse_state *ps,
struct ftrace_event_call *call,
+ struct event_filter *filter,
struct filter_pred *pred,
filter_pred_fn_t fn)
{
- struct event_filter *filter = call->filter;
int idx, err;
if (filter->n_preds == MAX_FILTER_PRED) {
@@ -550,7 +661,6 @@ static int filter_add_pred_fn(struct filter_parse_state *ps,
return err;
filter->n_preds++;
- call->filter_active = 1;
return 0;
}
@@ -575,7 +685,10 @@ static bool is_string_field(struct ftrace_event_field *field)
static int is_legal_op(struct ftrace_event_field *field, int op)
{
- if (is_string_field(field) && (op != OP_EQ && op != OP_NE))
+ if (is_string_field(field) &&
+ (op != OP_EQ && op != OP_NE && op != OP_GLOB))
+ return 0;
+ if (!is_string_field(field) && op == OP_GLOB)
return 0;
return 1;
@@ -626,6 +739,7 @@ static filter_pred_fn_t select_comparison_fn(int op, int field_size,
static int filter_add_pred(struct filter_parse_state *ps,
struct ftrace_event_call *call,
+ struct event_filter *filter,
struct filter_pred *pred,
bool dry_run)
{
@@ -660,21 +774,22 @@ static int filter_add_pred(struct filter_parse_state *ps,
}
if (is_string_field(field)) {
- pred->str_len = field->size;
+ filter_build_regex(pred);
- if (field->filter_type == FILTER_STATIC_STRING)
+ if (field->filter_type == FILTER_STATIC_STRING) {
fn = filter_pred_string;
- else if (field->filter_type == FILTER_DYN_STRING)
+ pred->regex.field_len = field->size;
+ } else if (field->filter_type == FILTER_DYN_STRING)
fn = filter_pred_strloc;
else {
fn = filter_pred_pchar;
- pred->str_len = strlen(pred->str_val);
+ pred->regex.field_len = strlen(pred->regex.pattern);
}
} else {
if (field->is_signed)
- ret = strict_strtoll(pred->str_val, 0, &val);
+ ret = strict_strtoll(pred->regex.pattern, 0, &val);
else
- ret = strict_strtoull(pred->str_val, 0, &val);
+ ret = strict_strtoull(pred->regex.pattern, 0, &val);
if (ret) {
parse_error(ps, FILT_ERR_ILLEGAL_INTVAL, 0);
return -EINVAL;
@@ -694,45 +809,7 @@ static int filter_add_pred(struct filter_parse_state *ps,
add_pred_fn:
if (!dry_run)
- return filter_add_pred_fn(ps, call, pred, fn);
- return 0;
-}
-
-static int filter_add_subsystem_pred(struct filter_parse_state *ps,
- struct event_subsystem *system,
- struct filter_pred *pred,
- char *filter_string,
- bool dry_run)
-{
- struct ftrace_event_call *call;
- int err = 0;
- bool fail = true;
-
- list_for_each_entry(call, &ftrace_events, list) {
-
- if (!call->define_fields)
- continue;
-
- if (strcmp(call->system, system->name))
- continue;
-
- if (call->filter->no_reset)
- continue;
-
- err = filter_add_pred(ps, call, pred, dry_run);
- if (err)
- call->filter->no_reset = true;
- else
- fail = false;
-
- if (!dry_run)
- replace_filter_string(call->filter, filter_string);
- }
-
- if (fail) {
- parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0);
- return err;
- }
+ return filter_add_pred_fn(ps, call, filter, pred, fn);
return 0;
}
@@ -933,8 +1010,9 @@ static void postfix_clear(struct filter_parse_state *ps)
while (!list_empty(&ps->postfix)) {
elt = list_first_entry(&ps->postfix, struct postfix_elt, list);
- kfree(elt->operand);
list_del(&elt->list);
+ kfree(elt->operand);
+ kfree(elt);
}
}
@@ -1044,8 +1122,8 @@ static struct filter_pred *create_pred(int op, char *operand1, char *operand2)
return NULL;
}
- strcpy(pred->str_val, operand2);
- pred->str_len = strlen(operand2);
+ strcpy(pred->regex.pattern, operand2);
+ pred->regex.len = strlen(pred->regex.pattern);
pred->op = op;
@@ -1089,8 +1167,8 @@ static int check_preds(struct filter_parse_state *ps)
return 0;
}
-static int replace_preds(struct event_subsystem *system,
- struct ftrace_event_call *call,
+static int replace_preds(struct ftrace_event_call *call,
+ struct event_filter *filter,
struct filter_parse_state *ps,
char *filter_string,
bool dry_run)
@@ -1137,11 +1215,7 @@ static int replace_preds(struct event_subsystem *system,
add_pred:
if (!pred)
return -ENOMEM;
- if (call)
- err = filter_add_pred(ps, call, pred, false);
- else
- err = filter_add_subsystem_pred(ps, system, pred,
- filter_string, dry_run);
+ err = filter_add_pred(ps, call, filter, pred, dry_run);
filter_free_pred(pred);
if (err)
return err;
@@ -1152,10 +1226,50 @@ add_pred:
return 0;
}
-int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
+static int replace_system_preds(struct event_subsystem *system,
+ struct filter_parse_state *ps,
+ char *filter_string)
{
+ struct ftrace_event_call *call;
+ bool fail = true;
int err;
+ list_for_each_entry(call, &ftrace_events, list) {
+ struct event_filter *filter = call->filter;
+
+ if (!call->define_fields)
+ continue;
+
+ if (strcmp(call->system, system->name) != 0)
+ continue;
+
+ /* try to see if the filter can be applied */
+ err = replace_preds(call, filter, ps, filter_string, true);
+ if (err)
+ continue;
+
+ /* really apply the filter */
+ filter_disable_preds(call);
+ err = replace_preds(call, filter, ps, filter_string, false);
+ if (err)
+ filter_disable_preds(call);
+ else {
+ call->filter_active = 1;
+ replace_filter_string(filter, filter_string);
+ }
+ fail = false;
+ }
+
+ if (fail) {
+ parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
+{
+ int err;
struct filter_parse_state *ps;
mutex_lock(&event_mutex);
@@ -1167,8 +1281,7 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
if (!strcmp(strstrip(filter_string), "0")) {
filter_disable_preds(call);
remove_filter_string(call->filter);
- mutex_unlock(&event_mutex);
- return 0;
+ goto out_unlock;
}
err = -ENOMEM;
@@ -1186,10 +1299,11 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
goto out;
}
- err = replace_preds(NULL, call, ps, filter_string, false);
+ err = replace_preds(call, call->filter, ps, filter_string, false);
if (err)
append_filter_err(ps, call->filter);
-
+ else
+ call->filter_active = 1;
out:
filter_opstack_clear(ps);
postfix_clear(ps);
@@ -1204,7 +1318,6 @@ int apply_subsystem_event_filter(struct event_subsystem *system,
char *filter_string)
{
int err;
-
struct filter_parse_state *ps;
mutex_lock(&event_mutex);
@@ -1214,10 +1327,9 @@ int apply_subsystem_event_filter(struct event_subsystem *system,
goto out_unlock;
if (!strcmp(strstrip(filter_string), "0")) {
- filter_free_subsystem_preds(system, FILTER_DISABLE_ALL);
+ filter_free_subsystem_preds(system);
remove_filter_string(system->filter);
- mutex_unlock(&event_mutex);
- return 0;
+ goto out_unlock;
}
err = -ENOMEM;
@@ -1234,31 +1346,87 @@ int apply_subsystem_event_filter(struct event_subsystem *system,
goto out;
}
- filter_free_subsystem_preds(system, FILTER_INIT_NO_RESET);
-
- /* try to see the filter can be applied to which events */
- err = replace_preds(system, NULL, ps, filter_string, true);
- if (err) {
+ err = replace_system_preds(system, ps, filter_string);
+ if (err)
append_filter_err(ps, system->filter);
- goto out;
+
+out:
+ filter_opstack_clear(ps);
+ postfix_clear(ps);
+ kfree(ps);
+out_unlock:
+ mutex_unlock(&event_mutex);
+
+ return err;
+}
+
+#ifdef CONFIG_EVENT_PROFILE
+
+void ftrace_profile_free_filter(struct perf_event *event)
+{
+ struct event_filter *filter = event->filter;
+
+ event->filter = NULL;
+ __free_preds(filter);
+}
+
+int ftrace_profile_set_filter(struct perf_event *event, int event_id,
+ char *filter_str)
+{
+ int err;
+ struct event_filter *filter;
+ struct filter_parse_state *ps;
+ struct ftrace_event_call *call = NULL;
+
+ mutex_lock(&event_mutex);
+
+ list_for_each_entry(call, &ftrace_events, list) {
+ if (call->id == event_id)
+ break;
}
- filter_free_subsystem_preds(system, FILTER_SKIP_NO_RESET);
+ err = -EINVAL;
+ if (!call)
+ goto out_unlock;
- /* really apply the filter to the events */
- err = replace_preds(system, NULL, ps, filter_string, false);
- if (err) {
- append_filter_err(ps, system->filter);
- filter_free_subsystem_preds(system, 2);
+ err = -EEXIST;
+ if (event->filter)
+ goto out_unlock;
+
+ filter = __alloc_preds();
+ if (IS_ERR(filter)) {
+ err = PTR_ERR(filter);
+ goto out_unlock;
}
-out:
+ err = -ENOMEM;
+ ps = kzalloc(sizeof(*ps), GFP_KERNEL);
+ if (!ps)
+ goto free_preds;
+
+ parse_init(ps, filter_ops, filter_str);
+ err = filter_parse(ps);
+ if (err)
+ goto free_ps;
+
+ err = replace_preds(call, filter, ps, filter_str, false);
+ if (!err)
+ event->filter = filter;
+
+free_ps:
filter_opstack_clear(ps);
postfix_clear(ps);
kfree(ps);
+
+free_preds:
+ if (err)
+ __free_preds(filter);
+
out_unlock:
mutex_unlock(&event_mutex);
return err;
}
+#endif /* CONFIG_EVENT_PROFILE */
+
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index 9753fcc61bc5..dff8c84ddf17 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -48,11 +48,11 @@
struct ____ftrace_##name { \
tstruct \
}; \
-static void __used ____ftrace_check_##name(void) \
+static void __always_unused ____ftrace_check_##name(void) \
{ \
struct ____ftrace_##name *__entry = NULL; \
\
- /* force cmpile-time check on F_printk() */ \
+ /* force compile-time check on F_printk() */ \
printk(print); \
}
@@ -66,44 +66,47 @@ static void __used ____ftrace_check_##name(void) \
#undef __field
#define __field(type, item) \
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
- "offset:%zu;\tsize:%zu;\n", \
+ "offset:%zu;\tsize:%zu;\tsigned:%u;\n", \
offsetof(typeof(field), item), \
- sizeof(field.item)); \
+ sizeof(field.item), is_signed_type(type)); \
if (!ret) \
return 0;
#undef __field_desc
#define __field_desc(type, container, item) \
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
- "offset:%zu;\tsize:%zu;\n", \
+ "offset:%zu;\tsize:%zu;\tsigned:%u;\n", \
offsetof(typeof(field), container.item), \
- sizeof(field.container.item)); \
+ sizeof(field.container.item), \
+ is_signed_type(type)); \
if (!ret) \
return 0;
#undef __array
#define __array(type, item, len) \
ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
- "offset:%zu;\tsize:%zu;\n", \
- offsetof(typeof(field), item), \
- sizeof(field.item)); \
+ "offset:%zu;\tsize:%zu;\tsigned:%u;\n", \
+ offsetof(typeof(field), item), \
+ sizeof(field.item), is_signed_type(type)); \
if (!ret) \
return 0;
#undef __array_desc
#define __array_desc(type, container, item, len) \
ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
- "offset:%zu;\tsize:%zu;\n", \
+ "offset:%zu;\tsize:%zu;\tsigned:%u;\n", \
offsetof(typeof(field), container.item), \
- sizeof(field.container.item)); \
+ sizeof(field.container.item), \
+ is_signed_type(type)); \
if (!ret) \
return 0;
#undef __dynamic_array
#define __dynamic_array(type, item) \
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
- "offset:%zu;\tsize:0;\n", \
- offsetof(typeof(field), item)); \
+ "offset:%zu;\tsize:0;\tsigned:%u;\n", \
+ offsetof(typeof(field), item), \
+ is_signed_type(type)); \
if (!ret) \
return 0;
@@ -131,7 +134,6 @@ ftrace_format_##name(struct ftrace_event_call *unused, \
#include "trace_entries.h"
-
#undef __field
#define __field(type, item) \
ret = trace_define_field(event_call, #type, #item, \
@@ -193,6 +195,11 @@ ftrace_define_fields_##name(struct ftrace_event_call *event_call) \
#include "trace_entries.h"
+static int ftrace_raw_init_event(struct ftrace_event_call *call)
+{
+ INIT_LIST_HEAD(&call->fields);
+ return 0;
+}
#undef __field
#define __field(type, item)
@@ -211,7 +218,6 @@ ftrace_define_fields_##name(struct ftrace_event_call *event_call) \
#undef FTRACE_ENTRY
#define FTRACE_ENTRY(call, struct_name, type, tstruct, print) \
-static int ftrace_raw_init_event_##call(void); \
\
struct ftrace_event_call __used \
__attribute__((__aligned__(4))) \
@@ -219,14 +225,9 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
.name = #call, \
.id = type, \
.system = __stringify(TRACE_SYSTEM), \
- .raw_init = ftrace_raw_init_event_##call, \
+ .raw_init = ftrace_raw_init_event, \
.show_format = ftrace_format_##call, \
.define_fields = ftrace_define_fields_##call, \
}; \
-static int ftrace_raw_init_event_##call(void) \
-{ \
- INIT_LIST_HEAD(&event_##call.fields); \
- return 0; \
-} \
#include "trace_entries.h"
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
new file mode 100644
index 000000000000..aff5f80b59b8
--- /dev/null
+++ b/kernel/trace/trace_kprobe.c
@@ -0,0 +1,1523 @@
+/*
+ * Kprobes-based tracing events
+ *
+ * Created by Masami Hiramatsu <mhiramat@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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/kprobes.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/debugfs.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/ptrace.h>
+#include <linux/perf_event.h>
+
+#include "trace.h"
+#include "trace_output.h"
+
+#define MAX_TRACE_ARGS 128
+#define MAX_ARGSTR_LEN 63
+#define MAX_EVENT_NAME_LEN 64
+#define KPROBE_EVENT_SYSTEM "kprobes"
+
+/* Reserved field names */
+#define FIELD_STRING_IP "__probe_ip"
+#define FIELD_STRING_NARGS "__probe_nargs"
+#define FIELD_STRING_RETIP "__probe_ret_ip"
+#define FIELD_STRING_FUNC "__probe_func"
+
+const char *reserved_field_names[] = {
+ "common_type",
+ "common_flags",
+ "common_preempt_count",
+ "common_pid",
+ "common_tgid",
+ "common_lock_depth",
+ FIELD_STRING_IP,
+ FIELD_STRING_NARGS,
+ FIELD_STRING_RETIP,
+ FIELD_STRING_FUNC,
+};
+
+struct fetch_func {
+ unsigned long (*func)(struct pt_regs *, void *);
+ void *data;
+};
+
+static __kprobes unsigned long call_fetch(struct fetch_func *f,
+ struct pt_regs *regs)
+{
+ return f->func(regs, f->data);
+}
+
+/* fetch handlers */
+static __kprobes unsigned long fetch_register(struct pt_regs *regs,
+ void *offset)
+{
+ return regs_get_register(regs, (unsigned int)((unsigned long)offset));
+}
+
+static __kprobes unsigned long fetch_stack(struct pt_regs *regs,
+ void *num)
+{
+ return regs_get_kernel_stack_nth(regs,
+ (unsigned int)((unsigned long)num));
+}
+
+static __kprobes unsigned long fetch_memory(struct pt_regs *regs, void *addr)
+{
+ unsigned long retval;
+
+ if (probe_kernel_address(addr, retval))
+ return 0;
+ return retval;
+}
+
+static __kprobes unsigned long fetch_argument(struct pt_regs *regs, void *num)
+{
+ return regs_get_argument_nth(regs, (unsigned int)((unsigned long)num));
+}
+
+static __kprobes unsigned long fetch_retvalue(struct pt_regs *regs,
+ void *dummy)
+{
+ return regs_return_value(regs);
+}
+
+static __kprobes unsigned long fetch_stack_address(struct pt_regs *regs,
+ void *dummy)
+{
+ return kernel_stack_pointer(regs);
+}
+
+/* Memory fetching by symbol */
+struct symbol_cache {
+ char *symbol;
+ long offset;
+ unsigned long addr;
+};
+
+static unsigned long update_symbol_cache(struct symbol_cache *sc)
+{
+ sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol);
+ if (sc->addr)
+ sc->addr += sc->offset;
+ return sc->addr;
+}
+
+static void free_symbol_cache(struct symbol_cache *sc)
+{
+ kfree(sc->symbol);
+ kfree(sc);
+}
+
+static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
+{
+ struct symbol_cache *sc;
+
+ if (!sym || strlen(sym) == 0)
+ return NULL;
+ sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL);
+ if (!sc)
+ return NULL;
+
+ sc->symbol = kstrdup(sym, GFP_KERNEL);
+ if (!sc->symbol) {
+ kfree(sc);
+ return NULL;
+ }
+ sc->offset = offset;
+
+ update_symbol_cache(sc);
+ return sc;
+}
+
+static __kprobes unsigned long fetch_symbol(struct pt_regs *regs, void *data)
+{
+ struct symbol_cache *sc = data;
+
+ if (sc->addr)
+ return fetch_memory(regs, (void *)sc->addr);
+ else
+ return 0;
+}
+
+/* Special indirect memory access interface */
+struct indirect_fetch_data {
+ struct fetch_func orig;
+ long offset;
+};
+
+static __kprobes unsigned long fetch_indirect(struct pt_regs *regs, void *data)
+{
+ struct indirect_fetch_data *ind = data;
+ unsigned long addr;
+
+ addr = call_fetch(&ind->orig, regs);
+ if (addr) {
+ addr += ind->offset;
+ return fetch_memory(regs, (void *)addr);
+ } else
+ return 0;
+}
+
+static __kprobes void free_indirect_fetch_data(struct indirect_fetch_data *data)
+{
+ if (data->orig.func == fetch_indirect)
+ free_indirect_fetch_data(data->orig.data);
+ else if (data->orig.func == fetch_symbol)
+ free_symbol_cache(data->orig.data);
+ kfree(data);
+}
+
+/**
+ * Kprobe event core functions
+ */
+
+struct probe_arg {
+ struct fetch_func fetch;
+ const char *name;
+};
+
+/* Flags for trace_probe */
+#define TP_FLAG_TRACE 1
+#define TP_FLAG_PROFILE 2
+
+struct trace_probe {
+ struct list_head list;
+ struct kretprobe rp; /* Use rp.kp for kprobe use */
+ unsigned long nhit;
+ unsigned int flags; /* For TP_FLAG_* */
+ const char *symbol; /* symbol name */
+ struct ftrace_event_call call;
+ struct trace_event event;
+ unsigned int nr_args;
+ struct probe_arg args[];
+};
+
+#define SIZEOF_TRACE_PROBE(n) \
+ (offsetof(struct trace_probe, args) + \
+ (sizeof(struct probe_arg) * (n)))
+
+static __kprobes int probe_is_return(struct trace_probe *tp)
+{
+ return tp->rp.handler != NULL;
+}
+
+static __kprobes const char *probe_symbol(struct trace_probe *tp)
+{
+ return tp->symbol ? tp->symbol : "unknown";
+}
+
+static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff)
+{
+ int ret = -EINVAL;
+
+ if (ff->func == fetch_argument)
+ ret = snprintf(buf, n, "$arg%lu", (unsigned long)ff->data);
+ else if (ff->func == fetch_register) {
+ const char *name;
+ name = regs_query_register_name((unsigned int)((long)ff->data));
+ ret = snprintf(buf, n, "%%%s", name);
+ } else if (ff->func == fetch_stack)
+ ret = snprintf(buf, n, "$stack%lu", (unsigned long)ff->data);
+ else if (ff->func == fetch_memory)
+ ret = snprintf(buf, n, "@0x%p", ff->data);
+ else if (ff->func == fetch_symbol) {
+ struct symbol_cache *sc = ff->data;
+ if (sc->offset)
+ ret = snprintf(buf, n, "@%s%+ld", sc->symbol,
+ sc->offset);
+ else
+ ret = snprintf(buf, n, "@%s", sc->symbol);
+ } else if (ff->func == fetch_retvalue)
+ ret = snprintf(buf, n, "$retval");
+ else if (ff->func == fetch_stack_address)
+ ret = snprintf(buf, n, "$stack");
+ else if (ff->func == fetch_indirect) {
+ struct indirect_fetch_data *id = ff->data;
+ size_t l = 0;
+ ret = snprintf(buf, n, "%+ld(", id->offset);
+ if (ret >= n)
+ goto end;
+ l += ret;
+ ret = probe_arg_string(buf + l, n - l, &id->orig);
+ if (ret < 0)
+ goto end;
+ l += ret;
+ ret = snprintf(buf + l, n - l, ")");
+ ret += l;
+ }
+end:
+ if (ret >= n)
+ return -ENOSPC;
+ return ret;
+}
+
+static int register_probe_event(struct trace_probe *tp);
+static void unregister_probe_event(struct trace_probe *tp);
+
+static DEFINE_MUTEX(probe_lock);
+static LIST_HEAD(probe_list);
+
+static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
+static int kretprobe_dispatcher(struct kretprobe_instance *ri,
+ struct pt_regs *regs);
+
+/*
+ * Allocate new trace_probe and initialize it (including kprobes).
+ */
+static struct trace_probe *alloc_trace_probe(const char *group,
+ const char *event,
+ void *addr,
+ const char *symbol,
+ unsigned long offs,
+ int nargs, int is_return)
+{
+ struct trace_probe *tp;
+
+ tp = kzalloc(SIZEOF_TRACE_PROBE(nargs), GFP_KERNEL);
+ if (!tp)
+ return ERR_PTR(-ENOMEM);
+
+ if (symbol) {
+ tp->symbol = kstrdup(symbol, GFP_KERNEL);
+ if (!tp->symbol)
+ goto error;
+ tp->rp.kp.symbol_name = tp->symbol;
+ tp->rp.kp.offset = offs;
+ } else
+ tp->rp.kp.addr = addr;
+
+ if (is_return)
+ tp->rp.handler = kretprobe_dispatcher;
+ else
+ tp->rp.kp.pre_handler = kprobe_dispatcher;
+
+ if (!event)
+ goto error;
+ tp->call.name = kstrdup(event, GFP_KERNEL);
+ if (!tp->call.name)
+ goto error;
+
+ if (!group)
+ goto error;
+ tp->call.system = kstrdup(group, GFP_KERNEL);
+ if (!tp->call.system)
+ goto error;
+
+ INIT_LIST_HEAD(&tp->list);
+ return tp;
+error:
+ kfree(tp->call.name);
+ kfree(tp->symbol);
+ kfree(tp);
+ return ERR_PTR(-ENOMEM);
+}
+
+static void free_probe_arg(struct probe_arg *arg)
+{
+ if (arg->fetch.func == fetch_symbol)
+ free_symbol_cache(arg->fetch.data);
+ else if (arg->fetch.func == fetch_indirect)
+ free_indirect_fetch_data(arg->fetch.data);
+ kfree(arg->name);
+}
+
+static void free_trace_probe(struct trace_probe *tp)
+{
+ int i;
+
+ for (i = 0; i < tp->nr_args; i++)
+ free_probe_arg(&tp->args[i]);
+
+ kfree(tp->call.system);
+ kfree(tp->call.name);
+ kfree(tp->symbol);
+ kfree(tp);
+}
+
+static struct trace_probe *find_probe_event(const char *event,
+ const char *group)
+{
+ struct trace_probe *tp;
+
+ list_for_each_entry(tp, &probe_list, list)
+ if (strcmp(tp->call.name, event) == 0 &&
+ strcmp(tp->call.system, group) == 0)
+ return tp;
+ return NULL;
+}
+
+/* Unregister a trace_probe and probe_event: call with locking probe_lock */
+static void unregister_trace_probe(struct trace_probe *tp)
+{
+ if (probe_is_return(tp))
+ unregister_kretprobe(&tp->rp);
+ else
+ unregister_kprobe(&tp->rp.kp);
+ list_del(&tp->list);
+ unregister_probe_event(tp);
+}
+
+/* Register a trace_probe and probe_event */
+static int register_trace_probe(struct trace_probe *tp)
+{
+ struct trace_probe *old_tp;
+ int ret;
+
+ mutex_lock(&probe_lock);
+
+ /* register as an event */
+ old_tp = find_probe_event(tp->call.name, tp->call.system);
+ if (old_tp) {
+ /* delete old event */
+ unregister_trace_probe(old_tp);
+ free_trace_probe(old_tp);
+ }
+ ret = register_probe_event(tp);
+ if (ret) {
+ pr_warning("Faild to register probe event(%d)\n", ret);
+ goto end;
+ }
+
+ tp->rp.kp.flags |= KPROBE_FLAG_DISABLED;
+ if (probe_is_return(tp))
+ ret = register_kretprobe(&tp->rp);
+ else
+ ret = register_kprobe(&tp->rp.kp);
+
+ if (ret) {
+ pr_warning("Could not insert probe(%d)\n", ret);
+ if (ret == -EILSEQ) {
+ pr_warning("Probing address(0x%p) is not an "
+ "instruction boundary.\n",
+ tp->rp.kp.addr);
+ ret = -EINVAL;
+ }
+ unregister_probe_event(tp);
+ } else
+ list_add_tail(&tp->list, &probe_list);
+end:
+ mutex_unlock(&probe_lock);
+ return ret;
+}
+
+/* Split symbol and offset. */
+static int split_symbol_offset(char *symbol, unsigned long *offset)
+{
+ char *tmp;
+ int ret;
+
+ if (!offset)
+ return -EINVAL;
+
+ tmp = strchr(symbol, '+');
+ if (tmp) {
+ /* skip sign because strict_strtol doesn't accept '+' */
+ ret = strict_strtoul(tmp + 1, 0, offset);
+ if (ret)
+ return ret;
+ *tmp = '\0';
+ } else
+ *offset = 0;
+ return 0;
+}
+
+#define PARAM_MAX_ARGS 16
+#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
+
+static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return)
+{
+ int ret = 0;
+ unsigned long param;
+
+ if (strcmp(arg, "retval") == 0) {
+ if (is_return) {
+ ff->func = fetch_retvalue;
+ ff->data = NULL;
+ } else
+ ret = -EINVAL;
+ } else if (strncmp(arg, "stack", 5) == 0) {
+ if (arg[5] == '\0') {
+ ff->func = fetch_stack_address;
+ ff->data = NULL;
+ } else if (isdigit(arg[5])) {
+ ret = strict_strtoul(arg + 5, 10, &param);
+ if (ret || param > PARAM_MAX_STACK)
+ ret = -EINVAL;
+ else {
+ ff->func = fetch_stack;
+ ff->data = (void *)param;
+ }
+ } else
+ ret = -EINVAL;
+ } else if (strncmp(arg, "arg", 3) == 0 && isdigit(arg[3])) {
+ ret = strict_strtoul(arg + 3, 10, &param);
+ if (ret || param > PARAM_MAX_ARGS)
+ ret = -EINVAL;
+ else {
+ ff->func = fetch_argument;
+ ff->data = (void *)param;
+ }
+ } else
+ ret = -EINVAL;
+ return ret;
+}
+
+/* Recursive argument parser */
+static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
+{
+ int ret = 0;
+ unsigned long param;
+ long offset;
+ char *tmp;
+
+ switch (arg[0]) {
+ case '$':
+ ret = parse_probe_vars(arg + 1, ff, is_return);
+ break;
+ case '%': /* named register */
+ ret = regs_query_register_offset(arg + 1);
+ if (ret >= 0) {
+ ff->func = fetch_register;
+ ff->data = (void *)(unsigned long)ret;
+ ret = 0;
+ }
+ break;
+ case '@': /* memory or symbol */
+ if (isdigit(arg[1])) {
+ ret = strict_strtoul(arg + 1, 0, &param);
+ if (ret)
+ break;
+ ff->func = fetch_memory;
+ ff->data = (void *)param;
+ } else {
+ ret = split_symbol_offset(arg + 1, &offset);
+ if (ret)
+ break;
+ ff->data = alloc_symbol_cache(arg + 1, offset);
+ if (ff->data)
+ ff->func = fetch_symbol;
+ else
+ ret = -EINVAL;
+ }
+ break;
+ case '+': /* indirect memory */
+ case '-':
+ tmp = strchr(arg, '(');
+ if (!tmp) {
+ ret = -EINVAL;
+ break;
+ }
+ *tmp = '\0';
+ ret = strict_strtol(arg + 1, 0, &offset);
+ if (ret)
+ break;
+ if (arg[0] == '-')
+ offset = -offset;
+ arg = tmp + 1;
+ tmp = strrchr(arg, ')');
+ if (tmp) {
+ struct indirect_fetch_data *id;
+ *tmp = '\0';
+ id = kzalloc(sizeof(struct indirect_fetch_data),
+ GFP_KERNEL);
+ if (!id)
+ return -ENOMEM;
+ id->offset = offset;
+ ret = __parse_probe_arg(arg, &id->orig, is_return);
+ if (ret)
+ kfree(id);
+ else {
+ ff->func = fetch_indirect;
+ ff->data = (void *)id;
+ }
+ } else
+ ret = -EINVAL;
+ break;
+ default:
+ /* TODO: support custom handler */
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+/* String length checking wrapper */
+static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
+{
+ if (strlen(arg) > MAX_ARGSTR_LEN) {
+ pr_info("Argument is too long.: %s\n", arg);
+ return -ENOSPC;
+ }
+ return __parse_probe_arg(arg, ff, is_return);
+}
+
+/* Return 1 if name is reserved or already used by another argument */
+static int conflict_field_name(const char *name,
+ struct probe_arg *args, int narg)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++)
+ if (strcmp(reserved_field_names[i], name) == 0)
+ return 1;
+ for (i = 0; i < narg; i++)
+ if (strcmp(args[i].name, name) == 0)
+ return 1;
+ return 0;
+}
+
+static int create_trace_probe(int argc, char **argv)
+{
+ /*
+ * Argument syntax:
+ * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS]
+ * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS]
+ * Fetch args:
+ * $argN : fetch Nth of function argument. (N:0-)
+ * $retval : fetch return value
+ * $stack : fetch stack address
+ * $stackN : fetch Nth of stack (N:0-)
+ * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
+ * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
+ * %REG : fetch register REG
+ * Indirect memory fetch:
+ * +|-offs(ARG) : fetch memory at ARG +|- offs address.
+ * Alias name of args:
+ * NAME=FETCHARG : set NAME as alias of FETCHARG.
+ */
+ struct trace_probe *tp;
+ int i, ret = 0;
+ int is_return = 0;
+ char *symbol = NULL, *event = NULL, *arg = NULL, *group = NULL;
+ unsigned long offset = 0;
+ void *addr = NULL;
+ char buf[MAX_EVENT_NAME_LEN];
+
+ if (argc < 2) {
+ pr_info("Probe point is not specified.\n");
+ return -EINVAL;
+ }
+
+ if (argv[0][0] == 'p')
+ is_return = 0;
+ else if (argv[0][0] == 'r')
+ is_return = 1;
+ else {
+ pr_info("Probe definition must be started with 'p' or 'r'.\n");
+ return -EINVAL;
+ }
+
+ if (argv[0][1] == ':') {
+ event = &argv[0][2];
+ if (strchr(event, '/')) {
+ group = event;
+ event = strchr(group, '/') + 1;
+ event[-1] = '\0';
+ if (strlen(group) == 0) {
+ pr_info("Group name is not specifiled\n");
+ return -EINVAL;
+ }
+ }
+ if (strlen(event) == 0) {
+ pr_info("Event name is not specifiled\n");
+ return -EINVAL;
+ }
+ }
+
+ if (isdigit(argv[1][0])) {
+ if (is_return) {
+ pr_info("Return probe point must be a symbol.\n");
+ return -EINVAL;
+ }
+ /* an address specified */
+ ret = strict_strtoul(&argv[0][2], 0, (unsigned long *)&addr);
+ if (ret) {
+ pr_info("Failed to parse address.\n");
+ return ret;
+ }
+ } else {
+ /* a symbol specified */
+ symbol = argv[1];
+ /* TODO: support .init module functions */
+ ret = split_symbol_offset(symbol, &offset);
+ if (ret) {
+ pr_info("Failed to parse symbol.\n");
+ return ret;
+ }
+ if (offset && is_return) {
+ pr_info("Return probe must be used without offset.\n");
+ return -EINVAL;
+ }
+ }
+ argc -= 2; argv += 2;
+
+ /* setup a probe */
+ if (!group)
+ group = KPROBE_EVENT_SYSTEM;
+ if (!event) {
+ /* Make a new event name */
+ if (symbol)
+ snprintf(buf, MAX_EVENT_NAME_LEN, "%c@%s%+ld",
+ is_return ? 'r' : 'p', symbol, offset);
+ else
+ snprintf(buf, MAX_EVENT_NAME_LEN, "%c@0x%p",
+ is_return ? 'r' : 'p', addr);
+ event = buf;
+ }
+ tp = alloc_trace_probe(group, event, addr, symbol, offset, argc,
+ is_return);
+ if (IS_ERR(tp)) {
+ pr_info("Failed to allocate trace_probe.(%d)\n",
+ (int)PTR_ERR(tp));
+ return PTR_ERR(tp);
+ }
+
+ /* parse arguments */
+ ret = 0;
+ for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
+ /* Parse argument name */
+ arg = strchr(argv[i], '=');
+ if (arg)
+ *arg++ = '\0';
+ else
+ arg = argv[i];
+
+ if (conflict_field_name(argv[i], tp->args, i)) {
+ pr_info("Argument%d name '%s' conflicts with "
+ "another field.\n", i, argv[i]);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
+ if (!tp->args[i].name) {
+ pr_info("Failed to allocate argument%d name '%s'.\n",
+ i, argv[i]);
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ /* Parse fetch argument */
+ ret = parse_probe_arg(arg, &tp->args[i].fetch, is_return);
+ if (ret) {
+ pr_info("Parse error at argument%d. (%d)\n", i, ret);
+ kfree(tp->args[i].name);
+ goto error;
+ }
+
+ tp->nr_args++;
+ }
+
+ ret = register_trace_probe(tp);
+ if (ret)
+ goto error;
+ return 0;
+
+error:
+ free_trace_probe(tp);
+ return ret;
+}
+
+static void cleanup_all_probes(void)
+{
+ struct trace_probe *tp;
+
+ mutex_lock(&probe_lock);
+ /* TODO: Use batch unregistration */
+ while (!list_empty(&probe_list)) {
+ tp = list_entry(probe_list.next, struct trace_probe, list);
+ unregister_trace_probe(tp);
+ free_trace_probe(tp);
+ }
+ mutex_unlock(&probe_lock);
+}
+
+
+/* Probes listing interfaces */
+static void *probes_seq_start(struct seq_file *m, loff_t *pos)
+{
+ mutex_lock(&probe_lock);
+ return seq_list_start(&probe_list, *pos);
+}
+
+static void *probes_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ return seq_list_next(v, &probe_list, pos);
+}
+
+static void probes_seq_stop(struct seq_file *m, void *v)
+{
+ mutex_unlock(&probe_lock);
+}
+
+static int probes_seq_show(struct seq_file *m, void *v)
+{
+ struct trace_probe *tp = v;
+ int i, ret;
+ char buf[MAX_ARGSTR_LEN + 1];
+
+ seq_printf(m, "%c", probe_is_return(tp) ? 'r' : 'p');
+ seq_printf(m, ":%s/%s", tp->call.system, tp->call.name);
+
+ if (!tp->symbol)
+ seq_printf(m, " 0x%p", tp->rp.kp.addr);
+ else if (tp->rp.kp.offset)
+ seq_printf(m, " %s+%u", probe_symbol(tp), tp->rp.kp.offset);
+ else
+ seq_printf(m, " %s", probe_symbol(tp));
+
+ for (i = 0; i < tp->nr_args; i++) {
+ ret = probe_arg_string(buf, MAX_ARGSTR_LEN, &tp->args[i].fetch);
+ if (ret < 0) {
+ pr_warning("Argument%d decoding error(%d).\n", i, ret);
+ return ret;
+ }
+ seq_printf(m, " %s=%s", tp->args[i].name, buf);
+ }
+ seq_printf(m, "\n");
+ return 0;
+}
+
+static const struct seq_operations probes_seq_op = {
+ .start = probes_seq_start,
+ .next = probes_seq_next,
+ .stop = probes_seq_stop,
+ .show = probes_seq_show
+};
+
+static int probes_open(struct inode *inode, struct file *file)
+{
+ if ((file->f_mode & FMODE_WRITE) &&
+ (file->f_flags & O_TRUNC))
+ cleanup_all_probes();
+
+ return seq_open(file, &probes_seq_op);
+}
+
+static int command_trace_probe(const char *buf)
+{
+ char **argv;
+ int argc = 0, ret = 0;
+
+ argv = argv_split(GFP_KERNEL, buf, &argc);
+ if (!argv)
+ return -ENOMEM;
+
+ if (argc)
+ ret = create_trace_probe(argc, argv);
+
+ argv_free(argv);
+ return ret;
+}
+
+#define WRITE_BUFSIZE 128
+
+static ssize_t probes_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ char *kbuf, *tmp;
+ int ret;
+ size_t done;
+ size_t size;
+
+ kbuf = kmalloc(WRITE_BUFSIZE, GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+
+ ret = done = 0;
+ while (done < count) {
+ size = count - done;
+ if (size >= WRITE_BUFSIZE)
+ size = WRITE_BUFSIZE - 1;
+ if (copy_from_user(kbuf, buffer + done, size)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ kbuf[size] = '\0';
+ tmp = strchr(kbuf, '\n');
+ if (tmp) {
+ *tmp = '\0';
+ size = tmp - kbuf + 1;
+ } else if (done + size < count) {
+ pr_warning("Line length is too long: "
+ "Should be less than %d.", WRITE_BUFSIZE);
+ ret = -EINVAL;
+ goto out;
+ }
+ done += size;
+ /* Remove comments */
+ tmp = strchr(kbuf, '#');
+ if (tmp)
+ *tmp = '\0';
+
+ ret = command_trace_probe(kbuf);
+ if (ret)
+ goto out;
+ }
+ ret = done;
+out:
+ kfree(kbuf);
+ return ret;
+}
+
+static const struct file_operations kprobe_events_ops = {
+ .owner = THIS_MODULE,
+ .open = probes_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+ .write = probes_write,
+};
+
+/* Probes profiling interfaces */
+static int probes_profile_seq_show(struct seq_file *m, void *v)
+{
+ struct trace_probe *tp = v;
+
+ seq_printf(m, " %-44s %15lu %15lu\n", tp->call.name, tp->nhit,
+ tp->rp.kp.nmissed);
+
+ return 0;
+}
+
+static const struct seq_operations profile_seq_op = {
+ .start = probes_seq_start,
+ .next = probes_seq_next,
+ .stop = probes_seq_stop,
+ .show = probes_profile_seq_show
+};
+
+static int profile_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &profile_seq_op);
+}
+
+static const struct file_operations kprobe_profile_ops = {
+ .owner = THIS_MODULE,
+ .open = profile_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+/* Kprobe handler */
+static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
+{
+ struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
+ struct kprobe_trace_entry *entry;
+ struct ring_buffer_event *event;
+ struct ring_buffer *buffer;
+ int size, i, pc;
+ unsigned long irq_flags;
+ struct ftrace_event_call *call = &tp->call;
+
+ tp->nhit++;
+
+ local_save_flags(irq_flags);
+ pc = preempt_count();
+
+ size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args);
+
+ event = trace_current_buffer_lock_reserve(&buffer, call->id, size,
+ irq_flags, pc);
+ if (!event)
+ return 0;
+
+ entry = ring_buffer_event_data(event);
+ entry->nargs = tp->nr_args;
+ entry->ip = (unsigned long)kp->addr;
+ for (i = 0; i < tp->nr_args; i++)
+ entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+
+ if (!filter_current_check_discard(buffer, call, entry, event))
+ trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
+ return 0;
+}
+
+/* Kretprobe handler */
+static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+{
+ struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
+ struct kretprobe_trace_entry *entry;
+ struct ring_buffer_event *event;
+ struct ring_buffer *buffer;
+ int size, i, pc;
+ unsigned long irq_flags;
+ struct ftrace_event_call *call = &tp->call;
+
+ local_save_flags(irq_flags);
+ pc = preempt_count();
+
+ size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args);
+
+ event = trace_current_buffer_lock_reserve(&buffer, call->id, size,
+ irq_flags, pc);
+ if (!event)
+ return 0;
+
+ entry = ring_buffer_event_data(event);
+ entry->nargs = tp->nr_args;
+ entry->func = (unsigned long)tp->rp.kp.addr;
+ entry->ret_ip = (unsigned long)ri->ret_addr;
+ for (i = 0; i < tp->nr_args; i++)
+ entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+
+ if (!filter_current_check_discard(buffer, call, entry, event))
+ trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
+
+ return 0;
+}
+
+/* Event entry printers */
+enum print_line_t
+print_kprobe_event(struct trace_iterator *iter, int flags)
+{
+ struct kprobe_trace_entry *field;
+ struct trace_seq *s = &iter->seq;
+ struct trace_event *event;
+ struct trace_probe *tp;
+ int i;
+
+ field = (struct kprobe_trace_entry *)iter->ent;
+ event = ftrace_find_event(field->ent.type);
+ tp = container_of(event, struct trace_probe, event);
+
+ if (!trace_seq_printf(s, "%s: (", tp->call.name))
+ goto partial;
+
+ if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET))
+ goto partial;
+
+ if (!trace_seq_puts(s, ")"))
+ goto partial;
+
+ for (i = 0; i < field->nargs; i++)
+ if (!trace_seq_printf(s, " %s=%lx",
+ tp->args[i].name, field->args[i]))
+ goto partial;
+
+ if (!trace_seq_puts(s, "\n"))
+ goto partial;
+
+ return TRACE_TYPE_HANDLED;
+partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+enum print_line_t
+print_kretprobe_event(struct trace_iterator *iter, int flags)
+{
+ struct kretprobe_trace_entry *field;
+ struct trace_seq *s = &iter->seq;
+ struct trace_event *event;
+ struct trace_probe *tp;
+ int i;
+
+ field = (struct kretprobe_trace_entry *)iter->ent;
+ event = ftrace_find_event(field->ent.type);
+ tp = container_of(event, struct trace_probe, event);
+
+ if (!trace_seq_printf(s, "%s: (", tp->call.name))
+ goto partial;
+
+ if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET))
+ goto partial;
+
+ if (!trace_seq_puts(s, " <- "))
+ goto partial;
+
+ if (!seq_print_ip_sym(s, field->func, flags & ~TRACE_ITER_SYM_OFFSET))
+ goto partial;
+
+ if (!trace_seq_puts(s, ")"))
+ goto partial;
+
+ for (i = 0; i < field->nargs; i++)
+ if (!trace_seq_printf(s, " %s=%lx",
+ tp->args[i].name, field->args[i]))
+ goto partial;
+
+ if (!trace_seq_puts(s, "\n"))
+ goto partial;
+
+ return TRACE_TYPE_HANDLED;
+partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static int probe_event_enable(struct ftrace_event_call *call)
+{
+ struct trace_probe *tp = (struct trace_probe *)call->data;
+
+ tp->flags |= TP_FLAG_TRACE;
+ if (probe_is_return(tp))
+ return enable_kretprobe(&tp->rp);
+ else
+ return enable_kprobe(&tp->rp.kp);
+}
+
+static void probe_event_disable(struct ftrace_event_call *call)
+{
+ struct trace_probe *tp = (struct trace_probe *)call->data;
+
+ tp->flags &= ~TP_FLAG_TRACE;
+ if (!(tp->flags & (TP_FLAG_TRACE | TP_FLAG_PROFILE))) {
+ if (probe_is_return(tp))
+ disable_kretprobe(&tp->rp);
+ else
+ disable_kprobe(&tp->rp.kp);
+ }
+}
+
+static int probe_event_raw_init(struct ftrace_event_call *event_call)
+{
+ INIT_LIST_HEAD(&event_call->fields);
+
+ return 0;
+}
+
+#undef DEFINE_FIELD
+#define DEFINE_FIELD(type, item, name, is_signed) \
+ do { \
+ ret = trace_define_field(event_call, #type, name, \
+ offsetof(typeof(field), item), \
+ sizeof(field.item), is_signed, \
+ FILTER_OTHER); \
+ if (ret) \
+ return ret; \
+ } while (0)
+
+static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
+{
+ int ret, i;
+ struct kprobe_trace_entry field;
+ struct trace_probe *tp = (struct trace_probe *)event_call->data;
+
+ ret = trace_define_common_fields(event_call);
+ if (!ret)
+ return ret;
+
+ DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
+ DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
+ /* Set argument names as fields */
+ for (i = 0; i < tp->nr_args; i++)
+ DEFINE_FIELD(unsigned long, args[i], tp->args[i].name, 0);
+ return 0;
+}
+
+static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
+{
+ int ret, i;
+ struct kretprobe_trace_entry field;
+ struct trace_probe *tp = (struct trace_probe *)event_call->data;
+
+ ret = trace_define_common_fields(event_call);
+ if (!ret)
+ return ret;
+
+ DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
+ DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
+ DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
+ /* Set argument names as fields */
+ for (i = 0; i < tp->nr_args; i++)
+ DEFINE_FIELD(unsigned long, args[i], tp->args[i].name, 0);
+ return 0;
+}
+
+static int __probe_event_show_format(struct trace_seq *s,
+ struct trace_probe *tp, const char *fmt,
+ const char *arg)
+{
+ int i;
+
+ /* Show format */
+ if (!trace_seq_printf(s, "\nprint fmt: \"%s", fmt))
+ return 0;
+
+ for (i = 0; i < tp->nr_args; i++)
+ if (!trace_seq_printf(s, " %s=%%lx", tp->args[i].name))
+ return 0;
+
+ if (!trace_seq_printf(s, "\", %s", arg))
+ return 0;
+
+ for (i = 0; i < tp->nr_args; i++)
+ if (!trace_seq_printf(s, ", REC->%s", tp->args[i].name))
+ return 0;
+
+ return trace_seq_puts(s, "\n");
+}
+
+#undef SHOW_FIELD
+#define SHOW_FIELD(type, item, name) \
+ do { \
+ ret = trace_seq_printf(s, "\tfield: " #type " %s;\t" \
+ "offset:%u;\tsize:%u;\n", name, \
+ (unsigned int)offsetof(typeof(field), item),\
+ (unsigned int)sizeof(type)); \
+ if (!ret) \
+ return 0; \
+ } while (0)
+
+static int kprobe_event_show_format(struct ftrace_event_call *call,
+ struct trace_seq *s)
+{
+ struct kprobe_trace_entry field __attribute__((unused));
+ int ret, i;
+ struct trace_probe *tp = (struct trace_probe *)call->data;
+
+ SHOW_FIELD(unsigned long, ip, FIELD_STRING_IP);
+ SHOW_FIELD(int, nargs, FIELD_STRING_NARGS);
+
+ /* Show fields */
+ for (i = 0; i < tp->nr_args; i++)
+ SHOW_FIELD(unsigned long, args[i], tp->args[i].name);
+ trace_seq_puts(s, "\n");
+
+ return __probe_event_show_format(s, tp, "(%lx)",
+ "REC->" FIELD_STRING_IP);
+}
+
+static int kretprobe_event_show_format(struct ftrace_event_call *call,
+ struct trace_seq *s)
+{
+ struct kretprobe_trace_entry field __attribute__((unused));
+ int ret, i;
+ struct trace_probe *tp = (struct trace_probe *)call->data;
+
+ SHOW_FIELD(unsigned long, func, FIELD_STRING_FUNC);
+ SHOW_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP);
+ SHOW_FIELD(int, nargs, FIELD_STRING_NARGS);
+
+ /* Show fields */
+ for (i = 0; i < tp->nr_args; i++)
+ SHOW_FIELD(unsigned long, args[i], tp->args[i].name);
+ trace_seq_puts(s, "\n");
+
+ return __probe_event_show_format(s, tp, "(%lx <- %lx)",
+ "REC->" FIELD_STRING_FUNC
+ ", REC->" FIELD_STRING_RETIP);
+}
+
+#ifdef CONFIG_EVENT_PROFILE
+
+/* Kprobe profile handler */
+static __kprobes int kprobe_profile_func(struct kprobe *kp,
+ struct pt_regs *regs)
+{
+ struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
+ struct ftrace_event_call *call = &tp->call;
+ struct kprobe_trace_entry *entry;
+ struct trace_entry *ent;
+ int size, __size, i, pc, __cpu;
+ unsigned long irq_flags;
+ char *trace_buf;
+ char *raw_data;
+ int rctx;
+
+ pc = preempt_count();
+ __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args);
+ size = ALIGN(__size + sizeof(u32), sizeof(u64));
+ size -= sizeof(u32);
+ if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
+ "profile buffer not large enough"))
+ return 0;
+
+ /*
+ * Protect the non nmi buffer
+ * This also protects the rcu read side
+ */
+ local_irq_save(irq_flags);
+
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
+ goto end_recursion;
+
+ __cpu = smp_processor_id();
+
+ if (in_nmi())
+ trace_buf = rcu_dereference(perf_trace_buf_nmi);
+ else
+ trace_buf = rcu_dereference(perf_trace_buf);
+
+ if (!trace_buf)
+ goto end;
+
+ raw_data = per_cpu_ptr(trace_buf, __cpu);
+
+ /* Zero dead bytes from alignment to avoid buffer leak to userspace */
+ *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL;
+ entry = (struct kprobe_trace_entry *)raw_data;
+ ent = &entry->ent;
+
+ tracing_generic_entry_update(ent, irq_flags, pc);
+ ent->type = call->id;
+ entry->nargs = tp->nr_args;
+ entry->ip = (unsigned long)kp->addr;
+ for (i = 0; i < tp->nr_args; i++)
+ entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+ perf_tp_event(call->id, entry->ip, 1, entry, size);
+
+end:
+ perf_swevent_put_recursion_context(rctx);
+end_recursion:
+ local_irq_restore(irq_flags);
+
+ return 0;
+}
+
+/* Kretprobe profile handler */
+static __kprobes int kretprobe_profile_func(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+{
+ struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
+ struct ftrace_event_call *call = &tp->call;
+ struct kretprobe_trace_entry *entry;
+ struct trace_entry *ent;
+ int size, __size, i, pc, __cpu;
+ unsigned long irq_flags;
+ char *trace_buf;
+ char *raw_data;
+ int rctx;
+
+ pc = preempt_count();
+ __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args);
+ size = ALIGN(__size + sizeof(u32), sizeof(u64));
+ size -= sizeof(u32);
+ if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
+ "profile buffer not large enough"))
+ return 0;
+
+ /*
+ * Protect the non nmi buffer
+ * This also protects the rcu read side
+ */
+ local_irq_save(irq_flags);
+
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
+ goto end_recursion;
+
+ __cpu = smp_processor_id();
+
+ if (in_nmi())
+ trace_buf = rcu_dereference(perf_trace_buf_nmi);
+ else
+ trace_buf = rcu_dereference(perf_trace_buf);
+
+ if (!trace_buf)
+ goto end;
+
+ raw_data = per_cpu_ptr(trace_buf, __cpu);
+
+ /* Zero dead bytes from alignment to avoid buffer leak to userspace */
+ *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL;
+ entry = (struct kretprobe_trace_entry *)raw_data;
+ ent = &entry->ent;
+
+ tracing_generic_entry_update(ent, irq_flags, pc);
+ ent->type = call->id;
+ entry->nargs = tp->nr_args;
+ entry->func = (unsigned long)tp->rp.kp.addr;
+ entry->ret_ip = (unsigned long)ri->ret_addr;
+ for (i = 0; i < tp->nr_args; i++)
+ entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+ perf_tp_event(call->id, entry->ret_ip, 1, entry, size);
+
+end:
+ perf_swevent_put_recursion_context(rctx);
+end_recursion:
+ local_irq_restore(irq_flags);
+
+ return 0;
+}
+
+static int probe_profile_enable(struct ftrace_event_call *call)
+{
+ struct trace_probe *tp = (struct trace_probe *)call->data;
+
+ tp->flags |= TP_FLAG_PROFILE;
+
+ if (probe_is_return(tp))
+ return enable_kretprobe(&tp->rp);
+ else
+ return enable_kprobe(&tp->rp.kp);
+}
+
+static void probe_profile_disable(struct ftrace_event_call *call)
+{
+ struct trace_probe *tp = (struct trace_probe *)call->data;
+
+ tp->flags &= ~TP_FLAG_PROFILE;
+
+ if (!(tp->flags & TP_FLAG_TRACE)) {
+ if (probe_is_return(tp))
+ disable_kretprobe(&tp->rp);
+ else
+ disable_kprobe(&tp->rp.kp);
+ }
+}
+#endif /* CONFIG_EVENT_PROFILE */
+
+
+static __kprobes
+int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
+{
+ struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
+
+ if (tp->flags & TP_FLAG_TRACE)
+ kprobe_trace_func(kp, regs);
+#ifdef CONFIG_EVENT_PROFILE
+ if (tp->flags & TP_FLAG_PROFILE)
+ kprobe_profile_func(kp, regs);
+#endif /* CONFIG_EVENT_PROFILE */
+ return 0; /* We don't tweek kernel, so just return 0 */
+}
+
+static __kprobes
+int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
+
+ if (tp->flags & TP_FLAG_TRACE)
+ kretprobe_trace_func(ri, regs);
+#ifdef CONFIG_EVENT_PROFILE
+ if (tp->flags & TP_FLAG_PROFILE)
+ kretprobe_profile_func(ri, regs);
+#endif /* CONFIG_EVENT_PROFILE */
+ return 0; /* We don't tweek kernel, so just return 0 */
+}
+
+static int register_probe_event(struct trace_probe *tp)
+{
+ struct ftrace_event_call *call = &tp->call;
+ int ret;
+
+ /* Initialize ftrace_event_call */
+ if (probe_is_return(tp)) {
+ tp->event.trace = print_kretprobe_event;
+ call->raw_init = probe_event_raw_init;
+ call->show_format = kretprobe_event_show_format;
+ call->define_fields = kretprobe_event_define_fields;
+ } else {
+ tp->event.trace = print_kprobe_event;
+ call->raw_init = probe_event_raw_init;
+ call->show_format = kprobe_event_show_format;
+ call->define_fields = kprobe_event_define_fields;
+ }
+ call->event = &tp->event;
+ call->id = register_ftrace_event(&tp->event);
+ if (!call->id)
+ return -ENODEV;
+ call->enabled = 0;
+ call->regfunc = probe_event_enable;
+ call->unregfunc = probe_event_disable;
+
+#ifdef CONFIG_EVENT_PROFILE
+ atomic_set(&call->profile_count, -1);
+ call->profile_enable = probe_profile_enable;
+ call->profile_disable = probe_profile_disable;
+#endif
+ call->data = tp;
+ ret = trace_add_event_call(call);
+ if (ret) {
+ pr_info("Failed to register kprobe event: %s\n", call->name);
+ unregister_ftrace_event(&tp->event);
+ }
+ return ret;
+}
+
+static void unregister_probe_event(struct trace_probe *tp)
+{
+ /* tp->event is unregistered in trace_remove_event_call() */
+ trace_remove_event_call(&tp->call);
+}
+
+/* Make a debugfs interface for controling probe points */
+static __init int init_kprobe_trace(void)
+{
+ struct dentry *d_tracer;
+ struct dentry *entry;
+
+ d_tracer = tracing_init_dentry();
+ if (!d_tracer)
+ return 0;
+
+ entry = debugfs_create_file("kprobe_events", 0644, d_tracer,
+ NULL, &kprobe_events_ops);
+
+ /* Event list interface */
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'kprobe_events' entry\n");
+
+ /* Profile interface */
+ entry = debugfs_create_file("kprobe_profile", 0444, d_tracer,
+ NULL, &kprobe_profile_ops);
+
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'kprobe_profile' entry\n");
+ return 0;
+}
+fs_initcall(init_kprobe_trace);
+
+
+#ifdef CONFIG_FTRACE_STARTUP_TEST
+
+static int kprobe_trace_selftest_target(int a1, int a2, int a3,
+ int a4, int a5, int a6)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6;
+}
+
+static __init int kprobe_trace_self_tests_init(void)
+{
+ int ret;
+ int (*target)(int, int, int, int, int, int);
+
+ target = kprobe_trace_selftest_target;
+
+ pr_info("Testing kprobe tracing: ");
+
+ ret = command_trace_probe("p:testprobe kprobe_trace_selftest_target "
+ "$arg1 $arg2 $arg3 $arg4 $stack $stack0");
+ if (WARN_ON_ONCE(ret))
+ pr_warning("error enabling function entry\n");
+
+ ret = command_trace_probe("r:testprobe2 kprobe_trace_selftest_target "
+ "$retval");
+ if (WARN_ON_ONCE(ret))
+ pr_warning("error enabling function return\n");
+
+ ret = target(1, 2, 3, 4, 5, 6);
+
+ cleanup_all_probes();
+
+ pr_cont("OK\n");
+ return 0;
+}
+
+late_initcall(kprobe_trace_self_tests_init);
+
+#endif
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c
new file mode 100644
index 000000000000..ddfa0fd43bc0
--- /dev/null
+++ b/kernel/trace/trace_ksym.c
@@ -0,0 +1,550 @@
+/*
+ * trace_ksym.c - Kernel Symbol Tracer
+ *
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2009
+ */
+
+#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/ftrace.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+
+#include "trace_output.h"
+#include "trace_stat.h"
+#include "trace.h"
+
+#include <linux/hw_breakpoint.h>
+#include <asm/hw_breakpoint.h>
+
+/*
+ * For now, let us restrict the no. of symbols traced simultaneously to number
+ * of available hardware breakpoint registers.
+ */
+#define KSYM_TRACER_MAX HBP_NUM
+
+#define KSYM_TRACER_OP_LEN 3 /* rw- */
+
+struct trace_ksym {
+ struct perf_event **ksym_hbp;
+ struct perf_event_attr attr;
+#ifdef CONFIG_PROFILE_KSYM_TRACER
+ unsigned long counter;
+#endif
+ struct hlist_node ksym_hlist;
+};
+
+static struct trace_array *ksym_trace_array;
+
+static unsigned int ksym_filter_entry_count;
+static unsigned int ksym_tracing_enabled;
+
+static HLIST_HEAD(ksym_filter_head);
+
+static DEFINE_MUTEX(ksym_tracer_mutex);
+
+#ifdef CONFIG_PROFILE_KSYM_TRACER
+
+#define MAX_UL_INT 0xffffffff
+
+void ksym_collect_stats(unsigned long hbp_hit_addr)
+{
+ struct hlist_node *node;
+ struct trace_ksym *entry;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(entry, node, &ksym_filter_head, ksym_hlist) {
+ if ((entry->attr.bp_addr == hbp_hit_addr) &&
+ (entry->counter <= MAX_UL_INT)) {
+ entry->counter++;
+ break;
+ }
+ }
+ rcu_read_unlock();
+}
+#endif /* CONFIG_PROFILE_KSYM_TRACER */
+
+void ksym_hbp_handler(struct perf_event *hbp, void *data)
+{
+ struct ring_buffer_event *event;
+ struct ksym_trace_entry *entry;
+ struct pt_regs *regs = data;
+ struct ring_buffer *buffer;
+ int pc;
+
+ if (!ksym_tracing_enabled)
+ return;
+
+ buffer = ksym_trace_array->buffer;
+
+ pc = preempt_count();
+
+ event = trace_buffer_lock_reserve(buffer, TRACE_KSYM,
+ sizeof(*entry), 0, pc);
+ if (!event)
+ return;
+
+ entry = ring_buffer_event_data(event);
+ entry->ip = instruction_pointer(regs);
+ entry->type = hw_breakpoint_type(hbp);
+ entry->addr = hw_breakpoint_addr(hbp);
+ strlcpy(entry->cmd, current->comm, TASK_COMM_LEN);
+
+#ifdef CONFIG_PROFILE_KSYM_TRACER
+ ksym_collect_stats(hw_breakpoint_addr(hbp));
+#endif /* CONFIG_PROFILE_KSYM_TRACER */
+
+ trace_buffer_unlock_commit(buffer, event, 0, pc);
+}
+
+/* Valid access types are represented as
+ *
+ * rw- : Set Read/Write Access Breakpoint
+ * -w- : Set Write Access Breakpoint
+ * --- : Clear Breakpoints
+ * --x : Set Execution Break points (Not available yet)
+ *
+ */
+static int ksym_trace_get_access_type(char *str)
+{
+ int access = 0;
+
+ if (str[0] == 'r')
+ access |= HW_BREAKPOINT_R;
+
+ if (str[1] == 'w')
+ access |= HW_BREAKPOINT_W;
+
+ if (str[2] == 'x')
+ access |= HW_BREAKPOINT_X;
+
+ switch (access) {
+ case HW_BREAKPOINT_R:
+ case HW_BREAKPOINT_W:
+ case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
+ return access;
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * There can be several possible malformed requests and we attempt to capture
+ * all of them. We enumerate some of the rules
+ * 1. We will not allow kernel symbols with ':' since it is used as a delimiter.
+ * i.e. multiple ':' symbols disallowed. Possible uses are of the form
+ * <module>:<ksym_name>:<op>.
+ * 2. No delimiter symbol ':' in the input string
+ * 3. Spurious operator symbols or symbols not in their respective positions
+ * 4. <ksym_name>:--- i.e. clear breakpoint request when ksym_name not in file
+ * 5. Kernel symbol not a part of /proc/kallsyms
+ * 6. Duplicate requests
+ */
+static int parse_ksym_trace_str(char *input_string, char **ksymname,
+ unsigned long *addr)
+{
+ int ret;
+
+ *ksymname = strsep(&input_string, ":");
+ *addr = kallsyms_lookup_name(*ksymname);
+
+ /* Check for malformed request: (2), (1) and (5) */
+ if ((!input_string) ||
+ (strlen(input_string) != KSYM_TRACER_OP_LEN) ||
+ (*addr == 0))
+ return -EINVAL;;
+
+ ret = ksym_trace_get_access_type(input_string);
+
+ return ret;
+}
+
+int process_new_ksym_entry(char *ksymname, int op, unsigned long addr)
+{
+ struct trace_ksym *entry;
+ int ret = -ENOMEM;
+
+ if (ksym_filter_entry_count >= KSYM_TRACER_MAX) {
+ printk(KERN_ERR "ksym_tracer: Maximum limit:(%d) reached. No"
+ " new requests for tracing can be accepted now.\n",
+ KSYM_TRACER_MAX);
+ return -ENOSPC;
+ }
+
+ entry = kzalloc(sizeof(struct trace_ksym), GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ hw_breakpoint_init(&entry->attr);
+
+ entry->attr.bp_type = op;
+ entry->attr.bp_addr = addr;
+ entry->attr.bp_len = HW_BREAKPOINT_LEN_4;
+
+ ret = -EAGAIN;
+ entry->ksym_hbp = register_wide_hw_breakpoint(&entry->attr,
+ ksym_hbp_handler);
+
+ if (IS_ERR(entry->ksym_hbp)) {
+ ret = PTR_ERR(entry->ksym_hbp);
+ printk(KERN_INFO "ksym_tracer request failed. Try again"
+ " later!!\n");
+ goto err;
+ }
+
+ hlist_add_head_rcu(&(entry->ksym_hlist), &ksym_filter_head);
+ ksym_filter_entry_count++;
+
+ return 0;
+
+err:
+ kfree(entry);
+
+ return ret;
+}
+
+static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct trace_ksym *entry;
+ struct hlist_node *node;
+ struct trace_seq *s;
+ ssize_t cnt = 0;
+ int ret;
+
+ s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+ trace_seq_init(s);
+
+ mutex_lock(&ksym_tracer_mutex);
+
+ hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) {
+ ret = trace_seq_printf(s, "%pS:", (void *)entry->attr.bp_addr);
+ if (entry->attr.bp_type == HW_BREAKPOINT_R)
+ ret = trace_seq_puts(s, "r--\n");
+ else if (entry->attr.bp_type == HW_BREAKPOINT_W)
+ ret = trace_seq_puts(s, "-w-\n");
+ else if (entry->attr.bp_type == (HW_BREAKPOINT_W | HW_BREAKPOINT_R))
+ ret = trace_seq_puts(s, "rw-\n");
+ WARN_ON_ONCE(!ret);
+ }
+
+ cnt = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len);
+
+ mutex_unlock(&ksym_tracer_mutex);
+
+ kfree(s);
+
+ return cnt;
+}
+
+static void __ksym_trace_reset(void)
+{
+ struct trace_ksym *entry;
+ struct hlist_node *node, *node1;
+
+ mutex_lock(&ksym_tracer_mutex);
+ hlist_for_each_entry_safe(entry, node, node1, &ksym_filter_head,
+ ksym_hlist) {
+ unregister_wide_hw_breakpoint(entry->ksym_hbp);
+ ksym_filter_entry_count--;
+ hlist_del_rcu(&(entry->ksym_hlist));
+ synchronize_rcu();
+ kfree(entry);
+ }
+ mutex_unlock(&ksym_tracer_mutex);
+}
+
+static ssize_t ksym_trace_filter_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct trace_ksym *entry;
+ struct hlist_node *node;
+ char *input_string, *ksymname = NULL;
+ unsigned long ksym_addr = 0;
+ int ret, op, changed = 0;
+
+ input_string = kzalloc(count + 1, GFP_KERNEL);
+ if (!input_string)
+ return -ENOMEM;
+
+ if (copy_from_user(input_string, buffer, count)) {
+ kfree(input_string);
+ return -EFAULT;
+ }
+ input_string[count] = '\0';
+
+ strstrip(input_string);
+
+ /*
+ * Clear all breakpoints if:
+ * 1: echo > ksym_trace_filter
+ * 2: echo 0 > ksym_trace_filter
+ * 3: echo "*:---" > ksym_trace_filter
+ */
+ if (!input_string[0] || !strcmp(input_string, "0") ||
+ !strcmp(input_string, "*:---")) {
+ __ksym_trace_reset();
+ kfree(input_string);
+ return count;
+ }
+
+ ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr);
+ if (ret < 0) {
+ kfree(input_string);
+ return ret;
+ }
+
+ mutex_lock(&ksym_tracer_mutex);
+
+ ret = -EINVAL;
+ hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) {
+ if (entry->attr.bp_addr == ksym_addr) {
+ /* Check for malformed request: (6) */
+ if (entry->attr.bp_type != op)
+ changed = 1;
+ else
+ goto out;
+ break;
+ }
+ }
+ if (changed) {
+ unregister_wide_hw_breakpoint(entry->ksym_hbp);
+ entry->attr.bp_type = op;
+ ret = 0;
+ if (op > 0) {
+ entry->ksym_hbp =
+ register_wide_hw_breakpoint(&entry->attr,
+ ksym_hbp_handler);
+ if (IS_ERR(entry->ksym_hbp))
+ ret = PTR_ERR(entry->ksym_hbp);
+ else
+ goto out;
+ }
+ /* Error or "symbol:---" case: drop it */
+ ksym_filter_entry_count--;
+ hlist_del_rcu(&(entry->ksym_hlist));
+ synchronize_rcu();
+ kfree(entry);
+ goto out;
+ } else {
+ /* Check for malformed request: (4) */
+ if (op == 0)
+ goto out;
+ ret = process_new_ksym_entry(ksymname, op, ksym_addr);
+ }
+out:
+ mutex_unlock(&ksym_tracer_mutex);
+
+ kfree(input_string);
+
+ if (!ret)
+ ret = count;
+ return ret;
+}
+
+static const struct file_operations ksym_tracing_fops = {
+ .open = tracing_open_generic,
+ .read = ksym_trace_filter_read,
+ .write = ksym_trace_filter_write,
+};
+
+static void ksym_trace_reset(struct trace_array *tr)
+{
+ ksym_tracing_enabled = 0;
+ __ksym_trace_reset();
+}
+
+static int ksym_trace_init(struct trace_array *tr)
+{
+ int cpu, ret = 0;
+
+ for_each_online_cpu(cpu)
+ tracing_reset(tr, cpu);
+ ksym_tracing_enabled = 1;
+ ksym_trace_array = tr;
+
+ return ret;
+}
+
+static void ksym_trace_print_header(struct seq_file *m)
+{
+ seq_puts(m,
+ "# TASK-PID CPU# Symbol "
+ "Type Function\n");
+ seq_puts(m,
+ "# | | | "
+ " | |\n");
+}
+
+static enum print_line_t ksym_trace_output(struct trace_iterator *iter)
+{
+ struct trace_entry *entry = iter->ent;
+ struct trace_seq *s = &iter->seq;
+ struct ksym_trace_entry *field;
+ char str[KSYM_SYMBOL_LEN];
+ int ret;
+
+ if (entry->type != TRACE_KSYM)
+ return TRACE_TYPE_UNHANDLED;
+
+ trace_assign_type(field, entry);
+
+ ret = trace_seq_printf(s, "%11s-%-5d [%03d] %pS", field->cmd,
+ entry->pid, iter->cpu, (char *)field->addr);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ switch (field->type) {
+ case HW_BREAKPOINT_R:
+ ret = trace_seq_printf(s, " R ");
+ break;
+ case HW_BREAKPOINT_W:
+ ret = trace_seq_printf(s, " W ");
+ break;
+ case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
+ ret = trace_seq_printf(s, " RW ");
+ break;
+ default:
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
+
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ sprint_symbol(str, field->ip);
+ ret = trace_seq_printf(s, "%s\n", str);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+struct tracer ksym_tracer __read_mostly =
+{
+ .name = "ksym_tracer",
+ .init = ksym_trace_init,
+ .reset = ksym_trace_reset,
+#ifdef CONFIG_FTRACE_SELFTEST
+ .selftest = trace_selftest_startup_ksym,
+#endif
+ .print_header = ksym_trace_print_header,
+ .print_line = ksym_trace_output
+};
+
+__init static int init_ksym_trace(void)
+{
+ struct dentry *d_tracer;
+ struct dentry *entry;
+
+ d_tracer = tracing_init_dentry();
+ ksym_filter_entry_count = 0;
+
+ entry = debugfs_create_file("ksym_trace_filter", 0644, d_tracer,
+ NULL, &ksym_tracing_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'ksym_trace_filter' file\n");
+
+ return register_tracer(&ksym_tracer);
+}
+device_initcall(init_ksym_trace);
+
+
+#ifdef CONFIG_PROFILE_KSYM_TRACER
+static int ksym_tracer_stat_headers(struct seq_file *m)
+{
+ seq_puts(m, " Access Type ");
+ seq_puts(m, " Symbol Counter\n");
+ seq_puts(m, " ----------- ");
+ seq_puts(m, " ------ -------\n");
+ return 0;
+}
+
+static int ksym_tracer_stat_show(struct seq_file *m, void *v)
+{
+ struct hlist_node *stat = v;
+ struct trace_ksym *entry;
+ int access_type = 0;
+ char fn_name[KSYM_NAME_LEN];
+
+ entry = hlist_entry(stat, struct trace_ksym, ksym_hlist);
+
+ access_type = entry->attr.bp_type;
+
+ switch (access_type) {
+ case HW_BREAKPOINT_R:
+ seq_puts(m, " R ");
+ break;
+ case HW_BREAKPOINT_W:
+ seq_puts(m, " W ");
+ break;
+ case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
+ seq_puts(m, " RW ");
+ break;
+ default:
+ seq_puts(m, " NA ");
+ }
+
+ if (lookup_symbol_name(entry->attr.bp_addr, fn_name) >= 0)
+ seq_printf(m, " %-36s", fn_name);
+ else
+ seq_printf(m, " %-36s", "<NA>");
+ seq_printf(m, " %15lu\n", entry->counter);
+
+ return 0;
+}
+
+static void *ksym_tracer_stat_start(struct tracer_stat *trace)
+{
+ return ksym_filter_head.first;
+}
+
+static void *
+ksym_tracer_stat_next(void *v, int idx)
+{
+ struct hlist_node *stat = v;
+
+ return stat->next;
+}
+
+static struct tracer_stat ksym_tracer_stats = {
+ .name = "ksym_tracer",
+ .stat_start = ksym_tracer_stat_start,
+ .stat_next = ksym_tracer_stat_next,
+ .stat_headers = ksym_tracer_stat_headers,
+ .stat_show = ksym_tracer_stat_show
+};
+
+__init static int ksym_tracer_stat_init(void)
+{
+ int ret;
+
+ ret = register_stat_tracer(&ksym_tracer_stats);
+ if (ret) {
+ printk(KERN_WARNING "Warning: could not register "
+ "ksym tracer stats\n");
+ return 1;
+ }
+
+ return 0;
+}
+fs_initcall(ksym_tracer_stat_init);
+#endif /* CONFIG_PROFILE_KSYM_TRACER */
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index ed17565826b0..b6c12c6a1bcd 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -69,6 +69,9 @@ enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
* @s: trace sequence descriptor
* @fmt: printf format string
*
+ * It returns 0 if the trace oversizes the buffer's free
+ * space, 1 otherwise.
+ *
* The tracer may use either sequence operations or its own
* copy to user routines. To simplify formating of a trace
* trace_seq_printf is used to store strings into a special
@@ -95,7 +98,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
s->len += ret;
- return len;
+ return 1;
}
EXPORT_SYMBOL_GPL(trace_seq_printf);
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index d2cdbabb4ead..dc98309e839a 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -17,6 +17,7 @@ static inline int trace_valid_entry(struct trace_entry *entry)
case TRACE_GRAPH_ENT:
case TRACE_GRAPH_RET:
case TRACE_HW_BRANCHES:
+ case TRACE_KSYM:
return 1;
}
return 0;
@@ -808,3 +809,57 @@ trace_selftest_startup_hw_branches(struct tracer *trace,
return ret;
}
#endif /* CONFIG_HW_BRANCH_TRACER */
+
+#ifdef CONFIG_KSYM_TRACER
+static int ksym_selftest_dummy;
+
+int
+trace_selftest_startup_ksym(struct tracer *trace, struct trace_array *tr)
+{
+ unsigned long count;
+ int ret;
+
+ /* start the tracing */
+ ret = tracer_init(trace, tr);
+ if (ret) {
+ warn_failed_init_tracer(trace, ret);
+ return ret;
+ }
+
+ ksym_selftest_dummy = 0;
+ /* Register the read-write tracing request */
+
+ ret = process_new_ksym_entry("ksym_selftest_dummy",
+ HW_BREAKPOINT_R | HW_BREAKPOINT_W,
+ (unsigned long)(&ksym_selftest_dummy));
+
+ if (ret < 0) {
+ printk(KERN_CONT "ksym_trace read-write startup test failed\n");
+ goto ret_path;
+ }
+ /* Perform a read and a write operation over the dummy variable to
+ * trigger the tracer
+ */
+ if (ksym_selftest_dummy == 0)
+ ksym_selftest_dummy++;
+
+ /* stop the tracing. */
+ tracing_stop();
+ /* check the trace buffer */
+ ret = trace_test_buffer(tr, &count);
+ trace->reset(tr);
+ tracing_start();
+
+ /* read & write operations - one each is performed on the dummy variable
+ * triggering two entries in the trace buffer
+ */
+ if (!ret && count != 2) {
+ printk(KERN_CONT "Ksym tracer startup test failed");
+ ret = -1;
+ }
+
+ret_path:
+ return ret;
+}
+#endif /* CONFIG_KSYM_TRACER */
+
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 527e17eae575..57501d90096a 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -14,6 +14,43 @@ static int sys_refcount_exit;
static DECLARE_BITMAP(enabled_enter_syscalls, NR_syscalls);
static DECLARE_BITMAP(enabled_exit_syscalls, NR_syscalls);
+extern unsigned long __start_syscalls_metadata[];
+extern unsigned long __stop_syscalls_metadata[];
+
+static struct syscall_metadata **syscalls_metadata;
+
+static struct syscall_metadata *find_syscall_meta(unsigned long syscall)
+{
+ struct syscall_metadata *start;
+ struct syscall_metadata *stop;
+ char str[KSYM_SYMBOL_LEN];
+
+
+ start = (struct syscall_metadata *)__start_syscalls_metadata;
+ stop = (struct syscall_metadata *)__stop_syscalls_metadata;
+ kallsyms_lookup(syscall, NULL, NULL, NULL, str);
+
+ for ( ; start < stop; start++) {
+ /*
+ * Only compare after the "sys" prefix. Archs that use
+ * syscall wrappers may have syscalls symbols aliases prefixed
+ * with "SyS" instead of "sys", leading to an unwanted
+ * mismatch.
+ */
+ if (start->name && !strcmp(start->name + 3, str + 3))
+ return start;
+ }
+ return NULL;
+}
+
+static struct syscall_metadata *syscall_nr_to_meta(int nr)
+{
+ if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
+ return NULL;
+
+ return syscalls_metadata[nr];
+}
+
enum print_line_t
print_syscall_enter(struct trace_iterator *iter, int flags)
{
@@ -30,7 +67,7 @@ print_syscall_enter(struct trace_iterator *iter, int flags)
if (!entry)
goto end;
- if (entry->enter_id != ent->type) {
+ if (entry->enter_event->id != ent->type) {
WARN_ON_ONCE(1);
goto end;
}
@@ -85,7 +122,7 @@ print_syscall_exit(struct trace_iterator *iter, int flags)
return TRACE_TYPE_HANDLED;
}
- if (entry->exit_id != ent->type) {
+ if (entry->exit_event->id != ent->type) {
WARN_ON_ONCE(1);
return TRACE_TYPE_UNHANDLED;
}
@@ -103,24 +140,19 @@ extern char *__bad_type_size(void);
#define SYSCALL_FIELD(type, name) \
sizeof(type) != sizeof(trace.name) ? \
__bad_type_size() : \
- #type, #name, offsetof(typeof(trace), name), sizeof(trace.name)
+ #type, #name, offsetof(typeof(trace), name), \
+ sizeof(trace.name), is_signed_type(type)
int syscall_enter_format(struct ftrace_event_call *call, struct trace_seq *s)
{
int i;
- int nr;
int ret;
- struct syscall_metadata *entry;
+ struct syscall_metadata *entry = call->data;
struct syscall_trace_enter trace;
int offset = offsetof(struct syscall_trace_enter, args);
- nr = syscall_name_to_nr(call->data);
- entry = syscall_nr_to_meta(nr);
-
- if (!entry)
- return 0;
-
- ret = trace_seq_printf(s, "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n",
+ ret = trace_seq_printf(s, "\tfield:%s %s;\toffset:%zu;\tsize:%zu;"
+ "\tsigned:%u;\n",
SYSCALL_FIELD(int, nr));
if (!ret)
return 0;
@@ -130,8 +162,10 @@ int syscall_enter_format(struct ftrace_event_call *call, struct trace_seq *s)
entry->args[i]);
if (!ret)
return 0;
- ret = trace_seq_printf(s, "\toffset:%d;\tsize:%zu;\n", offset,
- sizeof(unsigned long));
+ ret = trace_seq_printf(s, "\toffset:%d;\tsize:%zu;"
+ "\tsigned:%u;\n", offset,
+ sizeof(unsigned long),
+ is_signed_type(unsigned long));
if (!ret)
return 0;
offset += sizeof(unsigned long);
@@ -163,8 +197,10 @@ int syscall_exit_format(struct ftrace_event_call *call, struct trace_seq *s)
struct syscall_trace_exit trace;
ret = trace_seq_printf(s,
- "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
- "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n",
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;"
+ "\tsigned:%u;\n"
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;"
+ "\tsigned:%u;\n",
SYSCALL_FIELD(int, nr),
SYSCALL_FIELD(long, ret));
if (!ret)
@@ -176,22 +212,19 @@ int syscall_exit_format(struct ftrace_event_call *call, struct trace_seq *s)
int syscall_enter_define_fields(struct ftrace_event_call *call)
{
struct syscall_trace_enter trace;
- struct syscall_metadata *meta;
+ struct syscall_metadata *meta = call->data;
int ret;
- int nr;
int i;
int offset = offsetof(typeof(trace), args);
- nr = syscall_name_to_nr(call->data);
- meta = syscall_nr_to_meta(nr);
-
- if (!meta)
- return 0;
-
ret = trace_define_common_fields(call);
if (ret)
return ret;
+ ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
+ if (ret)
+ return ret;
+
for (i = 0; i < meta->nb_args; i++) {
ret = trace_define_field(call, meta->types[i],
meta->args[i], offset,
@@ -212,7 +245,11 @@ int syscall_exit_define_fields(struct ftrace_event_call *call)
if (ret)
return ret;
- ret = trace_define_field(call, SYSCALL_FIELD(long, ret), 0,
+ ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
+ if (ret)
+ return ret;
+
+ ret = trace_define_field(call, SYSCALL_FIELD(long, ret),
FILTER_OTHER);
return ret;
@@ -239,8 +276,8 @@ void ftrace_syscall_enter(struct pt_regs *regs, long id)
size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args;
- event = trace_current_buffer_lock_reserve(&buffer, sys_data->enter_id,
- size, 0, 0);
+ event = trace_current_buffer_lock_reserve(&buffer,
+ sys_data->enter_event->id, size, 0, 0);
if (!event)
return;
@@ -271,8 +308,8 @@ void ftrace_syscall_exit(struct pt_regs *regs, long ret)
if (!sys_data)
return;
- event = trace_current_buffer_lock_reserve(&buffer, sys_data->exit_id,
- sizeof(*entry), 0, 0);
+ event = trace_current_buffer_lock_reserve(&buffer,
+ sys_data->exit_event->id, sizeof(*entry), 0, 0);
if (!event)
return;
@@ -285,14 +322,12 @@ void ftrace_syscall_exit(struct pt_regs *regs, long ret)
trace_current_buffer_unlock_commit(buffer, event, 0, 0);
}
-int reg_event_syscall_enter(void *ptr)
+int reg_event_syscall_enter(struct ftrace_event_call *call)
{
int ret = 0;
int num;
- char *name;
- name = (char *)ptr;
- num = syscall_name_to_nr(name);
+ num = ((struct syscall_metadata *)call->data)->syscall_nr;
if (num < 0 || num >= NR_syscalls)
return -ENOSYS;
mutex_lock(&syscall_trace_lock);
@@ -309,13 +344,11 @@ int reg_event_syscall_enter(void *ptr)
return ret;
}
-void unreg_event_syscall_enter(void *ptr)
+void unreg_event_syscall_enter(struct ftrace_event_call *call)
{
int num;
- char *name;
- name = (char *)ptr;
- num = syscall_name_to_nr(name);
+ num = ((struct syscall_metadata *)call->data)->syscall_nr;
if (num < 0 || num >= NR_syscalls)
return;
mutex_lock(&syscall_trace_lock);
@@ -326,14 +359,12 @@ void unreg_event_syscall_enter(void *ptr)
mutex_unlock(&syscall_trace_lock);
}
-int reg_event_syscall_exit(void *ptr)
+int reg_event_syscall_exit(struct ftrace_event_call *call)
{
int ret = 0;
int num;
- char *name;
- name = (char *)ptr;
- num = syscall_name_to_nr(name);
+ num = ((struct syscall_metadata *)call->data)->syscall_nr;
if (num < 0 || num >= NR_syscalls)
return -ENOSYS;
mutex_lock(&syscall_trace_lock);
@@ -350,13 +381,11 @@ int reg_event_syscall_exit(void *ptr)
return ret;
}
-void unreg_event_syscall_exit(void *ptr)
+void unreg_event_syscall_exit(struct ftrace_event_call *call)
{
int num;
- char *name;
- name = (char *)ptr;
- num = syscall_name_to_nr(name);
+ num = ((struct syscall_metadata *)call->data)->syscall_nr;
if (num < 0 || num >= NR_syscalls)
return;
mutex_lock(&syscall_trace_lock);
@@ -367,13 +396,44 @@ void unreg_event_syscall_exit(void *ptr)
mutex_unlock(&syscall_trace_lock);
}
-struct trace_event event_syscall_enter = {
- .trace = print_syscall_enter,
-};
+int init_syscall_trace(struct ftrace_event_call *call)
+{
+ int id;
+
+ id = register_ftrace_event(call->event);
+ if (!id)
+ return -ENODEV;
+ call->id = id;
+ INIT_LIST_HEAD(&call->fields);
+ return 0;
+}
+
+int __init init_ftrace_syscalls(void)
+{
+ struct syscall_metadata *meta;
+ unsigned long addr;
+ int i;
+
+ syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
+ NR_syscalls, GFP_KERNEL);
+ if (!syscalls_metadata) {
+ WARN_ON(1);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < NR_syscalls; i++) {
+ addr = arch_syscall_addr(i);
+ meta = find_syscall_meta(addr);
+ if (!meta)
+ continue;
+
+ meta->syscall_nr = i;
+ syscalls_metadata[i] = meta;
+ }
-struct trace_event event_syscall_exit = {
- .trace = print_syscall_exit,
-};
+ return 0;
+}
+core_initcall(init_ftrace_syscalls);
#ifdef CONFIG_EVENT_PROFILE
@@ -387,8 +447,10 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
struct syscall_metadata *sys_data;
struct syscall_trace_enter *rec;
unsigned long flags;
+ char *trace_buf;
char *raw_data;
int syscall_nr;
+ int rctx;
int size;
int cpu;
@@ -412,41 +474,42 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
/* Protect the per cpu buffer, begin the rcu read side */
local_irq_save(flags);
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
+ goto end_recursion;
+
cpu = smp_processor_id();
- if (in_nmi())
- raw_data = rcu_dereference(trace_profile_buf_nmi);
- else
- raw_data = rcu_dereference(trace_profile_buf);
+ trace_buf = rcu_dereference(perf_trace_buf);
- if (!raw_data)
+ if (!trace_buf)
goto end;
- raw_data = per_cpu_ptr(raw_data, cpu);
+ raw_data = per_cpu_ptr(trace_buf, cpu);
/* zero the dead bytes from align to not leak stack to user */
*(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL;
rec = (struct syscall_trace_enter *) raw_data;
tracing_generic_entry_update(&rec->ent, 0, 0);
- rec->ent.type = sys_data->enter_id;
+ rec->ent.type = sys_data->enter_event->id;
rec->nr = syscall_nr;
syscall_get_arguments(current, regs, 0, sys_data->nb_args,
(unsigned long *)&rec->args);
- perf_tp_event(sys_data->enter_id, 0, 1, rec, size);
+ perf_tp_event(sys_data->enter_event->id, 0, 1, rec, size);
end:
+ perf_swevent_put_recursion_context(rctx);
+end_recursion:
local_irq_restore(flags);
}
-int reg_prof_syscall_enter(char *name)
+int prof_sysenter_enable(struct ftrace_event_call *call)
{
int ret = 0;
int num;
- num = syscall_name_to_nr(name);
- if (num < 0 || num >= NR_syscalls)
- return -ENOSYS;
+ num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
if (!sys_prof_refcount_enter)
@@ -462,13 +525,11 @@ int reg_prof_syscall_enter(char *name)
return ret;
}
-void unreg_prof_syscall_enter(char *name)
+void prof_sysenter_disable(struct ftrace_event_call *call)
{
int num;
- num = syscall_name_to_nr(name);
- if (num < 0 || num >= NR_syscalls)
- return;
+ num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
sys_prof_refcount_enter--;
@@ -484,7 +545,9 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
struct syscall_trace_exit *rec;
unsigned long flags;
int syscall_nr;
+ char *trace_buf;
char *raw_data;
+ int rctx;
int size;
int cpu;
@@ -510,17 +573,19 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
/* Protect the per cpu buffer, begin the rcu read side */
local_irq_save(flags);
+
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
+ goto end_recursion;
+
cpu = smp_processor_id();
- if (in_nmi())
- raw_data = rcu_dereference(trace_profile_buf_nmi);
- else
- raw_data = rcu_dereference(trace_profile_buf);
+ trace_buf = rcu_dereference(perf_trace_buf);
- if (!raw_data)
+ if (!trace_buf)
goto end;
- raw_data = per_cpu_ptr(raw_data, cpu);
+ raw_data = per_cpu_ptr(trace_buf, cpu);
/* zero the dead bytes from align to not leak stack to user */
*(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL;
@@ -528,24 +593,24 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
rec = (struct syscall_trace_exit *)raw_data;
tracing_generic_entry_update(&rec->ent, 0, 0);
- rec->ent.type = sys_data->exit_id;
+ rec->ent.type = sys_data->exit_event->id;
rec->nr = syscall_nr;
rec->ret = syscall_get_return_value(current, regs);
- perf_tp_event(sys_data->exit_id, 0, 1, rec, size);
+ perf_tp_event(sys_data->exit_event->id, 0, 1, rec, size);
end:
+ perf_swevent_put_recursion_context(rctx);
+end_recursion:
local_irq_restore(flags);
}
-int reg_prof_syscall_exit(char *name)
+int prof_sysexit_enable(struct ftrace_event_call *call)
{
int ret = 0;
int num;
- num = syscall_name_to_nr(name);
- if (num < 0 || num >= NR_syscalls)
- return -ENOSYS;
+ num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
if (!sys_prof_refcount_exit)
@@ -561,13 +626,11 @@ int reg_prof_syscall_exit(char *name)
return ret;
}
-void unreg_prof_syscall_exit(char *name)
+void prof_sysexit_disable(struct ftrace_event_call *call)
{
int num;
- num = syscall_name_to_nr(name);
- if (num < 0 || num >= NR_syscalls)
- return;
+ num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
sys_prof_refcount_exit--;
diff --git a/kernel/user.c b/kernel/user.c
index 2c000e7132ac..46d0165ca70c 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -330,9 +330,9 @@ done:
*/
static void free_user(struct user_struct *up, unsigned long flags)
{
- spin_unlock_irqrestore(&uidhash_lock, flags);
INIT_DELAYED_WORK(&up->work, cleanup_user_struct);
schedule_delayed_work(&up->work, msecs_to_jiffies(1000));
+ spin_unlock_irqrestore(&uidhash_lock, flags);
}
#else /* CONFIG_USER_SCHED && CONFIG_SYSFS */
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index addfe2df93b1..67e526b6ae81 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -640,6 +640,24 @@ int schedule_delayed_work(struct delayed_work *dwork,
EXPORT_SYMBOL(schedule_delayed_work);
/**
+ * flush_delayed_work - block until a dwork_struct's callback has terminated
+ * @dwork: the delayed work which is to be flushed
+ *
+ * Any timeout is cancelled, and any pending work is run immediately.
+ */
+void flush_delayed_work(struct delayed_work *dwork)
+{
+ if (del_timer_sync(&dwork->timer)) {
+ struct cpu_workqueue_struct *cwq;
+ cwq = wq_per_cpu(keventd_wq, get_cpu());
+ __queue_work(cwq, &dwork->work);
+ put_cpu();
+ }
+ flush_work(&dwork->work);
+}
+EXPORT_SYMBOL(flush_delayed_work);
+
+/**
* schedule_delayed_work_on - queue work in global workqueue on CPU after delay
* @cpu: cpu to use
* @dwork: job to be done
@@ -667,6 +685,7 @@ EXPORT_SYMBOL(schedule_delayed_work_on);
int schedule_on_each_cpu(work_func_t func)
{
int cpu;
+ int orig = -1;
struct work_struct *works;
works = alloc_percpu(struct work_struct);
@@ -674,14 +693,28 @@ int schedule_on_each_cpu(work_func_t func)
return -ENOMEM;
get_online_cpus();
+
+ /*
+ * When running in keventd don't schedule a work item on
+ * itself. Can just call directly because the work queue is
+ * already bound. This also is faster.
+ */
+ if (current_is_keventd())
+ orig = raw_smp_processor_id();
+
for_each_online_cpu(cpu) {
struct work_struct *work = per_cpu_ptr(works, cpu);
INIT_WORK(work, func);
- schedule_work_on(cpu, work);
+ if (cpu != orig)
+ schedule_work_on(cpu, work);
}
+ if (orig >= 0)
+ func(per_cpu_ptr(works, orig));
+
for_each_online_cpu(cpu)
flush_work(per_cpu_ptr(works, cpu));
+
put_online_cpus();
free_percpu(works);
return 0;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 30df5865ecbe..a79c4d0407ab 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -392,7 +392,7 @@ config DEBUG_KMEMLEAK_TEST
config DEBUG_PREEMPT
bool "Debug preemptible kernel"
- depends on DEBUG_KERNEL && PREEMPT && (TRACE_IRQFLAGS_SUPPORT || PPC64)
+ depends on DEBUG_KERNEL && PREEMPT && TRACE_IRQFLAGS_SUPPORT
default y
help
If you say Y here then the kernel will use a debug variant of the
@@ -750,7 +750,7 @@ config RCU_TORTURE_TEST_RUNNABLE
config RCU_CPU_STALL_DETECTOR
bool "Check for stalled CPUs delaying RCU grace periods"
depends on TREE_RCU || TREE_PREEMPT_RCU
- default n
+ default y
help
This option causes RCU to printk information on which
CPUs are delaying the current grace period, but only when
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 58a9f9fc609a..ce6b7eabf674 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -819,9 +819,11 @@ static void check_unmap(struct dma_debug_entry *ref)
err_printk(ref->dev, entry, "DMA-API: device driver frees "
"DMA memory with different CPU address "
"[device address=0x%016llx] [size=%llu bytes] "
- "[cpu alloc address=%p] [cpu free address=%p]",
+ "[cpu alloc address=0x%016llx] "
+ "[cpu free address=0x%016llx]",
ref->dev_addr, ref->size,
- (void *)entry->paddr, (void *)ref->paddr);
+ (unsigned long long)entry->paddr,
+ (unsigned long long)ref->paddr);
}
if (ref->sg_call_ents && ref->type == dma_debug_sg &&
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
index 39f1029e3525..4ebfa5a164d7 100644
--- a/lib/kernel_lock.c
+++ b/lib/kernel_lock.c
@@ -5,10 +5,13 @@
* relegated to obsolescence, but used by various less
* important (or lazy) subsystems.
*/
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/semaphore.h>
+#include <linux/smp_lock.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/bkl.h>
/*
* The 'big kernel lock'
@@ -113,21 +116,26 @@ static inline void __unlock_kernel(void)
* This cannot happen asynchronously, so we only need to
* worry about other CPU's.
*/
-void __lockfunc lock_kernel(void)
+void __lockfunc _lock_kernel(const char *func, const char *file, int line)
{
- int depth = current->lock_depth+1;
+ int depth = current->lock_depth + 1;
+
+ trace_lock_kernel(func, file, line);
+
if (likely(!depth))
__lock_kernel();
current->lock_depth = depth;
}
-void __lockfunc unlock_kernel(void)
+void __lockfunc _unlock_kernel(const char *func, const char *file, int line)
{
BUG_ON(current->lock_depth < 0);
if (likely(--current->lock_depth < 0))
__unlock_kernel();
+
+ trace_unlock_kernel(func, file, line);
}
-EXPORT_SYMBOL(lock_kernel);
-EXPORT_SYMBOL(unlock_kernel);
+EXPORT_SYMBOL(_lock_kernel);
+EXPORT_SYMBOL(_unlock_kernel);
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 23abbd93cae1..92cdd9936e3d 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -200,6 +200,9 @@ radix_tree_node_free(struct radix_tree_node *node)
* ensure that the addition of a single element in the tree cannot fail. On
* success, return zero, with preemption disabled. On error, return -ENOMEM
* with preemption not disabled.
+ *
+ * To make use of this facility, the radix tree must be initialised without
+ * __GFP_WAIT being passed to INIT_RADIX_TREE().
*/
int radix_tree_preload(gfp_t gfp_mask)
{
@@ -543,7 +546,6 @@ out:
}
EXPORT_SYMBOL(radix_tree_tag_clear);
-#ifndef __KERNEL__ /* Only the test harness uses this at present */
/**
* radix_tree_tag_get - get a tag on a radix tree node
* @root: radix tree root
@@ -606,7 +608,6 @@ int radix_tree_tag_get(struct radix_tree_root *root,
}
}
EXPORT_SYMBOL(radix_tree_tag_get);
-#endif
/**
* radix_tree_next_hole - find the next hole (not-present entry)
diff --git a/lib/ratelimit.c b/lib/ratelimit.c
index 26187edcc7ea..09f5ce1810dc 100644
--- a/lib/ratelimit.c
+++ b/lib/ratelimit.c
@@ -7,15 +7,12 @@
* parameter. Now every user can use their own standalone ratelimit_state.
*
* This file is released under the GPLv2.
- *
*/
-#include <linux/kernel.h>
+#include <linux/ratelimit.h>
#include <linux/jiffies.h>
#include <linux/module.h>
-static DEFINE_SPINLOCK(ratelimit_lock);
-
/*
* __ratelimit - rate limiting
* @rs: ratelimit_state data
@@ -23,35 +20,43 @@ static DEFINE_SPINLOCK(ratelimit_lock);
* This enforces a rate limit: not more than @rs->ratelimit_burst callbacks
* in every @rs->ratelimit_jiffies
*/
-int __ratelimit(struct ratelimit_state *rs)
+int ___ratelimit(struct ratelimit_state *rs, const char *func)
{
unsigned long flags;
+ int ret;
if (!rs->interval)
return 1;
- spin_lock_irqsave(&ratelimit_lock, flags);
+ /*
+ * If we contend on this state's lock then almost
+ * by definition we are too busy to print a message,
+ * in addition to the one that will be printed by
+ * the entity that is holding the lock already:
+ */
+ if (!spin_trylock_irqsave(&rs->lock, flags))
+ return 1;
+
if (!rs->begin)
rs->begin = jiffies;
if (time_is_before_jiffies(rs->begin + rs->interval)) {
if (rs->missed)
printk(KERN_WARNING "%s: %d callbacks suppressed\n",
- __func__, rs->missed);
- rs->begin = 0;
+ func, rs->missed);
+ rs->begin = 0;
rs->printed = 0;
- rs->missed = 0;
+ rs->missed = 0;
}
- if (rs->burst && rs->burst > rs->printed)
- goto print;
-
- rs->missed++;
- spin_unlock_irqrestore(&ratelimit_lock, flags);
- return 0;
+ if (rs->burst && rs->burst > rs->printed) {
+ rs->printed++;
+ ret = 1;
+ } else {
+ rs->missed++;
+ ret = 0;
+ }
+ spin_unlock_irqrestore(&rs->lock, flags);
-print:
- rs->printed++;
- spin_unlock_irqrestore(&ratelimit_lock, flags);
- return 1;
+ return ret;
}
-EXPORT_SYMBOL(__ratelimit);
+EXPORT_SYMBOL(___ratelimit);
diff --git a/lib/string.c b/lib/string.c
index b19b87af65a3..e96421ab9a9a 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -246,13 +246,17 @@ EXPORT_SYMBOL(strlcat);
#undef strcmp
int strcmp(const char *cs, const char *ct)
{
- signed char __res;
+ unsigned char c1, c2;
while (1) {
- if ((__res = *cs - *ct++) != 0 || !*cs++)
+ c1 = *cs++;
+ c2 = *ct++;
+ if (c1 != c2)
+ return c1 < c2 ? -1 : 1;
+ if (!c1)
break;
}
- return __res;
+ return 0;
}
EXPORT_SYMBOL(strcmp);
#endif
@@ -266,14 +270,18 @@ EXPORT_SYMBOL(strcmp);
*/
int strncmp(const char *cs, const char *ct, size_t count)
{
- signed char __res = 0;
+ unsigned char c1, c2;
while (count) {
- if ((__res = *cs - *ct++) != 0 || !*cs++)
+ c1 = *cs++;
+ c2 = *ct++;
+ if (c1 != c2)
+ return c1 < c2 ? -1 : 1;
+ if (!c1)
break;
count--;
}
- return __res;
+ return 0;
}
EXPORT_SYMBOL(strncmp);
#endif
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index ac25cd28e807..795472d8ae24 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -97,6 +97,8 @@ static phys_addr_t *io_tlb_orig_addr;
*/
static DEFINE_SPINLOCK(io_tlb_lock);
+static int late_alloc;
+
static int __init
setup_io_tlb_npages(char *str)
{
@@ -109,6 +111,7 @@ setup_io_tlb_npages(char *str)
++str;
if (!strcmp(str, "force"))
swiotlb_force = 1;
+
return 1;
}
__setup("swiotlb=", setup_io_tlb_npages);
@@ -121,8 +124,9 @@ static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
return phys_to_dma(hwdev, virt_to_phys(address));
}
-static void swiotlb_print_info(unsigned long bytes)
+void swiotlb_print_info(void)
{
+ unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT;
phys_addr_t pstart, pend;
pstart = virt_to_phys(io_tlb_start);
@@ -140,7 +144,7 @@ static void swiotlb_print_info(unsigned long bytes)
* structures for the software IO TLB used to implement the DMA API.
*/
void __init
-swiotlb_init_with_default_size(size_t default_size)
+swiotlb_init_with_default_size(size_t default_size, int verbose)
{
unsigned long i, bytes;
@@ -176,14 +180,14 @@ swiotlb_init_with_default_size(size_t default_size)
io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
if (!io_tlb_overflow_buffer)
panic("Cannot allocate SWIOTLB overflow buffer!\n");
-
- swiotlb_print_info(bytes);
+ if (verbose)
+ swiotlb_print_info();
}
void __init
-swiotlb_init(void)
+swiotlb_init(int verbose)
{
- swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */
+ swiotlb_init_with_default_size(64 * (1<<20), verbose); /* default to 64MB */
}
/*
@@ -260,7 +264,9 @@ swiotlb_late_init_with_default_size(size_t default_size)
if (!io_tlb_overflow_buffer)
goto cleanup4;
- swiotlb_print_info(bytes);
+ swiotlb_print_info();
+
+ late_alloc = 1;
return 0;
@@ -281,6 +287,32 @@ cleanup1:
return -ENOMEM;
}
+void __init swiotlb_free(void)
+{
+ if (!io_tlb_overflow_buffer)
+ return;
+
+ if (late_alloc) {
+ free_pages((unsigned long)io_tlb_overflow_buffer,
+ get_order(io_tlb_overflow));
+ free_pages((unsigned long)io_tlb_orig_addr,
+ get_order(io_tlb_nslabs * sizeof(phys_addr_t)));
+ free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs *
+ sizeof(int)));
+ free_pages((unsigned long)io_tlb_start,
+ get_order(io_tlb_nslabs << IO_TLB_SHIFT));
+ } else {
+ free_bootmem_late(__pa(io_tlb_overflow_buffer),
+ io_tlb_overflow);
+ free_bootmem_late(__pa(io_tlb_orig_addr),
+ io_tlb_nslabs * sizeof(phys_addr_t));
+ free_bootmem_late(__pa(io_tlb_list),
+ io_tlb_nslabs * sizeof(int));
+ free_bootmem_late(__pa(io_tlb_start),
+ io_tlb_nslabs << IO_TLB_SHIFT);
+ }
+}
+
static int is_swiotlb_buffer(phys_addr_t paddr)
{
return paddr >= virt_to_phys(io_tlb_start) &&
diff --git a/mm/Kconfig b/mm/Kconfig
index 57963c6063d1..44cf6f0a3a6d 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -67,7 +67,7 @@ config DISCONTIGMEM
config SPARSEMEM
def_bool y
- depends on SPARSEMEM_MANUAL
+ depends on (!SELECT_MEMORY_MODEL && ARCH_SPARSEMEM_ENABLE) || SPARSEMEM_MANUAL
config FLATMEM
def_bool y
@@ -128,11 +128,8 @@ config SPARSEMEM_VMEMMAP
config MEMORY_HOTPLUG
bool "Allow for memory hot-add"
depends on SPARSEMEM || X86_64_ACPI_NUMA
- depends on HOTPLUG && !(HIBERNATION && !S390) && ARCH_ENABLE_MEMORY_HOTPLUG
- depends on (IA64 || X86 || PPC64 || SUPERH || S390)
-
-comment "Memory hotplug is currently incompatible with Software Suspend"
- depends on SPARSEMEM && HOTPLUG && HIBERNATION && !S390
+ depends on HOTPLUG && ARCH_ENABLE_MEMORY_HOTPLUG
+ depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390)
config MEMORY_HOTPLUG_SPARSE
def_bool y
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 5a37e2055717..67a33a5a1a93 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -604,15 +604,36 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
/*
* Finally, kill the kernel threads. We don't need to be RCU
- * safe anymore, since the bdi is gone from visibility.
+ * safe anymore, since the bdi is gone from visibility. Force
+ * unfreeze of the thread before calling kthread_stop(), otherwise
+ * it would never exet if it is currently stuck in the refrigerator.
*/
- list_for_each_entry(wb, &bdi->wb_list, list)
+ list_for_each_entry(wb, &bdi->wb_list, list) {
+ wb->task->flags &= ~PF_FROZEN;
kthread_stop(wb->task);
+ }
+}
+
+/*
+ * This bdi is going away now, make sure that no super_blocks point to it
+ */
+static void bdi_prune_sb(struct backing_dev_info *bdi)
+{
+ struct super_block *sb;
+
+ spin_lock(&sb_lock);
+ list_for_each_entry(sb, &super_blocks, s_list) {
+ if (sb->s_bdi == bdi)
+ sb->s_bdi = NULL;
+ }
+ spin_unlock(&sb_lock);
}
void bdi_unregister(struct backing_dev_info *bdi)
{
if (bdi->dev) {
+ bdi_prune_sb(bdi);
+
if (!bdi_cap_flush_forker(bdi))
bdi_wb_shutdown(bdi);
bdi_debug_unregister(bdi);
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 555d5d2731c6..d1dc23cc7f10 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -143,6 +143,30 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
return init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages);
}
+/*
+ * free_bootmem_late - free bootmem pages directly to page allocator
+ * @addr: starting address of the range
+ * @size: size of the range in bytes
+ *
+ * This is only useful when the bootmem allocator has already been torn
+ * down, but we are still initializing the system. Pages are given directly
+ * to the page allocator, no bootmem metadata is updated because it is gone.
+ */
+void __init free_bootmem_late(unsigned long addr, unsigned long size)
+{
+ unsigned long cursor, end;
+
+ kmemleak_free_part(__va(addr), size);
+
+ cursor = PFN_UP(addr);
+ end = PFN_DOWN(addr + size);
+
+ for (; cursor < end; cursor++) {
+ __free_pages_bootmem(pfn_to_page(cursor), 0);
+ totalram_pages++;
+ }
+}
+
static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
{
int aligned;
diff --git a/mm/highmem.c b/mm/highmem.c
index 25878cc49daa..9c1e627f282e 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -426,16 +426,21 @@ void __init page_address_init(void)
void debug_kmap_atomic(enum km_type type)
{
- static unsigned warn_count = 10;
+ static int warn_count = 10;
- if (unlikely(warn_count == 0))
+ if (unlikely(warn_count < 0))
return;
if (unlikely(in_interrupt())) {
- if (in_irq()) {
+ if (in_nmi()) {
+ if (type != KM_NMI && type != KM_NMI_PTE) {
+ WARN_ON(1);
+ warn_count--;
+ }
+ } else if (in_irq()) {
if (type != KM_IRQ0 && type != KM_IRQ1 &&
type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ &&
- type != KM_BOUNCE_READ) {
+ type != KM_BOUNCE_READ && type != KM_IRQ_PTE) {
WARN_ON(1);
warn_count--;
}
@@ -452,7 +457,9 @@ void debug_kmap_atomic(enum km_type type)
}
if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
- type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) {
+ type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ ||
+ type == KM_IRQ_PTE || type == KM_NMI ||
+ type == KM_NMI_PTE ) {
if (!irqs_disabled()) {
WARN_ON(1);
warn_count--;
diff --git a/mm/ksm.c b/mm/ksm.c
index bef1af4f77e3..5575f8628fef 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1012,6 +1012,7 @@ static struct rmap_item *unstable_tree_search_insert(struct page *page,
struct rmap_item *tree_rmap_item;
int ret;
+ cond_resched();
tree_rmap_item = rb_entry(*new, struct rmap_item, node);
page2[0] = get_mergeable_page(tree_rmap_item);
if (!page2[0])
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 729d4b15b645..dacc64183874 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -35,6 +35,7 @@
#include <linux/mm.h>
#include <linux/page-flags.h>
#include <linux/sched.h>
+#include <linux/ksm.h>
#include <linux/rmap.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
@@ -370,9 +371,6 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
int ret = FAILED;
struct address_space *mapping;
- if (!isolate_lru_page(p))
- page_cache_release(p);
-
/*
* For anonymous pages we're done the only reference left
* should be the one m_f() holds.
@@ -498,30 +496,18 @@ static int me_pagecache_dirty(struct page *p, unsigned long pfn)
*/
static int me_swapcache_dirty(struct page *p, unsigned long pfn)
{
- int ret = FAILED;
-
ClearPageDirty(p);
/* Trigger EIO in shmem: */
ClearPageUptodate(p);
- if (!isolate_lru_page(p)) {
- page_cache_release(p);
- ret = DELAYED;
- }
-
- return ret;
+ return DELAYED;
}
static int me_swapcache_clean(struct page *p, unsigned long pfn)
{
- int ret = FAILED;
-
- if (!isolate_lru_page(p)) {
- page_cache_release(p);
- ret = RECOVERED;
- }
delete_from_swap_cache(p);
- return ret;
+
+ return RECOVERED;
}
/*
@@ -611,8 +597,6 @@ static struct page_state {
{ 0, 0, "unknown page state", me_unknown },
};
-#undef lru
-
static void action_result(unsigned long pfn, char *msg, int result)
{
struct page *page = NULL;
@@ -629,13 +613,16 @@ static int page_action(struct page_state *ps, struct page *p,
unsigned long pfn, int ref)
{
int result;
+ int count;
result = ps->action(p, pfn);
action_result(pfn, ps->msg, result);
- if (page_count(p) != 1 + ref)
+
+ count = page_count(p) - 1 - ref;
+ if (count != 0)
printk(KERN_ERR
"MCE %#lx: %s page still referenced by %d users\n",
- pfn, ps->msg, page_count(p) - 1);
+ pfn, ps->msg, count);
/* Could do more checks here if page looks ok */
/*
@@ -661,12 +648,9 @@ static void hwpoison_user_mappings(struct page *p, unsigned long pfn,
int i;
int kill = 1;
- if (PageReserved(p) || PageCompound(p) || PageSlab(p))
+ if (PageReserved(p) || PageCompound(p) || PageSlab(p) || PageKsm(p))
return;
- if (!PageLRU(p))
- lru_add_drain_all();
-
/*
* This check implies we don't kill processes if their pages
* are in the swap cache early. Those are always late kills.
@@ -738,6 +722,7 @@ static void hwpoison_user_mappings(struct page *p, unsigned long pfn,
int __memory_failure(unsigned long pfn, int trapno, int ref)
{
+ unsigned long lru_flag;
struct page_state *ps;
struct page *p;
int res;
@@ -775,6 +760,24 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
}
/*
+ * We ignore non-LRU pages for good reasons.
+ * - PG_locked is only well defined for LRU pages and a few others
+ * - to avoid races with __set_page_locked()
+ * - to avoid races with __SetPageSlab*() (and more non-atomic ops)
+ * The check (unnecessarily) ignores LRU pages being isolated and
+ * walked by the page reclaim code, however that's not a big loss.
+ */
+ if (!PageLRU(p))
+ lru_add_drain_all();
+ lru_flag = p->flags & lru;
+ if (isolate_lru_page(p)) {
+ action_result(pfn, "non LRU", IGNORED);
+ put_page(p);
+ return -EBUSY;
+ }
+ page_cache_release(p);
+
+ /*
* Lock the page and wait for writeback to finish.
* It's very difficult to mess with pages currently under IO
* and in many cases impossible, so we just avoid it here.
@@ -790,7 +793,7 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
/*
* Torn down by someone else?
*/
- if (PageLRU(p) && !PageSwapCache(p) && p->mapping == NULL) {
+ if ((lru_flag & lru) && !PageSwapCache(p) && p->mapping == NULL) {
action_result(pfn, "already truncated LRU", IGNORED);
res = 0;
goto out;
@@ -798,7 +801,7 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
res = -EBUSY;
for (ps = error_states;; ps++) {
- if ((p->flags & ps->mask) == ps->res) {
+ if (((p->flags | lru_flag)& ps->mask) == ps->res) {
res = page_action(ps, p, pfn, ref);
break;
}
diff --git a/mm/memory.c b/mm/memory.c
index 7e91b5f9f690..6ab19dd4a199 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -641,6 +641,7 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
pmd_t *dst_pmd, pmd_t *src_pmd, struct vm_area_struct *vma,
unsigned long addr, unsigned long end)
{
+ pte_t *orig_src_pte, *orig_dst_pte;
pte_t *src_pte, *dst_pte;
spinlock_t *src_ptl, *dst_ptl;
int progress = 0;
@@ -654,6 +655,8 @@ again:
src_pte = pte_offset_map_nested(src_pmd, addr);
src_ptl = pte_lockptr(src_mm, src_pmd);
spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
+ orig_src_pte = src_pte;
+ orig_dst_pte = dst_pte;
arch_enter_lazy_mmu_mode();
do {
@@ -677,9 +680,9 @@ again:
arch_leave_lazy_mmu_mode();
spin_unlock(src_ptl);
- pte_unmap_nested(src_pte - 1);
+ pte_unmap_nested(orig_src_pte);
add_mm_rss(dst_mm, rss[0], rss[1]);
- pte_unmap_unlock(dst_pte - 1, dst_ptl);
+ pte_unmap_unlock(orig_dst_pte, dst_ptl);
cond_resched();
if (addr != end)
goto again;
@@ -1820,10 +1823,10 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
token = pmd_pgtable(*pmd);
do {
- err = fn(pte, token, addr, data);
+ err = fn(pte++, token, addr, data);
if (err)
break;
- } while (pte++, addr += PAGE_SIZE, addr != end);
+ } while (addr += PAGE_SIZE, addr != end);
arch_leave_lazy_mmu_mode();
@@ -2539,7 +2542,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
} else if (PageHWPoison(page)) {
ret = VM_FAULT_HWPOISON;
delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
- goto out;
+ goto out_release;
}
lock_page(page);
@@ -2611,6 +2614,7 @@ out_nomap:
pte_unmap_unlock(page_table, ptl);
out_page:
unlock_page(page);
+out_release:
page_cache_release(page);
return ret;
}
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 821dee596377..2047465cd27c 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -26,6 +26,7 @@
#include <linux/migrate.h>
#include <linux/page-isolation.h>
#include <linux/pfn.h>
+#include <linux/suspend.h>
#include <asm/tlbflush.h>
@@ -447,7 +448,8 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
}
#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
-static pg_data_t *hotadd_new_pgdat(int nid, u64 start)
+/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
+static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
{
struct pglist_data *pgdat;
unsigned long zones_size[MAX_NR_ZONES] = {0};
@@ -484,14 +486,18 @@ int __ref add_memory(int nid, u64 start, u64 size)
struct resource *res;
int ret;
+ lock_system_sleep();
+
res = register_memory_resource(start, size);
+ ret = -EEXIST;
if (!res)
- return -EEXIST;
+ goto out;
if (!node_online(nid)) {
pgdat = hotadd_new_pgdat(nid, start);
+ ret = -ENOMEM;
if (!pgdat)
- return -ENOMEM;
+ goto out;
new_pgdat = 1;
}
@@ -514,7 +520,8 @@ int __ref add_memory(int nid, u64 start, u64 size)
BUG_ON(ret);
}
- return ret;
+ goto out;
+
error:
/* rollback pgdat allocation and others */
if (new_pgdat)
@@ -522,6 +529,8 @@ error:
if (res)
release_memory_resource(res);
+out:
+ unlock_system_sleep();
return ret;
}
EXPORT_SYMBOL_GPL(add_memory);
@@ -758,6 +767,8 @@ int offline_pages(unsigned long start_pfn,
if (!test_pages_in_a_zone(start_pfn, end_pfn))
return -EINVAL;
+ lock_system_sleep();
+
zone = page_zone(pfn_to_page(start_pfn));
node = zone_to_nid(zone);
nr_pages = end_pfn - start_pfn;
@@ -765,7 +776,7 @@ int offline_pages(unsigned long start_pfn,
/* set above range as isolated */
ret = start_isolate_page_range(start_pfn, end_pfn);
if (ret)
- return ret;
+ goto out;
arg.start_pfn = start_pfn;
arg.nr_pages = nr_pages;
@@ -843,6 +854,7 @@ repeat:
writeback_set_ratelimit();
memory_notify(MEM_OFFLINE, &arg);
+ unlock_system_sleep();
return 0;
failed_removal:
@@ -852,6 +864,8 @@ failed_removal:
/* pushback to free area */
undo_isolate_page_range(start_pfn, end_pfn);
+out:
+ unlock_system_sleep();
return ret;
}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 7dd9d9f80694..4545d5944243 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1024,7 +1024,7 @@ static long do_mbind(unsigned long start, unsigned long len,
err = migrate_prep();
if (err)
- return err;
+ goto mpol_out;
}
{
NODEMASK_SCRATCH(scratch);
@@ -1039,10 +1039,9 @@ static long do_mbind(unsigned long start, unsigned long len,
err = -ENOMEM;
NODEMASK_SCRATCH_FREE(scratch);
}
- if (err) {
- mpol_put(new);
- return err;
- }
+ if (err)
+ goto mpol_out;
+
vma = check_range(mm, start, end, nmask,
flags | MPOL_MF_INVERT, &pagelist);
@@ -1058,9 +1057,11 @@ static long do_mbind(unsigned long start, unsigned long len,
if (!err && nr_failed && (flags & MPOL_MF_STRICT))
err = -EIO;
- }
+ } else
+ putback_lru_pages(&pagelist);
up_write(&mm->mmap_sem);
+ mpol_out:
mpol_put(new);
return err;
}
diff --git a/mm/migrate.c b/mm/migrate.c
index 1a4bf4813780..7dbcb22316d2 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -602,7 +602,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
struct page *newpage = get_new_page(page, private, &result);
int rcu_locked = 0;
int charge = 0;
- struct mem_cgroup *mem;
+ struct mem_cgroup *mem = NULL;
if (!newpage)
return -ENOMEM;
diff --git a/mm/mmap.c b/mm/mmap.c
index 73f5e4b64010..292ddc3cef9c 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -20,7 +20,6 @@
#include <linux/fs.h>
#include <linux/personality.h>
#include <linux/security.h>
-#include <linux/ima.h>
#include <linux/hugetlb.h>
#include <linux/profile.h>
#include <linux/module.h>
@@ -1061,9 +1060,6 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
if (error)
return error;
- error = ima_file_mmap(file, prot);
- if (error)
- return error;
return mmap_region(file, addr, len, flags, vm_flags, pgoff);
}
diff --git a/mm/nommu.c b/mm/nommu.c
index 5189b5aed8c0..9876fa0c3ad3 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1362,9 +1362,11 @@ share:
error_just_free:
up_write(&nommu_region_sem);
error:
- fput(region->vm_file);
+ if (region->vm_file)
+ fput(region->vm_file);
kmem_cache_free(vm_region_jar, region);
- fput(vma->vm_file);
+ if (vma->vm_file)
+ fput(vma->vm_file);
if (vma->vm_flags & VM_EXECUTABLE)
removed_exe_file_vma(vma->vm_mm);
kmem_cache_free(vm_area_cachep, vma);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bf720550b44d..2bc2ac63f41e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1769,7 +1769,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
* See also cpuset_zone_allowed() comment in kernel/cpuset.c.
*/
alloc_flags &= ~ALLOC_CPUSET;
- } else if (unlikely(rt_task(p)))
+ } else if (unlikely(rt_task(p)) && !in_interrupt())
alloc_flags |= ALLOC_HARDER;
if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) {
@@ -1817,9 +1817,9 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
if (NUMA_BUILD && (gfp_mask & GFP_THISNODE) == GFP_THISNODE)
goto nopage;
+restart:
wake_all_kswapd(order, zonelist, high_zoneidx);
-restart:
/*
* OK, we're below the kswapd watermark and have kicked background
* reclaim. Now things get more complex, so set up alloc_flags according
@@ -2183,7 +2183,7 @@ void show_free_areas(void)
printk("active_anon:%lu inactive_anon:%lu isolated_anon:%lu\n"
" active_file:%lu inactive_file:%lu isolated_file:%lu\n"
" unevictable:%lu"
- " dirty:%lu writeback:%lu unstable:%lu buffer:%lu\n"
+ " dirty:%lu writeback:%lu unstable:%lu\n"
" free:%lu slab_reclaimable:%lu slab_unreclaimable:%lu\n"
" mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n",
global_page_state(NR_ACTIVE_ANON),
@@ -2196,7 +2196,6 @@ void show_free_areas(void)
global_page_state(NR_FILE_DIRTY),
global_page_state(NR_WRITEBACK),
global_page_state(NR_UNSTABLE_NFS),
- nr_blockdev_pages(),
global_page_state(NR_FREE_PAGES),
global_page_state(NR_SLAB_RECLAIMABLE),
global_page_state(NR_SLAB_UNRECLAIMABLE),
diff --git a/mm/percpu.c b/mm/percpu.c
index 6af78c1ee704..5adfc268b408 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -153,7 +153,10 @@ static int pcpu_reserved_chunk_limit;
*
* During allocation, pcpu_alloc_mutex is kept locked all the time and
* pcpu_lock is grabbed and released as necessary. All actual memory
- * allocations are done using GFP_KERNEL with pcpu_lock released.
+ * allocations are done using GFP_KERNEL with pcpu_lock released. In
+ * general, percpu memory can't be allocated with irq off but
+ * irqsave/restore are still used in alloc path so that it can be used
+ * from early init path - sched_init() specifically.
*
* Free path accesses and alters only the index data structures, so it
* can be safely called from atomic context. When memory needs to be
@@ -352,62 +355,86 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
}
/**
- * pcpu_extend_area_map - extend area map for allocation
- * @chunk: target chunk
+ * pcpu_need_to_extend - determine whether chunk area map needs to be extended
+ * @chunk: chunk of interest
*
- * Extend area map of @chunk so that it can accomodate an allocation.
- * A single allocation can split an area into three areas, so this
- * function makes sure that @chunk->map has at least two extra slots.
+ * Determine whether area map of @chunk needs to be extended to
+ * accomodate a new allocation.
*
* CONTEXT:
- * pcpu_alloc_mutex, pcpu_lock. pcpu_lock is released and reacquired
- * if area map is extended.
+ * pcpu_lock.
*
* RETURNS:
- * 0 if noop, 1 if successfully extended, -errno on failure.
+ * New target map allocation length if extension is necessary, 0
+ * otherwise.
*/
-static int pcpu_extend_area_map(struct pcpu_chunk *chunk)
+static int pcpu_need_to_extend(struct pcpu_chunk *chunk)
{
int new_alloc;
- int *new;
- size_t size;
- /* has enough? */
if (chunk->map_alloc >= chunk->map_used + 2)
return 0;
- spin_unlock_irq(&pcpu_lock);
-
new_alloc = PCPU_DFL_MAP_ALLOC;
while (new_alloc < chunk->map_used + 2)
new_alloc *= 2;
- new = pcpu_mem_alloc(new_alloc * sizeof(new[0]));
- if (!new) {
- spin_lock_irq(&pcpu_lock);
+ return new_alloc;
+}
+
+/**
+ * pcpu_extend_area_map - extend area map of a chunk
+ * @chunk: chunk of interest
+ * @new_alloc: new target allocation length of the area map
+ *
+ * Extend area map of @chunk to have @new_alloc entries.
+ *
+ * CONTEXT:
+ * Does GFP_KERNEL allocation. Grabs and releases pcpu_lock.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc)
+{
+ int *old = NULL, *new = NULL;
+ size_t old_size = 0, new_size = new_alloc * sizeof(new[0]);
+ unsigned long flags;
+
+ new = pcpu_mem_alloc(new_size);
+ if (!new)
return -ENOMEM;
- }
- /*
- * Acquire pcpu_lock and switch to new area map. Only free
- * could have happened inbetween, so map_used couldn't have
- * grown.
- */
- spin_lock_irq(&pcpu_lock);
- BUG_ON(new_alloc < chunk->map_used + 2);
+ /* acquire pcpu_lock and switch to new area map */
+ spin_lock_irqsave(&pcpu_lock, flags);
+
+ if (new_alloc <= chunk->map_alloc)
+ goto out_unlock;
- size = chunk->map_alloc * sizeof(chunk->map[0]);
- memcpy(new, chunk->map, size);
+ old_size = chunk->map_alloc * sizeof(chunk->map[0]);
+ memcpy(new, chunk->map, old_size);
/*
* map_alloc < PCPU_DFL_MAP_ALLOC indicates that the chunk is
* one of the first chunks and still using static map.
*/
if (chunk->map_alloc >= PCPU_DFL_MAP_ALLOC)
- pcpu_mem_free(chunk->map, size);
+ old = chunk->map;
chunk->map_alloc = new_alloc;
chunk->map = new;
+ new = NULL;
+
+out_unlock:
+ spin_unlock_irqrestore(&pcpu_lock, flags);
+
+ /*
+ * pcpu_mem_free() might end up calling vfree() which uses
+ * IRQ-unsafe lock and thus can't be called under pcpu_lock.
+ */
+ pcpu_mem_free(old, old_size);
+ pcpu_mem_free(new, new_size);
+
return 0;
}
@@ -1046,7 +1073,8 @@ static void *pcpu_alloc(size_t size, size_t align, bool reserved)
static int warn_limit = 10;
struct pcpu_chunk *chunk;
const char *err;
- int slot, off;
+ int slot, off, new_alloc;
+ unsigned long flags;
if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE)) {
WARN(true, "illegal size (%zu) or align (%zu) for "
@@ -1055,19 +1083,30 @@ static void *pcpu_alloc(size_t size, size_t align, bool reserved)
}
mutex_lock(&pcpu_alloc_mutex);
- spin_lock_irq(&pcpu_lock);
+ spin_lock_irqsave(&pcpu_lock, flags);
/* serve reserved allocations from the reserved chunk if available */
if (reserved && pcpu_reserved_chunk) {
chunk = pcpu_reserved_chunk;
- if (size > chunk->contig_hint ||
- pcpu_extend_area_map(chunk) < 0) {
- err = "failed to extend area map of reserved chunk";
+
+ if (size > chunk->contig_hint) {
+ err = "alloc from reserved chunk failed";
goto fail_unlock;
}
+
+ while ((new_alloc = pcpu_need_to_extend(chunk))) {
+ spin_unlock_irqrestore(&pcpu_lock, flags);
+ if (pcpu_extend_area_map(chunk, new_alloc) < 0) {
+ err = "failed to extend area map of reserved chunk";
+ goto fail_unlock_mutex;
+ }
+ spin_lock_irqsave(&pcpu_lock, flags);
+ }
+
off = pcpu_alloc_area(chunk, size, align);
if (off >= 0)
goto area_found;
+
err = "alloc from reserved chunk failed";
goto fail_unlock;
}
@@ -1079,14 +1118,20 @@ restart:
if (size > chunk->contig_hint)
continue;
- switch (pcpu_extend_area_map(chunk)) {
- case 0:
- break;
- case 1:
- goto restart; /* pcpu_lock dropped, restart */
- default:
- err = "failed to extend area map";
- goto fail_unlock;
+ new_alloc = pcpu_need_to_extend(chunk);
+ if (new_alloc) {
+ spin_unlock_irqrestore(&pcpu_lock, flags);
+ if (pcpu_extend_area_map(chunk,
+ new_alloc) < 0) {
+ err = "failed to extend area map";
+ goto fail_unlock_mutex;
+ }
+ spin_lock_irqsave(&pcpu_lock, flags);
+ /*
+ * pcpu_lock has been dropped, need to
+ * restart cpu_slot list walking.
+ */
+ goto restart;
}
off = pcpu_alloc_area(chunk, size, align);
@@ -1096,7 +1141,7 @@ restart:
}
/* hmmm... no space left, create a new chunk */
- spin_unlock_irq(&pcpu_lock);
+ spin_unlock_irqrestore(&pcpu_lock, flags);
chunk = alloc_pcpu_chunk();
if (!chunk) {
@@ -1104,16 +1149,16 @@ restart:
goto fail_unlock_mutex;
}
- spin_lock_irq(&pcpu_lock);
+ spin_lock_irqsave(&pcpu_lock, flags);
pcpu_chunk_relocate(chunk, -1);
goto restart;
area_found:
- spin_unlock_irq(&pcpu_lock);
+ spin_unlock_irqrestore(&pcpu_lock, flags);
/* populate, map and clear the area */
if (pcpu_populate_chunk(chunk, off, size)) {
- spin_lock_irq(&pcpu_lock);
+ spin_lock_irqsave(&pcpu_lock, flags);
pcpu_free_area(chunk, off);
err = "failed to populate";
goto fail_unlock;
@@ -1125,7 +1170,7 @@ area_found:
return __addr_to_pcpu_ptr(chunk->base_addr + off);
fail_unlock:
- spin_unlock_irq(&pcpu_lock);
+ spin_unlock_irqrestore(&pcpu_lock, flags);
fail_unlock_mutex:
mutex_unlock(&pcpu_alloc_mutex);
if (warn_limit) {
diff --git a/mm/swapfile.c b/mm/swapfile.c
index a1bc6b9af9a2..9c590eef7912 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1151,8 +1151,7 @@ static int try_to_unuse(unsigned int type)
} else
retval = unuse_mm(mm, entry, page);
- if (set_start_mm &&
- swap_count(*swap_map) < swcount) {
+ if (set_start_mm && *swap_map < swcount) {
mmput(new_start_mm);
atomic_inc(&mm->mm_users);
new_start_mm = mm;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 64e438898832..777af57fd8c8 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -544,6 +544,16 @@ redo:
*/
lru = LRU_UNEVICTABLE;
add_page_to_unevictable_list(page);
+ /*
+ * When racing with an mlock clearing (page is
+ * unlocked), make sure that if the other thread does
+ * not observe our setting of PG_lru and fails
+ * isolation, we see PG_mlocked cleared below and move
+ * the page back to the evictable list.
+ *
+ * The other side is TestClearPageMlocked().
+ */
+ smp_mb();
}
/*
@@ -1088,7 +1098,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
int lumpy_reclaim = 0;
while (unlikely(too_many_isolated(zone, file, sc))) {
- congestion_wait(WRITE, HZ/10);
+ congestion_wait(BLK_RW_ASYNC, HZ/10);
/* We are about to die and free our memory. Return now. */
if (fatal_signal_pending(current))
@@ -1356,7 +1366,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
* IO, plus JVM can create lots of anon VM_EXEC pages,
* so we ignore them here.
*/
- if ((vm_flags & VM_EXEC) && !PageAnon(page)) {
+ if ((vm_flags & VM_EXEC) && page_is_file_cache(page)) {
list_add(&page->lru, &l_active);
continue;
}
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 8836575f9d79..a29c5ab5815c 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -281,8 +281,11 @@ out_uninit_applicant:
if (ngrp)
vlan_gvrp_uninit_applicant(real_dev);
out_free_group:
- if (ngrp)
- vlan_group_free(ngrp);
+ if (ngrp) {
+ hlist_del_rcu(&ngrp->hlist);
+ /* Free the group, after all cpu's are done. */
+ call_rcu(&ngrp->rcu, vlan_rcu_free);
+ }
return err;
}
diff --git a/net/9p/client.c b/net/9p/client.c
index 5bf5f227dbe0..8af95b2dddd6 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -582,11 +582,9 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
memset(&fid->qid, 0, sizeof(struct p9_qid));
fid->mode = -1;
- fid->rdir_fpos = 0;
fid->uid = current_fsuid();
fid->clnt = clnt;
- fid->aux = NULL;
-
+ fid->rdir = NULL;
spin_lock_irqsave(&clnt->lock, flags);
list_add(&fid->flist, &clnt->fidlist);
spin_unlock_irqrestore(&clnt->lock, flags);
@@ -609,6 +607,7 @@ static void p9_fid_destroy(struct p9_fid *fid)
spin_lock_irqsave(&clnt->lock, flags);
list_del(&fid->flist);
spin_unlock_irqrestore(&clnt->lock, flags);
+ kfree(fid->rdir);
kfree(fid);
}
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index b2e07f0dd298..ea1e3daabefe 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -43,7 +43,6 @@
#include <net/9p/transport.h>
#include <linux/scatterlist.h>
#include <linux/virtio.h>
-#include <linux/virtio_ids.h>
#include <linux/virtio_9p.h>
#define VIRTQUEUE_NUM 128
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index a9750984f772..b7c4224f4e7d 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -211,6 +211,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn->type = type;
conn->mode = HCI_CM_ACTIVE;
conn->state = BT_OPEN;
+ conn->auth_type = HCI_AT_GENERAL_BONDING;
conn->power_save = 1;
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 7f939ce29801..2bc6f6a8de68 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -92,6 +92,8 @@ static void add_conn(struct work_struct *work)
dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
+ dev_set_drvdata(&conn->dev, conn);
+
if (device_add(&conn->dev) < 0) {
BT_ERR("Failed to register connection device");
return;
@@ -144,8 +146,6 @@ void hci_conn_init_sysfs(struct hci_conn *conn)
conn->dev.class = bt_class;
conn->dev.parent = &hdev->dev;
- dev_set_drvdata(&conn->dev, conn);
-
device_initialize(&conn->dev);
INIT_WORK(&conn->work_add, add_conn);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 555d9da1869b..947f8bbb4bb3 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -555,12 +555,12 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
conn->feat_mask = 0;
- setup_timer(&conn->info_timer, l2cap_info_timeout,
- (unsigned long) conn);
-
spin_lock_init(&conn->lock);
rwlock_init(&conn->chan_list.lock);
+ setup_timer(&conn->info_timer, l2cap_info_timeout,
+ (unsigned long) conn);
+
conn->disc_reason = 0x13;
return conn;
@@ -783,6 +783,9 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
/* Default config options */
pi->conf_len = 0;
pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+ skb_queue_head_init(TX_QUEUE(sk));
+ skb_queue_head_init(SREJ_QUEUE(sk));
+ INIT_LIST_HEAD(SREJ_LIST(sk));
}
static struct proto l2cap_proto = {
@@ -2202,7 +2205,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_conf_req *req = data;
- struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM };
+ struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
void *ptr = req->data;
BT_DBG("sk %p", sk);
@@ -2391,6 +2394,10 @@ done:
rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
pi->conf_state |= L2CAP_CONF_MODE_DONE;
+
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+ sizeof(rfc), (unsigned long) &rfc);
+
break;
case L2CAP_MODE_STREAMING:
@@ -2398,6 +2405,10 @@ done:
pi->max_pdu_size = rfc.max_pdu_size;
pi->conf_state |= L2CAP_CONF_MODE_DONE;
+
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+ sizeof(rfc), (unsigned long) &rfc);
+
break;
default:
@@ -2407,9 +2418,6 @@ done:
rfc.mode = pi->mode;
}
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
- sizeof(rfc), (unsigned long) &rfc);
-
if (result == L2CAP_CONF_SUCCESS)
pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index b1b3b0fbf41c..4a9f52732655 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -377,12 +377,16 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
struct net_bridge_port *p;
int err = 0;
- if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER)
+ /* Don't allow bridging non-ethernet like devices */
+ if ((dev->flags & IFF_LOOPBACK) ||
+ dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN)
return -EINVAL;
+ /* No bridging of bridges */
if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit)
return -ELOOP;
+ /* Device is already being bridged */
if (dev->br_port != NULL)
return -EBUSY;
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 597da4f8f888..e8d58f33fe09 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -132,23 +132,27 @@ static inline struct bcm_sock *bcm_sk(const struct sock *sk)
/*
* procfs functions
*/
-static char *bcm_proc_getifname(int ifindex)
+static char *bcm_proc_getifname(char *result, int ifindex)
{
struct net_device *dev;
if (!ifindex)
return "any";
- /* no usage counting */
+ read_lock(&dev_base_lock);
dev = __dev_get_by_index(&init_net, ifindex);
if (dev)
- return dev->name;
+ strcpy(result, dev->name);
+ else
+ strcpy(result, "???");
+ read_unlock(&dev_base_lock);
- return "???";
+ return result;
}
static int bcm_proc_show(struct seq_file *m, void *v)
{
+ char ifname[IFNAMSIZ];
struct sock *sk = (struct sock *)m->private;
struct bcm_sock *bo = bcm_sk(sk);
struct bcm_op *op;
@@ -157,7 +161,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
seq_printf(m, " / sk %p", sk);
seq_printf(m, " / bo %p", bo);
seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs);
- seq_printf(m, " / bound %s", bcm_proc_getifname(bo->ifindex));
+ seq_printf(m, " / bound %s", bcm_proc_getifname(ifname, bo->ifindex));
seq_printf(m, " <<<\n");
list_for_each_entry(op, &bo->rx_ops, list) {
@@ -169,7 +173,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
continue;
seq_printf(m, "rx_op: %03X %-5s ",
- op->can_id, bcm_proc_getifname(op->ifindex));
+ op->can_id, bcm_proc_getifname(ifname, op->ifindex));
seq_printf(m, "[%d]%c ", op->nframes,
(op->flags & RX_CHECK_DLC)?'d':' ');
if (op->kt_ival1.tv64)
@@ -194,7 +198,8 @@ static int bcm_proc_show(struct seq_file *m, void *v)
list_for_each_entry(op, &bo->tx_ops, list) {
seq_printf(m, "tx_op: %03X %s [%d] ",
- op->can_id, bcm_proc_getifname(op->ifindex),
+ op->can_id,
+ bcm_proc_getifname(ifname, op->ifindex),
op->nframes);
if (op->kt_ival1.tv64)
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 1c6cf3a1a4f6..4ade3011bb3c 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -224,6 +224,15 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
consume_skb(skb);
sk_mem_reclaim_partial(sk);
}
+EXPORT_SYMBOL(skb_free_datagram);
+
+void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb)
+{
+ lock_sock(sk);
+ skb_free_datagram(sk, skb);
+ release_sock(sk);
+}
+EXPORT_SYMBOL(skb_free_datagram_locked);
/**
* skb_kill_datagram - Free a datagram skbuff forcibly
@@ -752,5 +761,4 @@ unsigned int datagram_poll(struct file *file, struct socket *sock,
EXPORT_SYMBOL(datagram_poll);
EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec);
EXPORT_SYMBOL(skb_copy_datagram_iovec);
-EXPORT_SYMBOL(skb_free_datagram);
EXPORT_SYMBOL(skb_recv_datagram);
diff --git a/net/core/dev.c b/net/core/dev.c
index b8f74cfb1bfd..fe10551d3671 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -942,14 +942,15 @@ rollback:
ret = notifier_to_errno(ret);
if (ret) {
- if (err) {
- printk(KERN_ERR
- "%s: name change rollback failed: %d.\n",
- dev->name, ret);
- } else {
+ /* err >= 0 after dev_alloc_name() or stores the first errno */
+ if (err >= 0) {
err = ret;
memcpy(dev->name, oldname, IFNAMSIZ);
goto rollback;
+ } else {
+ printk(KERN_ERR
+ "%s: name change rollback failed: %d.\n",
+ dev->name, ret);
}
}
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 86acdba0a97d..6e79e96cb4f2 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -335,6 +335,7 @@ struct pktgen_dev {
__u32 cur_src_mac_offset;
__be32 cur_saddr;
__be32 cur_daddr;
+ __u16 ip_id;
__u16 cur_udp_dst;
__u16 cur_udp_src;
__u16 cur_queue_map;
@@ -362,6 +363,7 @@ struct pktgen_dev {
* device name (not when the inject is
* started as it used to do.)
*/
+ char odevname[32];
struct flow_state *flows;
unsigned cflows; /* Concurrent flows (config) */
unsigned lflow; /* Flow length (config) */
@@ -425,7 +427,7 @@ static const char version[] =
static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
static int pktgen_add_device(struct pktgen_thread *t, const char *ifname);
static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
- const char *ifname);
+ const char *ifname, bool exact);
static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
static void pktgen_run_all_threads(void);
static void pktgen_reset_all_threads(void);
@@ -527,7 +529,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
seq_printf(seq,
" frags: %d delay: %llu clone_skb: %d ifname: %s\n",
pkt_dev->nfrags, (unsigned long long) pkt_dev->delay,
- pkt_dev->clone_skb, pkt_dev->odev->name);
+ pkt_dev->clone_skb, pkt_dev->odevname);
seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows,
pkt_dev->lflow);
@@ -1687,13 +1689,13 @@ static int pktgen_thread_show(struct seq_file *seq, void *v)
if_lock(t);
list_for_each_entry(pkt_dev, &t->if_list, list)
if (pkt_dev->running)
- seq_printf(seq, "%s ", pkt_dev->odev->name);
+ seq_printf(seq, "%s ", pkt_dev->odevname);
seq_printf(seq, "\nStopped: ");
list_for_each_entry(pkt_dev, &t->if_list, list)
if (!pkt_dev->running)
- seq_printf(seq, "%s ", pkt_dev->odev->name);
+ seq_printf(seq, "%s ", pkt_dev->odevname);
if (t->result[0])
seq_printf(seq, "\nResult: %s\n", t->result);
@@ -1816,9 +1818,10 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
{
struct pktgen_thread *t;
struct pktgen_dev *pkt_dev = NULL;
+ bool exact = (remove == FIND);
list_for_each_entry(t, &pktgen_threads, th_list) {
- pkt_dev = pktgen_find_dev(t, ifname);
+ pkt_dev = pktgen_find_dev(t, ifname, exact);
if (pkt_dev) {
if (remove) {
if_lock(t);
@@ -1993,7 +1996,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
"queue_map_min (zero-based) (%d) exceeds valid range "
"[0 - %d] for (%d) queues on %s, resetting\n",
pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq,
- pkt_dev->odev->name);
+ pkt_dev->odevname);
pkt_dev->queue_map_min = ntxq - 1;
}
if (pkt_dev->queue_map_max >= ntxq) {
@@ -2001,7 +2004,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
"queue_map_max (zero-based) (%d) exceeds valid range "
"[0 - %d] for (%d) queues on %s, resetting\n",
pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq,
- pkt_dev->odev->name);
+ pkt_dev->odevname);
pkt_dev->queue_map_max = ntxq - 1;
}
@@ -2630,6 +2633,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
iph->protocol = IPPROTO_UDP; /* UDP */
iph->saddr = pkt_dev->cur_saddr;
iph->daddr = pkt_dev->cur_daddr;
+ iph->id = htons(pkt_dev->ip_id);
+ pkt_dev->ip_id++;
iph->frag_off = 0;
iplen = 20 + 8 + datalen;
iph->tot_len = htons(iplen);
@@ -2641,24 +2646,26 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
skb->dev = odev;
skb->pkt_type = PACKET_HOST;
- if (pkt_dev->nfrags <= 0)
+ if (pkt_dev->nfrags <= 0) {
pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
- else {
+ memset(pgh + 1, 0, datalen - sizeof(struct pktgen_hdr));
+ } else {
int frags = pkt_dev->nfrags;
- int i;
+ int i, len;
pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8);
if (frags > MAX_SKB_FRAGS)
frags = MAX_SKB_FRAGS;
if (datalen > frags * PAGE_SIZE) {
- skb_put(skb, datalen - frags * PAGE_SIZE);
+ len = datalen - frags * PAGE_SIZE;
+ memset(skb_put(skb, len), 0, len);
datalen = frags * PAGE_SIZE;
}
i = 0;
while (datalen > 0) {
- struct page *page = alloc_pages(GFP_KERNEL, 0);
+ struct page *page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
skb_shinfo(skb)->frags[i].page = page;
skb_shinfo(skb)->frags[i].page_offset = 0;
skb_shinfo(skb)->frags[i].size =
@@ -3257,7 +3264,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev)
if (!pkt_dev->running) {
printk(KERN_WARNING "pktgen: interface: %s is already "
- "stopped\n", pkt_dev->odev->name);
+ "stopped\n", pkt_dev->odevname);
return -EINVAL;
}
@@ -3459,7 +3466,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
default: /* Drivers are not supposed to return other values! */
if (net_ratelimit())
pr_info("pktgen: %s xmit error: %d\n",
- odev->name, ret);
+ pkt_dev->odevname, ret);
pkt_dev->errors++;
/* fallthru */
case NETDEV_TX_LOCKED:
@@ -3561,13 +3568,18 @@ static int pktgen_thread_worker(void *arg)
}
static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
- const char *ifname)
+ const char *ifname, bool exact)
{
struct pktgen_dev *p, *pkt_dev = NULL;
- if_lock(t);
+ size_t len = strlen(ifname);
+ if_lock(t);
list_for_each_entry(p, &t->if_list, list)
- if (strncmp(p->odev->name, ifname, IFNAMSIZ) == 0) {
+ if (strncmp(p->odevname, ifname, len) == 0) {
+ if (p->odevname[len]) {
+ if (exact || p->odevname[len] != '@')
+ continue;
+ }
pkt_dev = p;
break;
}
@@ -3623,6 +3635,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
if (!pkt_dev)
return -ENOMEM;
+ strcpy(pkt_dev->odevname, ifname);
pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state));
if (pkt_dev->flows == NULL) {
kfree(pkt_dev);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 80a96166df39..ec85681a7dd8 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2701,7 +2701,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
NAPI_GRO_CB(skb)->free = 1;
goto done;
- }
+ } else if (skb_gro_len(p) != pinfo->gso_size)
+ return -E2BIG;
headroom = skb_headroom(p);
nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p));
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 7db1de0497c6..887c03c4e3c6 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -10,7 +10,9 @@
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/netdevice.h>
+#include <linux/ratelimit.h>
#include <linux/init.h>
+
#include <net/ip.h>
#include <net/sock.h>
diff --git a/net/core/utils.c b/net/core/utils.c
index 83221aee7084..838250241d26 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -24,6 +24,8 @@
#include <linux/types.h>
#include <linux/percpu.h>
#include <linux/init.h>
+#include <linux/ratelimit.h>
+
#include <net/sock.h>
#include <asm/byteorder.h>
diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c
index 26b0ab1e9f56..2036568beea9 100644
--- a/net/decnet/sysctl_net_decnet.c
+++ b/net/decnet/sysctl_net_decnet.c
@@ -263,11 +263,10 @@ static int dn_def_dev_strategy(ctl_table *table,
return -ENODEV;
rv = -ENODEV;
- if (dev->dn_ptr != NULL) {
+ if (dev->dn_ptr != NULL)
rv = dn_dev_set_default(dev, 1);
- if (rv)
- dev_put(dev);
- }
+ if (rv)
+ dev_put(dev);
}
return rv;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index e2f950592566..aa00398be80e 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -229,14 +229,17 @@ unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
*/
int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
- struct net_device *dev, __be32 *spec_dst, u32 *itag)
+ struct net_device *dev, __be32 *spec_dst,
+ u32 *itag, u32 mark)
{
struct in_device *in_dev;
struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = src,
.saddr = dst,
.tos = tos } },
+ .mark = mark,
.iif = oif };
+
struct fib_result res;
int no_addr, rpf;
int ret;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 4351ca2cf0b8..537731b3bcb3 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -446,6 +446,28 @@ extern int sysctl_tcp_synack_retries;
EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add);
+/* Decide when to expire the request and when to resend SYN-ACK */
+static inline void syn_ack_recalc(struct request_sock *req, const int thresh,
+ const int max_retries,
+ const u8 rskq_defer_accept,
+ int *expire, int *resend)
+{
+ if (!rskq_defer_accept) {
+ *expire = req->retrans >= thresh;
+ *resend = 1;
+ return;
+ }
+ *expire = req->retrans >= thresh &&
+ (!inet_rsk(req)->acked || req->retrans >= max_retries);
+ /*
+ * Do not resend while waiting for data after ACK,
+ * start to resend on end of deferring period to give
+ * last chance for data or ACK to create established socket.
+ */
+ *resend = !inet_rsk(req)->acked ||
+ req->retrans >= rskq_defer_accept - 1;
+}
+
void inet_csk_reqsk_queue_prune(struct sock *parent,
const unsigned long interval,
const unsigned long timeout,
@@ -501,9 +523,15 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
reqp=&lopt->syn_table[i];
while ((req = *reqp) != NULL) {
if (time_after_eq(now, req->expires)) {
- if ((req->retrans < thresh ||
- (inet_rsk(req)->acked && req->retrans < max_retries))
- && !req->rsk_ops->rtx_syn_ack(parent, req)) {
+ int expire = 0, resend = 0;
+
+ syn_ack_recalc(req, thresh, max_retries,
+ queue->rskq_defer_accept,
+ &expire, &resend);
+ if (!expire &&
+ (!resend ||
+ !req->rsk_ops->rtx_syn_ack(parent, req) ||
+ inet_rsk(req)->acked)) {
unsigned long timeo;
if (req->retrans++ == 0)
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 575f9bd51ccd..d3fe10be7219 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -563,7 +563,7 @@ out_oversize:
printk(KERN_INFO "Oversized IP packet from %pI4.\n",
&qp->saddr);
out_fail:
- IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS);
+ IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
return err;
}
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 41ada9904d31..143333852624 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1464,7 +1464,7 @@ static void ipgre_tap_setup(struct net_device *dev)
ether_setup(dev);
- dev->netdev_ops = &ipgre_netdev_ops;
+ dev->netdev_ops = &ipgre_tap_netdev_ops;
dev->destructor = free_netdev;
dev->iflink = 0;
@@ -1525,25 +1525,29 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
if (t->dev != dev)
return -EEXIST;
} else {
- unsigned nflags = 0;
-
t = nt;
- if (ipv4_is_multicast(p.iph.daddr))
- nflags = IFF_BROADCAST;
- else if (p.iph.daddr)
- nflags = IFF_POINTOPOINT;
+ if (dev->type != ARPHRD_ETHER) {
+ unsigned nflags = 0;
- if ((dev->flags ^ nflags) &
- (IFF_POINTOPOINT | IFF_BROADCAST))
- return -EINVAL;
+ if (ipv4_is_multicast(p.iph.daddr))
+ nflags = IFF_BROADCAST;
+ else if (p.iph.daddr)
+ nflags = IFF_POINTOPOINT;
+
+ if ((dev->flags ^ nflags) &
+ (IFF_POINTOPOINT | IFF_BROADCAST))
+ return -EINVAL;
+ }
ipgre_tunnel_unlink(ign, t);
t->parms.iph.saddr = p.iph.saddr;
t->parms.iph.daddr = p.iph.daddr;
t->parms.i_key = p.i_key;
- memcpy(dev->dev_addr, &p.iph.saddr, 4);
- memcpy(dev->broadcast, &p.iph.daddr, 4);
+ if (dev->type != ARPHRD_ETHER) {
+ memcpy(dev->dev_addr, &p.iph.saddr, 4);
+ memcpy(dev->broadcast, &p.iph.daddr, 4);
+ }
ipgre_tunnel_link(ign, t);
netdev_state_change(dev);
}
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 0c0b6e363a20..e982b5c1ee17 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -634,17 +634,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
break;
}
dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr);
- if (dev) {
+ if (dev)
mreq.imr_ifindex = dev->ifindex;
- dev_put(dev);
- }
} else
- dev = __dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
+ dev = dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
err = -EADDRNOTAVAIL;
if (!dev)
break;
+ dev_put(dev);
err = -EINVAL;
if (sk->sk_bound_dev_if &&
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 08ccd344de7a..ae40ed1ba560 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -438,25 +438,27 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
goto tx_error;
}
- if (tiph->frag_off)
+ df |= old_iph->frag_off & htons(IP_DF);
+
+ if (df) {
mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
- else
- mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
- if (mtu < 68) {
- stats->collisions++;
- ip_rt_put(rt);
- goto tx_error;
- }
- if (skb_dst(skb))
- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
+ if (mtu < 68) {
+ stats->collisions++;
+ ip_rt_put(rt);
+ goto tx_error;
+ }
- df |= (old_iph->frag_off&htons(IP_DF));
+ if (skb_dst(skb))
+ skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
- if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
- ip_rt_put(rt);
- goto tx_error;
+ if ((old_iph->frag_off & htons(IP_DF)) &&
+ mtu < ntohs(old_iph->tot_len)) {
+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+ htonl(mtu));
+ ip_rt_put(rt);
+ goto tx_error;
+ }
}
if (tunnel->err_count > 0) {
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 630a56df7b47..99508d66a642 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -483,8 +483,10 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
return -EINVAL;
}
- if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
+ if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) {
+ dev_put(dev);
return -EADDRNOTAVAIL;
+ }
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
ip_rt_multicast_event(in_dev);
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 68afc6ecd343..fe1a64479dd0 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -750,6 +750,8 @@ static int __init nf_nat_init(void)
BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
nfnetlink_parse_nat_setup);
+ BUG_ON(nf_ct_nat_offset != NULL);
+ rcu_assign_pointer(nf_ct_nat_offset, nf_nat_get_offset);
return 0;
cleanup_extend:
@@ -764,6 +766,7 @@ static void __exit nf_nat_cleanup(void)
nf_ct_extend_unregister(&nat_extend);
rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
+ rcu_assign_pointer(nf_ct_nat_offset, NULL);
synchronize_net();
}
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 09172a65d9b6..f9520fa3aba9 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -73,6 +73,28 @@ adjust_tcp_sequence(u32 seq,
DUMP_OFFSET(this_way);
}
+/* Get the offset value, for conntrack */
+s16 nf_nat_get_offset(const struct nf_conn *ct,
+ enum ip_conntrack_dir dir,
+ u32 seq)
+{
+ struct nf_conn_nat *nat = nfct_nat(ct);
+ struct nf_nat_seq *this_way;
+ s16 offset;
+
+ if (!nat)
+ return 0;
+
+ this_way = &nat->seq[dir];
+ spin_lock_bh(&nf_nat_seqofs_lock);
+ offset = after(seq, this_way->correction_pos)
+ ? this_way->offset_after : this_way->offset_before;
+ spin_unlock_bh(&nf_nat_seqofs_lock);
+
+ return offset;
+}
+EXPORT_SYMBOL_GPL(nf_nat_get_offset);
+
/* Frobs data inside this packet, which is linear. */
static void mangle_contents(struct sk_buff *skb,
unsigned int dataoff,
@@ -189,11 +211,6 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
adjust_tcp_sequence(ntohl(tcph->seq),
(int)rep_len - (int)match_len,
ct, ctinfo);
- /* Tell TCP window tracking about seq change */
- nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
- ct, CTINFO2DIR(ctinfo),
- (int)rep_len - (int)match_len);
-
nf_conntrack_event_cache(IPCT_NATSEQADJ, ct);
}
return 1;
@@ -415,12 +432,7 @@ nf_nat_seq_adjust(struct sk_buff *skb,
tcph->seq = newseq;
tcph->ack_seq = newack;
- if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo))
- return 0;
-
- nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir, seqoff);
-
- return 1;
+ return nf_nat_sack_adjust(skb, tcph, ct, ctinfo);
}
/* Setup NAT on this expected conntrack so it follows master. */
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 757c9171e7c2..ab996f9c0fe0 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -352,13 +352,24 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
skb->ip_summed = CHECKSUM_NONE;
skb->transport_header = skb->network_header;
- err = memcpy_fromiovecend((void *)iph, from, 0, length);
- if (err)
- goto error_fault;
+ err = -EFAULT;
+ if (memcpy_fromiovecend((void *)iph, from, 0, length))
+ goto error_free;
- /* We don't modify invalid header */
iphlen = iph->ihl * 4;
- if (iphlen >= sizeof(*iph) && iphlen <= length) {
+
+ /*
+ * We don't want to modify the ip header, but we do need to
+ * be sure that it won't cause problems later along the network
+ * stack. Specifically we want to make sure that iph->ihl is a
+ * sane value. If ihl points beyond the length of the buffer passed
+ * in, reject the frame as invalid
+ */
+ err = -EINVAL;
+ if (iphlen > length)
+ goto error_free;
+
+ if (iphlen >= sizeof(*iph)) {
if (!iph->saddr)
iph->saddr = rt->rt_src;
iph->check = 0;
@@ -381,8 +392,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
out:
return 0;
-error_fault:
- err = -EFAULT;
+error_free:
kfree_skb(skb);
error:
IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index bb4199252026..5b1050a5d874 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1854,7 +1854,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
goto e_inval;
spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
} else if (fib_validate_source(saddr, 0, tos, 0,
- dev, &spec_dst, &itag) < 0)
+ dev, &spec_dst, &itag, 0) < 0)
goto e_inval;
rth = dst_alloc(&ipv4_dst_ops);
@@ -1967,7 +1967,7 @@ static int __mkroute_input(struct sk_buff *skb,
err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res),
- in_dev->dev, &spec_dst, &itag);
+ in_dev->dev, &spec_dst, &itag, skb->mark);
if (err < 0) {
ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
saddr);
@@ -2141,7 +2141,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
int result;
result = fib_validate_source(saddr, daddr, tos,
net->loopback_dev->ifindex,
- dev, &spec_dst, &itag);
+ dev, &spec_dst, &itag, skb->mark);
if (result < 0)
goto martian_source;
if (result)
@@ -2170,7 +2170,7 @@ brd_input:
spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
else {
err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst,
- &itag);
+ &itag, skb->mark);
if (err < 0)
goto martian_source;
if (err)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 64d0af675823..f1813bc71088 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -326,6 +326,43 @@ void tcp_enter_memory_pressure(struct sock *sk)
EXPORT_SYMBOL(tcp_enter_memory_pressure);
+/* Convert seconds to retransmits based on initial and max timeout */
+static u8 secs_to_retrans(int seconds, int timeout, int rto_max)
+{
+ u8 res = 0;
+
+ if (seconds > 0) {
+ int period = timeout;
+
+ res = 1;
+ while (seconds > period && res < 255) {
+ res++;
+ timeout <<= 1;
+ if (timeout > rto_max)
+ timeout = rto_max;
+ period += timeout;
+ }
+ }
+ return res;
+}
+
+/* Convert retransmits to seconds based on initial and max timeout */
+static int retrans_to_secs(u8 retrans, int timeout, int rto_max)
+{
+ int period = 0;
+
+ if (retrans > 0) {
+ period = timeout;
+ while (--retrans) {
+ timeout <<= 1;
+ if (timeout > rto_max)
+ timeout = rto_max;
+ period += timeout;
+ }
+ }
+ return period;
+}
+
/*
* Wait for a TCP event.
*
@@ -1146,7 +1183,9 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
#if TCP_DEBUG
struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
- WARN_ON(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq));
+ WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq),
+ KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n",
+ tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt);
#endif
if (inet_csk_ack_scheduled(sk)) {
@@ -1393,11 +1432,13 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
/* Now that we have two receive queues this
* shouldn't happen.
*/
- if (before(*seq, TCP_SKB_CB(skb)->seq)) {
- printk(KERN_INFO "recvmsg bug: copied %X "
- "seq %X\n", *seq, TCP_SKB_CB(skb)->seq);
+ if (WARN(before(*seq, TCP_SKB_CB(skb)->seq),
+ KERN_INFO "recvmsg bug: copied %X "
+ "seq %X rcvnxt %X fl %X\n", *seq,
+ TCP_SKB_CB(skb)->seq, tp->rcv_nxt,
+ flags))
break;
- }
+
offset = *seq - TCP_SKB_CB(skb)->seq;
if (tcp_hdr(skb)->syn)
offset--;
@@ -1405,7 +1446,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
goto found_ok_skb;
if (tcp_hdr(skb)->fin)
goto found_fin_ok;
- WARN_ON(!(flags & MSG_PEEK));
+ WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: "
+ "copied %X seq %X rcvnxt %X fl %X\n",
+ *seq, TCP_SKB_CB(skb)->seq,
+ tp->rcv_nxt, flags);
}
/* Well, if we have backlog, try to process it now yet. */
@@ -2163,16 +2207,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
break;
case TCP_DEFER_ACCEPT:
- icsk->icsk_accept_queue.rskq_defer_accept = 0;
- if (val > 0) {
- /* Translate value in seconds to number of
- * retransmits */
- while (icsk->icsk_accept_queue.rskq_defer_accept < 32 &&
- val > ((TCP_TIMEOUT_INIT / HZ) <<
- icsk->icsk_accept_queue.rskq_defer_accept))
- icsk->icsk_accept_queue.rskq_defer_accept++;
- icsk->icsk_accept_queue.rskq_defer_accept++;
- }
+ /* Translate value in seconds to number of retransmits */
+ icsk->icsk_accept_queue.rskq_defer_accept =
+ secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
+ TCP_RTO_MAX / HZ);
break;
case TCP_WINDOW_CLAMP:
@@ -2353,8 +2391,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
val = (val ? : sysctl_tcp_fin_timeout) / HZ;
break;
case TCP_DEFER_ACCEPT:
- val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 :
- ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1));
+ val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept,
+ TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ);
break;
case TCP_WINDOW_CLAMP:
val = tp->window_clamp;
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 624c3c9b3c2b..4c03598ed924 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -641,8 +641,8 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
if (!(flg & TCP_FLAG_ACK))
return NULL;
- /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
- if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
+ /* While TCP_DEFER_ACCEPT is active, drop bare ACK. */
+ if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
inet_rsk(req)->acked = 1;
return NULL;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 6ec6a8a4a224..0fa9f70e4b19 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -841,6 +841,42 @@ out:
return ret;
}
+
+/**
+ * first_packet_length - return length of first packet in receive queue
+ * @sk: socket
+ *
+ * Drops all bad checksum frames, until a valid one is found.
+ * Returns the length of found skb, or 0 if none is found.
+ */
+static unsigned int first_packet_length(struct sock *sk)
+{
+ struct sk_buff_head list_kill, *rcvq = &sk->sk_receive_queue;
+ struct sk_buff *skb;
+ unsigned int res;
+
+ __skb_queue_head_init(&list_kill);
+
+ spin_lock_bh(&rcvq->lock);
+ while ((skb = skb_peek(rcvq)) != NULL &&
+ udp_lib_checksum_complete(skb)) {
+ UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS,
+ IS_UDPLITE(sk));
+ __skb_unlink(skb, rcvq);
+ __skb_queue_tail(&list_kill, skb);
+ }
+ res = skb ? skb->len : 0;
+ spin_unlock_bh(&rcvq->lock);
+
+ if (!skb_queue_empty(&list_kill)) {
+ lock_sock(sk);
+ __skb_queue_purge(&list_kill);
+ sk_mem_reclaim_partial(sk);
+ release_sock(sk);
+ }
+ return res;
+}
+
/*
* IOCTL requests applicable to the UDP protocol
*/
@@ -857,21 +893,16 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
case SIOCINQ:
{
- struct sk_buff *skb;
- unsigned long amount;
+ unsigned int amount = first_packet_length(sk);
- amount = 0;
- spin_lock_bh(&sk->sk_receive_queue.lock);
- skb = skb_peek(&sk->sk_receive_queue);
- if (skb != NULL) {
+ if (amount)
/*
* We will only return the amount
* of this packet since that is all
* that will be read.
*/
- amount = skb->len - sizeof(struct udphdr);
- }
- spin_unlock_bh(&sk->sk_receive_queue.lock);
+ amount -= sizeof(struct udphdr);
+
return put_user(amount, (int __user *)arg);
}
@@ -968,9 +999,7 @@ try_again:
err = ulen;
out_free:
- lock_sock(sk);
- skb_free_datagram(sk, skb);
- release_sock(sk);
+ skb_free_datagram_locked(sk, skb);
out:
return err;
@@ -1540,29 +1569,11 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
{
unsigned int mask = datagram_poll(file, sock, wait);
struct sock *sk = sock->sk;
- int is_lite = IS_UDPLITE(sk);
/* Check for false positives due to checksum errors */
- if ((mask & POLLRDNORM) &&
- !(file->f_flags & O_NONBLOCK) &&
- !(sk->sk_shutdown & RCV_SHUTDOWN)) {
- struct sk_buff_head *rcvq = &sk->sk_receive_queue;
- struct sk_buff *skb;
-
- spin_lock_bh(&rcvq->lock);
- while ((skb = skb_peek(rcvq)) != NULL &&
- udp_lib_checksum_complete(skb)) {
- UDP_INC_STATS_BH(sock_net(sk),
- UDP_MIB_INERRORS, is_lite);
- __skb_unlink(skb, rcvq);
- kfree_skb(skb);
- }
- spin_unlock_bh(&rcvq->lock);
-
- /* nothing to see, move along */
- if (skb == NULL)
- mask &= ~(POLLIN | POLLRDNORM);
- }
+ if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) &&
+ !(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk))
+ mask &= ~(POLLIN | POLLRDNORM);
return mask;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 14f54eb5a7fc..4f7aaf6996a3 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -496,13 +496,17 @@ done:
goto e_inval;
if (val) {
+ struct net_device *dev;
+
if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val)
goto e_inval;
- if (__dev_get_by_index(net, val) == NULL) {
+ dev = dev_get_by_index(net, val);
+ if (!dev) {
retv = -ENODEV;
break;
}
+ dev_put(dev);
}
np->mcast_oif = val;
retv = 0;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 3a60f12b34ed..cf538ed5ef6a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -288,9 +288,7 @@ try_again:
err = ulen;
out_free:
- lock_sock(sk);
- skb_free_datagram(sk, skb);
- release_sock(sk);
+ skb_free_datagram_locked(sk, skb);
out:
return err;
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index bc064d7933ff..ce8e0e772bab 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -85,10 +85,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
- /* stop HW Rx aggregation. ampdu_action existence
- * already verified in session init so we add the BUG_ON */
- BUG_ON(!local->ops->ampdu_action);
-
rcu_read_lock();
sta = sta_info_get(local, ra);
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index bd765f30dba2..89e238b001de 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -123,13 +123,18 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
ieee80211_tx_skb(sdata, skb, 0);
}
-static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
- enum ieee80211_back_parties initiator)
+int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
+ enum ieee80211_back_parties initiator)
{
struct ieee80211_local *local = sta->local;
int ret;
u8 *state;
+#ifdef CONFIG_MAC80211_HT_DEBUG
+ printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
+ sta->sta.addr, tid);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
+
state = &sta->ampdu_mlme.tid_state_tx[tid];
if (*state == HT_AGG_STATE_OPERATIONAL)
@@ -143,7 +148,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
/* HW shall not deny going back to legacy */
if (WARN_ON(ret)) {
- *state = HT_AGG_STATE_OPERATIONAL;
/*
* We may have pending packets get stuck in this case...
* Not bothering with a workaround for now.
@@ -173,12 +177,14 @@ static void sta_addba_resp_timer_expired(unsigned long data)
/* check if the TID waits for addBA response */
spin_lock_bh(&sta->lock);
- if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
+ if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) !=
+ HT_ADDBA_REQUESTED_MSK) {
spin_unlock_bh(&sta->lock);
*state = HT_AGG_STATE_IDLE;
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "timer expired on tid %d but we are not "
- "expecting addBA response there", tid);
+ "(or no longer) expecting addBA response there",
+ tid);
#endif
return;
}
@@ -523,11 +529,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
goto unlock;
}
-#ifdef CONFIG_MAC80211_HT_DEBUG
- printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
- sta->sta.addr, tid);
-#endif /* CONFIG_MAC80211_HT_DEBUG */
-
ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
unlock:
@@ -543,7 +544,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
struct sta_info *sta;
int ret = 0;
- if (WARN_ON(!local->ops->ampdu_action))
+ if (!local->ops->ampdu_action)
return -EINVAL;
if (tid >= STA_TID_NUM)
@@ -668,24 +669,23 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
spin_lock_bh(&sta->lock);
- if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
- spin_unlock_bh(&sta->lock);
- return;
- }
+ if (!(*state & HT_ADDBA_REQUESTED_MSK))
+ goto out;
if (mgmt->u.action.u.addba_resp.dialog_token !=
sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
- spin_unlock_bh(&sta->lock);
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
- return;
+ goto out;
}
- del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
+ del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
+
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
+
if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
== WLAN_STATUS_SUCCESS) {
u8 curstate = *state;
@@ -699,5 +699,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
} else {
___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
}
+
+ out:
spin_unlock_bh(&sta->lock);
}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 5608f6c68413..7b5131bd6fa1 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -72,6 +72,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
struct ieee80211_sub_if_data *sdata;
int ret;
+ if (netif_running(dev))
+ return -EBUSY;
+
if (!nl80211_type_check(type))
return -EINVAL;
@@ -81,9 +84,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
if (ret)
return ret;
- if (netif_running(sdata->dev))
- return -EBUSY;
-
if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
ieee80211_sdata_set_mesh_id(sdata,
params->mesh_id_len,
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 0891bfb06996..cdc58e61d921 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -141,7 +141,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta,
struct ieee80211_mgmt *mgmt, size_t len)
{
- struct ieee80211_local *local = sdata->local;
u16 tid, params;
u16 initiator;
@@ -153,7 +152,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
if (net_ratelimit())
printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n",
mgmt->sa, initiator ? "initiator" : "recipient", tid,
- mgmt->u.action.u.delba.reason_code);
+ le16_to_cpu(mgmt->u.action.u.delba.reason_code));
#endif /* CONFIG_MAC80211_HT_DEBUG */
if (initiator == WLAN_BACK_INITIATOR)
@@ -161,10 +160,9 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
WLAN_BACK_INITIATOR, 0);
else { /* WLAN_BACK_RECIPIENT */
spin_lock_bh(&sta->lock);
- sta->ampdu_mlme.tid_state_tx[tid] =
- HT_AGG_STATE_OPERATIONAL;
+ if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK)
+ ___ieee80211_stop_tx_ba_session(sta, tid,
+ WLAN_BACK_RECIPIENT);
spin_unlock_bh(&sta->lock);
- ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid,
- WLAN_BACK_RECIPIENT);
}
}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 920ec8792f4b..f1362f32c17d 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -73,6 +73,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt;
u8 *pos;
struct ieee80211_supported_band *sband;
+ struct cfg80211_bss *bss;
u32 bss_change;
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
@@ -177,8 +178,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
mod_timer(&ifibss->timer,
round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
- cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
- mgmt, skb->len, 0, GFP_KERNEL);
+ bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
+ mgmt, skb->len, 0, GFP_KERNEL);
+ cfg80211_put_bss(bss);
cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
}
@@ -538,13 +540,12 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
WLAN_CAPABILITY_PRIVACY,
capability);
+ if (bss) {
#ifdef CONFIG_MAC80211_IBSS_DEBUG
- if (bss)
printk(KERN_DEBUG " sta_find_ibss: selected %pM current "
"%pM\n", bss->cbss.bssid, ifibss->bssid);
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
- if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) {
printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
" based on configured SSID\n",
sdata->dev->name, bss->cbss.bssid);
@@ -552,8 +553,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
ieee80211_sta_join_ibss(sdata, bss);
ieee80211_rx_bss_put(local, bss);
return;
- } else if (bss)
- ieee80211_rx_bss_put(local, bss);
+ }
#ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG " did not try to join ibss\n");
@@ -829,7 +829,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
if (!sdata->u.ibss.ssid_len)
continue;
sdata->u.ibss.last_scan_completed = jiffies;
- ieee80211_sta_find_ibss(sdata);
+ mod_timer(&sdata->u.ibss.timer, 0);
}
mutex_unlock(&local->iflist_mtx);
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 588005c84a6d..10d316e455de 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -662,6 +662,14 @@ struct ieee80211_local {
bool suspended;
/*
+ * Resuming is true while suspended, but when we're reprogramming the
+ * hardware -- at that time it's allowed to use ieee80211_queue_work()
+ * again even though some other parts of the stack are still suspended
+ * and we still drop received frames to avoid waking the stack.
+ */
+ bool resuming;
+
+ /*
* quiescing is true during the suspend process _only_ to
* ease timer cancelling etc.
*/
@@ -1083,6 +1091,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
enum ieee80211_back_parties initiator);
+int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
+ enum ieee80211_back_parties initiator);
/* Spectrum management */
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index e12a786e26b8..29b82e98effa 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -259,7 +259,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
* @hwmp_ie: hwmp information element (PREP or PREQ)
*
* This function updates the path routing information to the originator and the
- * transmitter of a HWMP PREQ or PREP fram.
+ * transmitter of a HWMP PREQ or PREP frame.
*
* Returns: metric to frame originator or 0 if the frame should not be further
* processed
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8d26e9bf8964..dc5049d58c51 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1457,8 +1457,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
if (status_code != WLAN_STATUS_SUCCESS) {
printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
sdata->dev->name, status_code);
- list_del(&wk->list);
- kfree(wk);
+ wk->state = IEEE80211_MGD_STATE_IDLE;
return RX_MGMT_CFG80211_ASSOC;
}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c01588f9d453..7170bf4565a8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2164,11 +2164,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
skb = rx.skb;
- list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ if (rx.sdata && ieee80211_is_data(hdr->frame_control)) {
+ rx.flags |= IEEE80211_RX_RA_MATCH;
+ prepares = prepare_for_handlers(rx.sdata, &rx, hdr);
+ if (prepares)
+ prev = rx.sdata;
+ } else list_for_each_entry_rcu(sdata, &local->interfaces, list) {
if (!netif_running(sdata->dev))
continue;
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
continue;
rx.flags |= IEEE80211_RX_RA_MATCH;
@@ -2447,6 +2453,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
struct ieee80211_supported_band *sband;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ WARN_ON_ONCE(softirq_count() == 0);
+
if (WARN_ON(status->band < 0 ||
status->band >= IEEE80211_NUM_BANDS))
goto drop;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index eec001491e66..594f2318c3d8 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -361,6 +361,7 @@ int sta_info_insert(struct sta_info *sta)
u.ap);
drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta);
+ sdata = sta->sdata;
}
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -496,6 +497,7 @@ static void __sta_info_unlink(struct sta_info **sta)
drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
&(*sta)->sta);
+ sdata = (*sta)->sdata;
}
if (ieee80211_vif_is_mesh(&sdata->vif)) {
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index fd4028296613..eaa4118de988 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1445,7 +1445,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
continue;
if (compare_ether_addr(tmp_sdata->dev->dev_addr,
- hdr->addr2)) {
+ hdr->addr2) == 0) {
dev_hold(tmp_sdata->dev);
dev_put(sdata->dev);
sdata = tmp_sdata;
@@ -1704,7 +1704,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
if (!is_multicast_ether_addr(hdr.addr1)) {
rcu_read_lock();
sta = sta_info_get(local, hdr.addr1);
- if (sta)
+ /* XXX: in the future, use sdata to look up the sta */
+ if (sta && sta->sdata == sdata)
sta_flags = get_sta_flags(sta);
rcu_read_unlock();
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index dd6564321369..e6c08da8da26 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -339,7 +339,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (WARN_ON(!info->control.vif)) {
- kfree(skb);
+ kfree_skb(skb);
return;
}
@@ -367,7 +367,7 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (WARN_ON(!info->control.vif)) {
- kfree(skb);
+ kfree_skb(skb);
continue;
}
@@ -520,9 +520,9 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
*/
static bool ieee80211_can_queue_work(struct ieee80211_local *local)
{
- if (WARN(local->suspended, "queueing ieee80211 work while "
- "going to suspend\n"))
- return false;
+ if (WARN(local->suspended && !local->resuming,
+ "queueing ieee80211 work while going to suspend\n"))
+ return false;
return true;
}
@@ -1025,13 +1025,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
struct sta_info *sta;
unsigned long flags;
int res;
- bool from_suspend = local->suspended;
- /*
- * We're going to start the hardware, at that point
- * we are no longer suspended and can RX frames.
- */
- local->suspended = false;
+ if (local->suspended)
+ local->resuming = true;
/* restart hardware */
if (local->open_count) {
@@ -1129,11 +1125,14 @@ int ieee80211_reconfig(struct ieee80211_local *local)
* If this is for hw restart things are still running.
* We may want to change that later, however.
*/
- if (!from_suspend)
+ if (!local->suspended)
return 0;
#ifdef CONFIG_PM
+ /* first set suspended false, then resuming */
local->suspended = false;
+ mb();
+ local->resuming = false;
list_for_each_entry(sdata, &local->interfaces, list) {
switch(sdata->vif.type) {
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ca6e68dcd8a8..b9168c1864ca 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1351,6 +1351,11 @@ err_stat:
return ret;
}
+s16 (*nf_ct_nat_offset)(const struct nf_conn *ct,
+ enum ip_conntrack_dir dir,
+ u32 seq);
+EXPORT_SYMBOL_GPL(nf_ct_nat_offset);
+
int nf_conntrack_init(struct net *net)
{
int ret;
@@ -1368,6 +1373,9 @@ int nf_conntrack_init(struct net *net)
/* For use by REJECT target */
rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
+
+ /* Howto get NAT offsets */
+ rcu_assign_pointer(nf_ct_nat_offset, NULL);
}
return 0;
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 97a82ba75376..ba2b76937283 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -492,6 +492,21 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
}
}
+#ifdef CONFIG_NF_NAT_NEEDED
+static inline s16 nat_offset(const struct nf_conn *ct,
+ enum ip_conntrack_dir dir,
+ u32 seq)
+{
+ typeof(nf_ct_nat_offset) get_offset = rcu_dereference(nf_ct_nat_offset);
+
+ return get_offset != NULL ? get_offset(ct, dir, seq) : 0;
+}
+#define NAT_OFFSET(pf, ct, dir, seq) \
+ (pf == NFPROTO_IPV4 ? nat_offset(ct, dir, seq) : 0)
+#else
+#define NAT_OFFSET(pf, ct, dir, seq) 0
+#endif
+
static bool tcp_in_window(const struct nf_conn *ct,
struct ip_ct_tcp *state,
enum ip_conntrack_dir dir,
@@ -506,6 +521,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
struct ip_ct_tcp_state *receiver = &state->seen[!dir];
const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
__u32 seq, ack, sack, end, win, swin;
+ s16 receiver_offset;
bool res;
/*
@@ -519,11 +535,16 @@ static bool tcp_in_window(const struct nf_conn *ct,
if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
tcp_sack(skb, dataoff, tcph, &sack);
+ /* Take into account NAT sequence number mangling */
+ receiver_offset = NAT_OFFSET(pf, ct, !dir, ack - 1);
+ ack -= receiver_offset;
+ sack -= receiver_offset;
+
pr_debug("tcp_in_window: START\n");
pr_debug("tcp_in_window: ");
nf_ct_dump_tuple(tuple);
- pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n",
- seq, ack, sack, win, end);
+ pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n",
+ seq, ack, receiver_offset, sack, receiver_offset, win, end);
pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
sender->td_end, sender->td_maxend, sender->td_maxwin,
@@ -613,8 +634,8 @@ static bool tcp_in_window(const struct nf_conn *ct,
pr_debug("tcp_in_window: ");
nf_ct_dump_tuple(tuple);
- pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n",
- seq, ack, sack, win, end);
+ pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n",
+ seq, ack, receiver_offset, sack, receiver_offset, win, end);
pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
sender->td_end, sender->td_maxend, sender->td_maxwin,
@@ -700,7 +721,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
before(seq, sender->td_maxend + 1) ?
after(end, sender->td_end - receiver->td_maxwin - 1) ?
before(sack, receiver->td_end + 1) ?
- after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG"
+ after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG"
: "ACK is under the lower bound (possible overly delayed ACK)"
: "ACK is over the upper bound (ACKed data not seen yet)"
: "SEQ is under the lower bound (already ACKed data retransmitted)"
@@ -715,39 +736,6 @@ static bool tcp_in_window(const struct nf_conn *ct,
return res;
}
-#ifdef CONFIG_NF_NAT_NEEDED
-/* Update sender->td_end after NAT successfully mangled the packet */
-/* Caller must linearize skb at tcp header. */
-void nf_conntrack_tcp_update(const struct sk_buff *skb,
- unsigned int dataoff,
- struct nf_conn *ct, int dir,
- s16 offset)
-{
- const struct tcphdr *tcph = (const void *)skb->data + dataoff;
- const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir];
- const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[!dir];
- __u32 end;
-
- end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
-
- spin_lock_bh(&ct->lock);
- /*
- * We have to worry for the ack in the reply packet only...
- */
- if (ct->proto.tcp.seen[dir].td_end + offset == end)
- ct->proto.tcp.seen[dir].td_end = end;
- ct->proto.tcp.last_end = end;
- spin_unlock_bh(&ct->lock);
- pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
- "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
- sender->td_end, sender->td_maxend, sender->td_maxwin,
- sender->td_scale,
- receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
- receiver->td_scale);
-}
-EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
-#endif
-
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index c93494fef8ef..d65d3481919c 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -128,9 +128,8 @@ EXPORT_SYMBOL(nf_log_packet);
#ifdef CONFIG_PROC_FS
static void *seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(RCU)
{
- rcu_read_lock();
+ mutex_lock(&nf_log_mutex);
if (*pos >= ARRAY_SIZE(nf_loggers))
return NULL;
@@ -149,9 +148,8 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void seq_stop(struct seq_file *s, void *v)
- __releases(RCU)
{
- rcu_read_unlock();
+ mutex_unlock(&nf_log_mutex);
}
static int seq_show(struct seq_file *s, void *v)
@@ -161,7 +159,7 @@ static int seq_show(struct seq_file *s, void *v)
struct nf_logger *t;
int ret;
- logger = rcu_dereference(nf_loggers[*pos]);
+ logger = nf_loggers[*pos];
if (!logger)
ret = seq_printf(s, "%2lld NONE (", *pos);
@@ -171,22 +169,16 @@ static int seq_show(struct seq_file *s, void *v)
if (ret < 0)
return ret;
- mutex_lock(&nf_log_mutex);
list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) {
ret = seq_printf(s, "%s", t->name);
- if (ret < 0) {
- mutex_unlock(&nf_log_mutex);
+ if (ret < 0)
return ret;
- }
if (&t->list[*pos] != nf_loggers_l[*pos].prev) {
ret = seq_printf(s, ",");
- if (ret < 0) {
- mutex_unlock(&nf_log_mutex);
+ if (ret < 0)
return ret;
- }
}
}
- mutex_unlock(&nf_log_mutex);
return seq_printf(s, ")\n");
}
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 680980954395..38f03f75a636 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -103,7 +103,7 @@ static int count_them(struct xt_connlimit_data *data,
const struct nf_conntrack_tuple *tuple,
const union nf_inet_addr *addr,
const union nf_inet_addr *mask,
- const struct xt_match *match)
+ u_int8_t family)
{
const struct nf_conntrack_tuple_hash *found;
struct xt_connlimit_conn *conn;
@@ -113,8 +113,7 @@ static int count_them(struct xt_connlimit_data *data,
bool addit = true;
int matches = 0;
-
- if (match->family == NFPROTO_IPV6)
+ if (family == NFPROTO_IPV6)
hash = &data->iphash[connlimit_iphash6(addr, mask)];
else
hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)];
@@ -157,8 +156,7 @@ static int count_them(struct xt_connlimit_data *data,
continue;
}
- if (same_source_net(addr, mask, &conn->tuple.src.u3,
- match->family))
+ if (same_source_net(addr, mask, &conn->tuple.src.u3, family))
/* same source network -> be counted! */
++matches;
nf_ct_put(found_ct);
@@ -207,7 +205,7 @@ connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
spin_lock_bh(&info->data->lock);
connections = count_them(info->data, tuple_ptr, &addr,
- &info->mask, par->match);
+ &info->mask, par->family);
spin_unlock_bh(&info->data->lock);
if (connections < 0) {
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index 2e8089ecd0af..2773be6a71dd 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -112,7 +112,7 @@ static bool limit_mt_check(const struct xt_mtchk_param *par)
priv = kmalloc(sizeof(*priv), GFP_KERNEL);
if (priv == NULL)
- return -ENOMEM;
+ return false;
/* For SMP, we only want to use one set of state. */
r->master = priv;
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c
index 63e190504656..4d1a41bbd5d7 100644
--- a/net/netfilter/xt_osf.c
+++ b/net/netfilter/xt_osf.c
@@ -118,7 +118,7 @@ static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb,
{
struct xt_osf_user_finger *f;
struct xt_osf_finger *sf;
- int err = ENOENT;
+ int err = -ENOENT;
if (!osf_attrs[OSF_ATTR_FINGER])
return -EINVAL;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index d7ecca0a0c07..f2d116a5cb35 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -982,10 +982,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
goto out_put;
size_max = po->tx_ring.frame_size
- - sizeof(struct skb_shared_info)
- - po->tp_hdrlen
- - LL_ALLOCATED_SPACE(dev)
- - sizeof(struct sockaddr_ll);
+ - (po->tp_hdrlen - sizeof(struct sockaddr_ll));
if (size_max > dev->mtu + reserve)
size_max = dev->mtu + reserve;
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index ba2efb960c60..a001f7c1f711 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -1189,6 +1189,7 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,
#endif
static const struct file_operations rfkill_fops = {
+ .owner = THIS_MODULE,
.open = rfkill_fop_open,
.read = rfkill_fop_read,
.write = rfkill_fop_write,
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 9478d9b3d977..f3e21989b88c 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -578,18 +578,18 @@ static int rose_clear_routes(void)
/*
* Check that the device given is a valid AX.25 interface that is "up".
+ * called whith RTNL
*/
-static struct net_device *rose_ax25_dev_get(char *devname)
+static struct net_device *rose_ax25_dev_find(char *devname)
{
struct net_device *dev;
- if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
+ if ((dev = __dev_get_by_name(&init_net, devname)) == NULL)
return NULL;
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
return dev;
- dev_put(dev);
return NULL;
}
@@ -720,27 +720,23 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg)
case SIOCADDRT:
if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
return -EFAULT;
- if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL)
+ if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
return -EINVAL;
- if (rose_dev_exists(&rose_route.address)) { /* Can't add routes to ourself */
- dev_put(dev);
+ if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */
return -EINVAL;
- }
if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
return -EINVAL;
if (rose_route.ndigis > AX25_MAX_DIGIS)
return -EINVAL;
err = rose_add_node(&rose_route, dev);
- dev_put(dev);
return err;
case SIOCDELRT:
if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
return -EFAULT;
- if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL)
+ if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
return -EINVAL;
err = rose_del_node(&rose_route, dev);
- dev_put(dev);
return err;
case SIOCRSCLRRT:
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 96c0ed115e2a..6b0359a500e6 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -34,7 +34,7 @@ static struct tcf_hashinfo pedit_hash_info = {
};
static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = {
- [TCA_PEDIT_PARMS] = { .len = sizeof(struct tcf_pedit) },
+ [TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) },
};
static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est,
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 6a536949cdc0..7cf6c0fbc7a6 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -350,7 +350,7 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp,
tcm = NLMSG_DATA(nlh);
tcm->tcm_family = AF_UNSPEC;
tcm->tcm__pad1 = 0;
- tcm->tcm__pad1 = 0;
+ tcm->tcm__pad2 = 0;
tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex;
tcm->tcm_parent = tp->classid;
tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 8450960df24f..7eed77a39d0d 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1485,15 +1485,13 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len)
* local endpoint and the remote peer.
*/
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
- gfp_t gfp)
+ sctp_scope_t scope, gfp_t gfp)
{
- sctp_scope_t scope;
int flags;
/* Use scoping rules to determine the subset of addresses from
* the endpoint.
*/
- scope = sctp_scope(&asoc->peer.active_path->ipaddr);
flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0;
if (asoc->peer.ipv4_address)
flags |= SCTP_ADDR4_PEERSUPP;
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index c9f20e28521b..23e5e97aa617 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -423,16 +423,6 @@ void sctp_retransmit_mark(struct sctp_outq *q,
if ((reason == SCTP_RTXR_FAST_RTX &&
(chunk->fast_retransmit == SCTP_NEED_FRTX)) ||
(reason != SCTP_RTXR_FAST_RTX && !chunk->tsn_gap_acked)) {
- /* If this chunk was sent less then 1 rto ago, do not
- * retransmit this chunk, but give the peer time
- * to acknowlege it. Do this only when
- * retransmitting due to T3 timeout.
- */
- if (reason == SCTP_RTXR_T3_RTX &&
- time_before(jiffies, chunk->sent_at +
- transport->last_rto))
- continue;
-
/* RFC 2960 6.2.1 Processing a Received SACK
*
* C) Any time a DATA chunk is marked for
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 8674d4919556..efa516b47e81 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -480,7 +480,6 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
* that indicates that we have an outstanding HB.
*/
if (!is_hb || transport->hb_sent) {
- transport->last_rto = transport->rto;
transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
}
}
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index c8fae1983dd1..d4df45022ffa 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -384,6 +384,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
if (!new_asoc)
goto nomem;
+ if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
+ sctp_scope(sctp_source(chunk)),
+ GFP_ATOMIC) < 0)
+ goto nomem_init;
+
/* The call, sctp_process_init(), can fail on memory allocation. */
if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
sctp_source(chunk),
@@ -401,9 +406,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
len = ntohs(err_chunk->chunk_hdr->length) -
sizeof(sctp_chunkhdr_t);
- if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
- goto nomem_init;
-
repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
if (!repl)
goto nomem_init;
@@ -1452,6 +1454,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
if (!new_asoc)
goto nomem;
+ if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
+ sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
+ goto nomem;
+
/* In the outbound INIT ACK the endpoint MUST copy its current
* Verification Tag and Peers Verification tag into a reserved
* place (local tie-tag and per tie-tag) within the state cookie.
@@ -1488,9 +1494,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
sizeof(sctp_chunkhdr_t);
}
- if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
- goto nomem;
-
repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
if (!repl)
goto nomem;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index c8d05758661d..3a95fcb17a9e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1080,6 +1080,13 @@ static int __sctp_connect(struct sock* sk,
err = -ENOMEM;
goto out_free;
}
+
+ err = sctp_assoc_set_bind_addr_from_ep(asoc, scope,
+ GFP_KERNEL);
+ if (err < 0) {
+ goto out_free;
+ }
+
}
/* Prime the peer's transport structures. */
@@ -1095,11 +1102,6 @@ static int __sctp_connect(struct sock* sk,
walk_size += af->sockaddr_len;
}
- err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
- if (err < 0) {
- goto out_free;
- }
-
/* In case the user of sctp_connectx() wants an association
* id back, assign one now.
*/
@@ -1274,22 +1276,30 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
}
/*
- * New (hopefully final) interface for the API. The option buffer is used
- * both for the returned association id and the addresses.
+ * New (hopefully final) interface for the API.
+ * We use the sctp_getaddrs_old structure so that use-space library
+ * can avoid any unnecessary allocations. The only defferent part
+ * is that we store the actual length of the address buffer into the
+ * addrs_num structure member. That way we can re-use the existing
+ * code.
*/
SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
char __user *optval,
int __user *optlen)
{
+ struct sctp_getaddrs_old param;
sctp_assoc_t assoc_id = 0;
int err = 0;
- if (len < sizeof(assoc_id))
+ if (len < sizeof(param))
return -EINVAL;
+ if (copy_from_user(&param, optval, sizeof(param)))
+ return -EFAULT;
+
err = __sctp_setsockopt_connectx(sk,
- (struct sockaddr __user *)(optval + sizeof(assoc_id)),
- len - sizeof(assoc_id), &assoc_id);
+ (struct sockaddr __user *)param.addrs,
+ param.addr_num, &assoc_id);
if (err == 0 || err == -EINPROGRESS) {
if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))
@@ -1689,6 +1699,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto out_unlock;
}
asoc = new_asoc;
+ err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL);
+ if (err < 0) {
+ err = -ENOMEM;
+ goto out_free;
+ }
/* If the SCTP_INIT ancillary data is specified, set all
* the association init values accordingly.
@@ -1718,11 +1733,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
err = -ENOMEM;
goto out_free;
}
- err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
- if (err < 0) {
- err = -ENOMEM;
- goto out_free;
- }
}
/* ASSERT: we have a valid association at this point. */
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index c256e4839316..37a1184d789f 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -74,7 +74,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
* given destination transport address, set RTO to the protocol
* parameter 'RTO.Initial'.
*/
- peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial);
+ peer->rto = msecs_to_jiffies(sctp_rto_initial);
peer->rtt = 0;
peer->rttvar = 0;
peer->srtt = 0;
@@ -308,7 +308,8 @@ void sctp_transport_route(struct sctp_transport *transport,
/* Initialize sk->sk_rcv_saddr, if the transport is the
* association's active path for getsockname().
*/
- if (asoc && (transport == asoc->peer.active_path))
+ if (asoc && (!asoc->peer.primary_path ||
+ (transport == asoc->peer.active_path)))
opt->pf->af->to_sk_saddr(&transport->saddr,
asoc->base.sk);
} else
@@ -385,7 +386,6 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
tp->rto = tp->asoc->rto_max;
tp->rtt = rtt;
- tp->last_rto = tp->rto;
/* Reset rto_pending so that a new RTT measurement is started when a
* new data chunk is sent.
@@ -601,7 +601,7 @@ void sctp_transport_reset(struct sctp_transport *t)
*/
t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
t->ssthresh = asoc->peer.i.a_rwnd;
- t->last_rto = t->rto = asoc->rto_initial;
+ t->rto = asoc->rto_initial;
t->rtt = 0;
t->srtt = 0;
t->rttvar = 0;
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c
index 22e8fd89477f..c7450c8f0a7c 100644
--- a/net/sunrpc/addr.c
+++ b/net/sunrpc/addr.c
@@ -306,24 +306,25 @@ EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr);
* @sap: buffer into which to plant socket address
* @salen: size of buffer
*
+ * @uaddr does not have to be '\0'-terminated, but strict_strtoul() and
+ * rpc_pton() require proper string termination to be successful.
+ *
* Returns the size of the socket address if successful; otherwise
* zero is returned.
*/
size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
struct sockaddr *sap, const size_t salen)
{
- char *c, buf[RPCBIND_MAXUADDRLEN];
+ char *c, buf[RPCBIND_MAXUADDRLEN + sizeof('\0')];
unsigned long portlo, porthi;
unsigned short port;
- if (uaddr_len > sizeof(buf))
+ if (uaddr_len > RPCBIND_MAXUADDRLEN)
return 0;
memcpy(buf, uaddr, uaddr_len);
- buf[uaddr_len] = '\n';
- buf[uaddr_len + 1] = '\0';
-
+ buf[uaddr_len] = '\0';
c = strrchr(buf, '.');
if (unlikely(c == NULL))
return 0;
@@ -332,9 +333,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
if (unlikely(portlo > 255))
return 0;
- c[0] = '\n';
- c[1] = '\0';
-
+ *c = '\0';
c = strrchr(buf, '.');
if (unlikely(c == NULL))
return 0;
@@ -345,8 +344,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
port = (unsigned short)((porthi << 8) | portlo);
- c[0] = '\0';
-
+ *c = '\0';
if (rpc_pton(buf, strlen(buf), sap, salen) == 0)
return 0;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index ccc5e83cae5d..1c246a4f491e 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -111,7 +111,7 @@ static void svc_release_skb(struct svc_rqst *rqstp)
rqstp->rq_xprt_ctxt = NULL;
dprintk("svc: service %p, releasing skb %p\n", rqstp, skb);
- skb_free_datagram(svsk->sk_sk, skb);
+ skb_free_datagram_locked(svsk->sk_sk, skb);
}
}
@@ -578,7 +578,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
"svc: received unknown control message %d/%d; "
"dropping RPC reply datagram\n",
cmh->cmsg_level, cmh->cmsg_type);
- skb_free_datagram(svsk->sk_sk, skb);
+ skb_free_datagram_locked(svsk->sk_sk, skb);
return 0;
}
@@ -588,18 +588,18 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) {
local_bh_enable();
/* checksum error */
- skb_free_datagram(svsk->sk_sk, skb);
+ skb_free_datagram_locked(svsk->sk_sk, skb);
return 0;
}
local_bh_enable();
- skb_free_datagram(svsk->sk_sk, skb);
+ skb_free_datagram_locked(svsk->sk_sk, skb);
} else {
/* we can use it in-place */
rqstp->rq_arg.head[0].iov_base = skb->data +
sizeof(struct udphdr);
rqstp->rq_arg.head[0].iov_len = len;
if (skb_checksum_complete(skb)) {
- skb_free_datagram(svsk->sk_sk, skb);
+ skb_free_datagram_locked(svsk->sk_sk, skb);
return 0;
}
rqstp->rq_xprt_ctxt = skb;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 51ab497115eb..fc820cd75453 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1074,6 +1074,8 @@ restart:
err = -ECONNREFUSED;
if (other->sk_state != TCP_LISTEN)
goto out_unlock;
+ if (other->sk_shutdown & RCV_SHUTDOWN)
+ goto out_unlock;
if (unix_recvq_full(other)) {
err = -EAGAIN;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 2a33d8bc886b..68b321997d4c 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -358,6 +358,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev);
void cfg80211_conn_work(struct work_struct *work);
+void cfg80211_sme_failed_assoc(struct wireless_dev *wdev);
bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
/* internal helpers */
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 79d2eec54cec..0a6b7a0eca6b 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -62,6 +62,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
u8 *ie = mgmt->u.assoc_resp.variable;
int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
struct cfg80211_internal_bss *bss = NULL;
+ bool need_connect_result = true;
wdev_lock(wdev);
@@ -94,6 +95,14 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
}
WARN_ON(!bss);
+ } else if (wdev->conn) {
+ cfg80211_sme_failed_assoc(wdev);
+ need_connect_result = false;
+ /*
+ * do not call connect_result() now because the
+ * sme will schedule work that does it later.
+ */
+ goto out;
}
if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index eddab097435c..ca3c92a0a14f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4029,7 +4029,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
rdev = cfg80211_get_dev_from_info(info);
if (IS_ERR(rdev)) {
err = PTR_ERR(rdev);
- goto out;
+ goto out_rtnl;
}
net = get_net_ns_by_pid(pid);
@@ -4049,6 +4049,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
put_net(net);
out:
cfg80211_unlock_rdev(rdev);
+ out_rtnl:
rtnl_unlock();
return err;
}
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 93c3ed329204..9f0b2800a9d7 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -26,6 +26,7 @@ struct cfg80211_conn {
CFG80211_CONN_AUTHENTICATING,
CFG80211_CONN_ASSOCIATE_NEXT,
CFG80211_CONN_ASSOCIATING,
+ CFG80211_CONN_DEAUTH_ASSOC_FAIL,
} state;
u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
u8 *ie;
@@ -148,6 +149,12 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
NULL, 0,
WLAN_REASON_DEAUTH_LEAVING);
return err;
+ case CFG80211_CONN_DEAUTH_ASSOC_FAIL:
+ __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
+ NULL, 0,
+ WLAN_REASON_DEAUTH_LEAVING);
+ /* return an error so that we call __cfg80211_connect_result() */
+ return -EINVAL;
default:
return 0;
}
@@ -158,6 +165,7 @@ void cfg80211_conn_work(struct work_struct *work)
struct cfg80211_registered_device *rdev =
container_of(work, struct cfg80211_registered_device, conn_work);
struct wireless_dev *wdev;
+ u8 bssid_buf[ETH_ALEN], *bssid = NULL;
rtnl_lock();
cfg80211_lock_rdev(rdev);
@@ -173,10 +181,13 @@ void cfg80211_conn_work(struct work_struct *work)
wdev_unlock(wdev);
continue;
}
+ if (wdev->conn->params.bssid) {
+ memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
+ bssid = bssid_buf;
+ }
if (cfg80211_conn_do_work(wdev))
__cfg80211_connect_result(
- wdev->netdev,
- wdev->conn->params.bssid,
+ wdev->netdev, bssid,
NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
false, NULL);
@@ -337,6 +348,15 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev)
return true;
}
+void cfg80211_sme_failed_assoc(struct wireless_dev *wdev)
+{
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ wdev->conn->state = CFG80211_CONN_DEAUTH_ASSOC_FAIL;
+ schedule_work(&rdev->conn_work);
+}
+
void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
const u8 *req_ie, size_t req_ie_len,
const u8 *resp_ie, size_t resp_ie_len,
diff --git a/samples/Kconfig b/samples/Kconfig
index b92bde3c6a89..e4be84ac3d38 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -40,5 +40,11 @@ config SAMPLE_KRETPROBES
default m
depends on SAMPLE_KPROBES && KRETPROBES
+config SAMPLE_HW_BREAKPOINT
+ tristate "Build kernel hardware breakpoint examples -- loadable module only"
+ depends on HAVE_HW_BREAKPOINT && m
+ help
+ This builds kernel hardware breakpoint example modules.
+
endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index 43343a03b1f4..0f15e6d77fd6 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,3 +1,4 @@
# Makefile for Linux samples code
-obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/
+obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \
+ hw_breakpoint/
diff --git a/samples/hw_breakpoint/Makefile b/samples/hw_breakpoint/Makefile
new file mode 100644
index 000000000000..0f5c31c2fc47
--- /dev/null
+++ b/samples/hw_breakpoint/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SAMPLE_HW_BREAKPOINT) += data_breakpoint.o
diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c
new file mode 100644
index 000000000000..29525500df00
--- /dev/null
+++ b/samples/hw_breakpoint/data_breakpoint.c
@@ -0,0 +1,87 @@
+/*
+ * data_breakpoint.c - Sample HW Breakpoint file to watch kernel data address
+ *
+ * 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.
+ *
+ * usage: insmod data_breakpoint.ko ksym=<ksym_name>
+ *
+ * This file is a kernel module that places a breakpoint over ksym_name kernel
+ * variable using Hardware Breakpoint register. The corresponding handler which
+ * prints a backtrace is invoked everytime a write operation is performed on
+ * that variable.
+ *
+ * Copyright (C) IBM Corporation, 2009
+ *
+ * Author: K.Prasad <prasad@linux.vnet.ibm.com>
+ */
+#include <linux/module.h> /* Needed by all modules */
+#include <linux/kernel.h> /* Needed for KERN_INFO */
+#include <linux/init.h> /* Needed for the macros */
+#include <linux/kallsyms.h>
+
+#include <linux/perf_event.h>
+#include <linux/hw_breakpoint.h>
+
+struct perf_event **sample_hbp;
+
+static char ksym_name[KSYM_NAME_LEN] = "pid_max";
+module_param_string(ksym, ksym_name, KSYM_NAME_LEN, S_IRUGO);
+MODULE_PARM_DESC(ksym, "Kernel symbol to monitor; this module will report any"
+ " write operations on the kernel symbol");
+
+static void sample_hbp_handler(struct perf_event *temp, void *data)
+{
+ printk(KERN_INFO "%s value is changed\n", ksym_name);
+ dump_stack();
+ printk(KERN_INFO "Dump stack from sample_hbp_handler\n");
+}
+
+static int __init hw_break_module_init(void)
+{
+ int ret;
+ DEFINE_BREAKPOINT_ATTR(attr);
+
+ attr.bp_addr = kallsyms_lookup_name(ksym_name);
+ attr.bp_len = HW_BREAKPOINT_LEN_4;
+ attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
+
+ sample_hbp = register_wide_hw_breakpoint(&attr, sample_hbp_handler);
+ if (IS_ERR(sample_hbp)) {
+ ret = PTR_ERR(sample_hbp);
+ goto fail;
+ }
+
+ printk(KERN_INFO "HW Breakpoint for %s write installed\n", ksym_name);
+
+ return 0;
+
+fail:
+ printk(KERN_INFO "Breakpoint registration failed\n");
+
+ return ret;
+}
+
+static void __exit hw_break_module_exit(void)
+{
+ unregister_wide_hw_breakpoint(sample_hbp);
+ printk(KERN_INFO "HW Breakpoint for %s write uninstalled\n", ksym_name);
+}
+
+module_init(hw_break_module_init);
+module_exit(hw_break_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("K.Prasad");
+MODULE_DESCRIPTION("ksym breakpoint");
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 87bbb8bce9bf..bc4114f1ab30 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2,7 +2,7 @@
# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit)
# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
-# (c) 2008, Andy Whitcroft <apw@canonical.com>
+# (c) 2008,2009, Andy Whitcroft <apw@canonical.com>
# Licensed under the terms of the GNU GPL License version 2
use strict;
@@ -10,7 +10,7 @@ use strict;
my $P = $0;
$P =~ s@.*/@@g;
-my $V = '0.29';
+my $V = '0.30';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -130,7 +130,10 @@ if ($tree) {
my $emitted_corrupt = 0;
-our $Ident = qr{[A-Za-z_][A-Za-z\d_]*};
+our $Ident = qr{
+ [A-Za-z_][A-Za-z\d_]*
+ (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
+ }x;
our $Storage = qr{extern|static|asmlinkage};
our $Sparse = qr{
__user|
@@ -997,23 +1000,25 @@ sub annotate_values {
sub possible {
my ($possible, $line) = @_;
-
- print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
- if ($possible !~ /(?:
+ my $notPermitted = qr{(?:
^(?:
$Modifier|
$Storage|
$Type|
- DEFINE_\S+|
+ DEFINE_\S+
+ )$|
+ ^(?:
goto|
return|
case|
else|
asm|__asm__|
do
- )$|
+ )(?:\s|$)|
^(?:typedef|struct|enum)\b
- )/x) {
+ )}x;
+ warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
+ if ($possible !~ $notPermitted) {
# Check for modifiers.
$possible =~ s/\s*$Storage\s*//g;
$possible =~ s/\s*$Sparse\s*//g;
@@ -1022,8 +1027,10 @@ sub possible {
} elsif ($possible =~ /\s/) {
$possible =~ s/\s*$Type\s*//g;
for my $modifier (split(' ', $possible)) {
- warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
- push(@modifierList, $modifier);
+ if ($modifier !~ $notPermitted) {
+ warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
+ push(@modifierList, $modifier);
+ }
}
} else {
@@ -1138,6 +1145,7 @@ sub process {
# suppression flags
my %suppress_ifbraces;
my %suppress_whiletrailers;
+ my %suppress_export;
# Pre-scan the patch sanitizing the lines.
# Pre-scan the patch looking for any __setup documentation.
@@ -1230,7 +1238,6 @@ sub process {
$linenr++;
my $rawline = $rawlines[$linenr - 1];
- my $hunk_line = ($realcnt != 0);
#extract the line range in the file after the patch is applied
if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
@@ -1247,6 +1254,7 @@ sub process {
%suppress_ifbraces = ();
%suppress_whiletrailers = ();
+ %suppress_export = ();
next;
# track the line number as we move through the hunk, note that
@@ -1270,6 +1278,8 @@ sub process {
$realcnt--;
}
+ my $hunk_line = ($realcnt != 0);
+
#make up the handle for any error we report on this line
$prefix = "$filename:$realline: " if ($emacs && $file);
$prefix = "$filename:$linenr: " if ($emacs && !$file);
@@ -1420,13 +1430,22 @@ sub process {
}
# Check for potential 'bare' types
- my ($stat, $cond, $line_nr_next, $remain_next, $off_next);
+ my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
+ $realline_next);
if ($realcnt && $line =~ /.\s*\S/) {
($stat, $cond, $line_nr_next, $remain_next, $off_next) =
ctx_statement_block($linenr, $realcnt, 0);
$stat =~ s/\n./\n /g;
$cond =~ s/\n./\n /g;
+ # Find the real next line.
+ $realline_next = $line_nr_next;
+ if (defined $realline_next &&
+ (!defined $lines[$realline_next - 1] ||
+ substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
+ $realline_next++;
+ }
+
my $s = $stat;
$s =~ s/{.*$//s;
@@ -1661,8 +1680,8 @@ sub process {
}
# check for initialisation to aggregates open brace on the next line
- if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ &&
- $line =~ /^.\s*{/) {
+ if ($line =~ /^.\s*{/ &&
+ $prevline =~ /(?:^|[^=])=\s*$/) {
ERROR("that open brace { should be on the previous line\n" . $hereprev);
}
@@ -1687,21 +1706,40 @@ sub process {
$line =~ s@//.*@@;
$opline =~ s@//.*@@;
-#EXPORT_SYMBOL should immediately follow its function closing }.
- if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
- ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
+# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
+# the whole statement.
+#print "APW <$lines[$realline_next - 1]>\n";
+ if (defined $realline_next &&
+ exists $lines[$realline_next - 1] &&
+ !defined $suppress_export{$realline_next} &&
+ ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
+ $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
my $name = $1;
- if ($prevline !~ /(?:
- ^.}|
+ if ($stat !~ /(?:
+ \n.}\s*$|
^.DEFINE_$Ident\(\Q$name\E\)|
^.DECLARE_$Ident\(\Q$name\E\)|
^.LIST_HEAD\(\Q$name\E\)|
- ^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
- \b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)
+ ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
+ \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
)/x) {
- WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
+#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
+ $suppress_export{$realline_next} = 2;
+ } else {
+ $suppress_export{$realline_next} = 1;
}
}
+ if (!defined $suppress_export{$linenr} &&
+ $prevline =~ /^.\s*$/ &&
+ ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
+ $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
+#print "FOO B <$lines[$linenr - 1]>\n";
+ $suppress_export{$linenr} = 2;
+ }
+ if (defined $suppress_export{$linenr} &&
+ $suppress_export{$linenr} == 2) {
+ WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
+ }
# check for external initialisers.
if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
index dd2e3d39d4c1..fe555e819bf8 100644
--- a/scripts/dtc/data.c
+++ b/scripts/dtc/data.c
@@ -217,7 +217,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
return d;
}
-struct data data_append_markers(struct data d, struct marker *m)
+static struct data data_append_markers(struct data d, struct marker *m)
{
struct marker **mp = &d.markers;
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index 44dbfd3f0976..a627bbee91d4 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -18,7 +18,7 @@
* USA
*/
-%option noyywrap nounput yylineno
+%option noyywrap noinput nounput yylineno
%x INCLUDE
%x BYTESTRING
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index ac392cb040f6..e27cc636e326 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -9,7 +9,7 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 34
+#define YY_FLEX_SUBMINOR_VERSION 35
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -54,7 +54,6 @@ typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
/* Limits of integral types. */
#ifndef INT8_MIN
@@ -85,6 +84,8 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
+#endif /* ! C99 */
+
#endif /* ! FLEXINT_H */
#ifdef __cplusplus
@@ -141,7 +142,15 @@ typedef unsigned int flex_uint32_t;
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
#endif
/* The state buf must be large enough to hold one state per character in the main buffer.
@@ -192,13 +201,6 @@ extern FILE *yyin, *yyout;
#define unput(c) yyunput( c, (yytext_ptr) )
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- * Given that the standard has decreed that size_t exists since 1989,
- * I guess we can afford to depend on it. Manoj.
- */
-
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
@@ -604,6 +606,7 @@ char *yytext;
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
+#define YY_NO_INPUT 1
@@ -634,7 +637,7 @@ static int dts_version; /* = 0 */
static void push_input_file(const char *filename);
static int pop_input_file(void);
-#line 638 "dtc-lexer.lex.c"
+#line 641 "dtc-lexer.lex.c"
#define INITIAL 0
#define INCLUDE 1
@@ -656,6 +659,35 @@ static int pop_input_file(void);
static int yy_init_globals (void );
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
@@ -688,7 +720,12 @@ static int input (void );
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
#endif
/* Copy whatever the last rule matched to the standard output. */
@@ -696,7 +733,7 @@ static int input (void );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -707,7 +744,7 @@ static int input (void );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- int n; \
+ size_t n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -791,7 +828,7 @@ YY_DECL
#line 64 "dtc-lexer.l"
-#line 795 "dtc-lexer.lex.c"
+#line 832 "dtc-lexer.lex.c"
if ( !(yy_init) )
{
@@ -1116,7 +1153,7 @@ YY_RULE_SETUP
#line 222 "dtc-lexer.l"
ECHO;
YY_BREAK
-#line 1120 "dtc-lexer.lex.c"
+#line 1157 "dtc-lexer.lex.c"
case YY_END_OF_BUFFER:
{
@@ -1840,8 +1877,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
* scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
*
* @return the newly allocated buffer state object.
*/
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index fbbba44fcd0d..22e692919ff9 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -411,7 +411,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
&phandle, sizeof(phandle));
}
-int _stringlist_contains(const char *strlist, int listlen, const char *str)
+static int _stringlist_contains(const char *strlist, int listlen, const char *str)
{
int len = strlen(str);
const char *p;
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index ebeb6eb27907..1521ff11bb97 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -52,7 +52,7 @@ static void write_prefix(FILE *f, int level)
fputc('\t', f);
}
-int isstring(char c)
+static int isstring(char c)
{
return (isprint(c)
|| (c == '\0')
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
index 971e0113ae7a..287467a2e8c7 100644
--- a/scripts/genksyms/keywords.c_shipped
+++ b/scripts/genksyms/keywords.c_shipped
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.2 */
+/* ANSI-C code produced by gperf version 3.0.3 */
/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -30,7 +30,9 @@
#line 1 "scripts/genksyms/keywords.gperf"
-#line 3 "scripts/genksyms/keywords.gperf"
+struct resword;
+static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
+#line 5 "scripts/genksyms/keywords.gperf"
struct resword { const char *name; int token; };
/* maximum key range = 62, duplicates = 0 */
@@ -78,6 +80,9 @@ is_reserved_hash (register const char *str, register unsigned int len)
#ifdef __GNUC__
__inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
#endif
const struct resword *
is_reserved_word (register const char *str, register unsigned int len)
@@ -94,105 +99,105 @@ is_reserved_word (register const char *str, register unsigned int len)
static const struct resword wordlist[] =
{
{""}, {""}, {""},
-#line 26 "scripts/genksyms/keywords.gperf"
+#line 28 "scripts/genksyms/keywords.gperf"
{"asm", ASM_KEYW},
{""},
-#line 8 "scripts/genksyms/keywords.gperf"
+#line 10 "scripts/genksyms/keywords.gperf"
{"__asm", ASM_KEYW},
{""},
-#line 9 "scripts/genksyms/keywords.gperf"
+#line 11 "scripts/genksyms/keywords.gperf"
{"__asm__", ASM_KEYW},
{""}, {""},
-#line 52 "scripts/genksyms/keywords.gperf"
+#line 54 "scripts/genksyms/keywords.gperf"
{"__typeof__", TYPEOF_KEYW},
{""},
-#line 12 "scripts/genksyms/keywords.gperf"
+#line 14 "scripts/genksyms/keywords.gperf"
{"__const", CONST_KEYW},
-#line 11 "scripts/genksyms/keywords.gperf"
- {"__attribute__", ATTRIBUTE_KEYW},
#line 13 "scripts/genksyms/keywords.gperf"
+ {"__attribute__", ATTRIBUTE_KEYW},
+#line 15 "scripts/genksyms/keywords.gperf"
{"__const__", CONST_KEYW},
-#line 18 "scripts/genksyms/keywords.gperf"
+#line 20 "scripts/genksyms/keywords.gperf"
{"__signed__", SIGNED_KEYW},
-#line 44 "scripts/genksyms/keywords.gperf"
+#line 46 "scripts/genksyms/keywords.gperf"
{"static", STATIC_KEYW},
-#line 20 "scripts/genksyms/keywords.gperf"
+#line 22 "scripts/genksyms/keywords.gperf"
{"__volatile__", VOLATILE_KEYW},
-#line 39 "scripts/genksyms/keywords.gperf"
+#line 41 "scripts/genksyms/keywords.gperf"
{"int", INT_KEYW},
-#line 32 "scripts/genksyms/keywords.gperf"
+#line 34 "scripts/genksyms/keywords.gperf"
{"char", CHAR_KEYW},
-#line 33 "scripts/genksyms/keywords.gperf"
+#line 35 "scripts/genksyms/keywords.gperf"
{"const", CONST_KEYW},
-#line 45 "scripts/genksyms/keywords.gperf"
+#line 47 "scripts/genksyms/keywords.gperf"
{"struct", STRUCT_KEYW},
-#line 24 "scripts/genksyms/keywords.gperf"
+#line 26 "scripts/genksyms/keywords.gperf"
{"__restrict__", RESTRICT_KEYW},
-#line 25 "scripts/genksyms/keywords.gperf"
+#line 27 "scripts/genksyms/keywords.gperf"
{"restrict", RESTRICT_KEYW},
-#line 23 "scripts/genksyms/keywords.gperf"
+#line 25 "scripts/genksyms/keywords.gperf"
{"_restrict", RESTRICT_KEYW},
-#line 16 "scripts/genksyms/keywords.gperf"
+#line 18 "scripts/genksyms/keywords.gperf"
{"__inline__", INLINE_KEYW},
-#line 10 "scripts/genksyms/keywords.gperf"
+#line 12 "scripts/genksyms/keywords.gperf"
{"__attribute", ATTRIBUTE_KEYW},
{""},
-#line 14 "scripts/genksyms/keywords.gperf"
+#line 16 "scripts/genksyms/keywords.gperf"
{"__extension__", EXTENSION_KEYW},
-#line 35 "scripts/genksyms/keywords.gperf"
+#line 37 "scripts/genksyms/keywords.gperf"
{"enum", ENUM_KEYW},
-#line 19 "scripts/genksyms/keywords.gperf"
+#line 21 "scripts/genksyms/keywords.gperf"
{"__volatile", VOLATILE_KEYW},
-#line 36 "scripts/genksyms/keywords.gperf"
+#line 38 "scripts/genksyms/keywords.gperf"
{"extern", EXTERN_KEYW},
{""},
-#line 17 "scripts/genksyms/keywords.gperf"
+#line 19 "scripts/genksyms/keywords.gperf"
{"__signed", SIGNED_KEYW},
-#line 7 "scripts/genksyms/keywords.gperf"
+#line 9 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
{""},
-#line 51 "scripts/genksyms/keywords.gperf"
+#line 53 "scripts/genksyms/keywords.gperf"
{"typeof", TYPEOF_KEYW},
-#line 46 "scripts/genksyms/keywords.gperf"
+#line 48 "scripts/genksyms/keywords.gperf"
{"typedef", TYPEDEF_KEYW},
-#line 15 "scripts/genksyms/keywords.gperf"
+#line 17 "scripts/genksyms/keywords.gperf"
{"__inline", INLINE_KEYW},
-#line 31 "scripts/genksyms/keywords.gperf"
+#line 33 "scripts/genksyms/keywords.gperf"
{"auto", AUTO_KEYW},
-#line 47 "scripts/genksyms/keywords.gperf"
+#line 49 "scripts/genksyms/keywords.gperf"
{"union", UNION_KEYW},
{""}, {""},
-#line 48 "scripts/genksyms/keywords.gperf"
+#line 50 "scripts/genksyms/keywords.gperf"
{"unsigned", UNSIGNED_KEYW},
-#line 49 "scripts/genksyms/keywords.gperf"
+#line 51 "scripts/genksyms/keywords.gperf"
{"void", VOID_KEYW},
-#line 42 "scripts/genksyms/keywords.gperf"
+#line 44 "scripts/genksyms/keywords.gperf"
{"short", SHORT_KEYW},
{""}, {""},
-#line 50 "scripts/genksyms/keywords.gperf"
+#line 52 "scripts/genksyms/keywords.gperf"
{"volatile", VOLATILE_KEYW},
{""},
-#line 37 "scripts/genksyms/keywords.gperf"
+#line 39 "scripts/genksyms/keywords.gperf"
{"float", FLOAT_KEYW},
-#line 34 "scripts/genksyms/keywords.gperf"
+#line 36 "scripts/genksyms/keywords.gperf"
{"double", DOUBLE_KEYW},
{""},
-#line 5 "scripts/genksyms/keywords.gperf"
+#line 7 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
{""}, {""},
-#line 38 "scripts/genksyms/keywords.gperf"
+#line 40 "scripts/genksyms/keywords.gperf"
{"inline", INLINE_KEYW},
-#line 6 "scripts/genksyms/keywords.gperf"
+#line 8 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
-#line 41 "scripts/genksyms/keywords.gperf"
+#line 43 "scripts/genksyms/keywords.gperf"
{"register", REGISTER_KEYW},
{""},
-#line 22 "scripts/genksyms/keywords.gperf"
+#line 24 "scripts/genksyms/keywords.gperf"
{"_Bool", BOOL_KEYW},
-#line 43 "scripts/genksyms/keywords.gperf"
+#line 45 "scripts/genksyms/keywords.gperf"
{"signed", SIGNED_KEYW},
{""}, {""},
-#line 40 "scripts/genksyms/keywords.gperf"
+#line 42 "scripts/genksyms/keywords.gperf"
{"long", LONG_KEYW}
};
diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf
index 5ef3733225fb..8fe977a4d57b 100644
--- a/scripts/genksyms/keywords.gperf
+++ b/scripts/genksyms/keywords.gperf
@@ -1,4 +1,6 @@
%{
+struct resword;
+static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
%}
struct resword { const char *name; int token; }
%%
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index cdb44b63342e..81a67a458e78 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -5,15 +5,15 @@
# Print selected MAINTAINERS information for
# the files modified in a patch or for a file
#
-# usage: perl scripts/get_maintainers.pl [OPTIONS] <patch>
-# perl scripts/get_maintainers.pl [OPTIONS] -f <file>
+# usage: perl scripts/get_maintainer.pl [OPTIONS] <patch>
+# perl scripts/get_maintainer.pl [OPTIONS] -f <file>
#
# Licensed under the terms of the GNU GPL License version 2
use strict;
my $P = $0;
-my $V = '0.20';
+my $V = '0.21';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -37,6 +37,7 @@ my $scm = 0;
my $web = 0;
my $subsystem = 0;
my $status = 0;
+my $keywords = 1;
my $from_filename = 0;
my $pattern_depth = 0;
my $version = 0;
@@ -84,6 +85,7 @@ if (!GetOptions(
'scm!' => \$scm,
'web!' => \$web,
'pattern-depth=i' => \$pattern_depth,
+ 'k|keywords!' => \$keywords,
'f|file' => \$from_filename,
'v|version' => \$version,
'h|help' => \$help,
@@ -132,6 +134,8 @@ if (!top_of_kernel_tree($lk_path)) {
## Read MAINTAINERS for type/value pairs
my @typevalue = ();
+my %keyword_hash;
+
open(MAINT, "<${lk_path}MAINTAINERS") || die "$P: Can't open MAINTAINERS\n";
while (<MAINT>) {
my $line = $_;
@@ -149,6 +153,8 @@ while (<MAINT>) {
if ((-d $value)) {
$value =~ s@([^/])$@$1/@;
}
+ } elsif ($type eq "K") {
+ $keyword_hash{@typevalue} = $value;
}
push(@typevalue, "$type:$value");
} elsif (!/^(\s)*$/) {
@@ -188,6 +194,7 @@ if ($email_remove_duplicates) {
my @files = ();
my @range = ();
+my @keyword_tvi = ();
foreach my $file (@ARGV) {
##if $file is a directory and it lacks a trailing slash, add one
@@ -198,11 +205,24 @@ foreach my $file (@ARGV) {
}
if ($from_filename) {
push(@files, $file);
+ if (-f $file && $keywords) {
+ open(FILE, "<$file") or die "$P: Can't open ${file}\n";
+ while (<FILE>) {
+ my $patch_line = $_;
+ foreach my $line (keys %keyword_hash) {
+ if ($patch_line =~ m/^.*$keyword_hash{$line}/x) {
+ push(@keyword_tvi, $line);
+ }
+ }
+ }
+ close(FILE);
+ }
} else {
my $file_cnt = @files;
my $lastfile;
open(PATCH, "<$file") or die "$P: Can't open ${file}\n";
while (<PATCH>) {
+ my $patch_line = $_;
if (m/^\+\+\+\s+(\S+)/) {
my $filename = $1;
$filename =~ s@^[^/]*/@@;
@@ -213,6 +233,12 @@ foreach my $file (@ARGV) {
if ($email_git_blame) {
push(@range, "$lastfile:$1:$2");
}
+ } elsif ($keywords) {
+ foreach my $line (keys %keyword_hash) {
+ if ($patch_line =~ m/^[+-].*$keyword_hash{$line}/x) {
+ push(@keyword_tvi, $line);
+ }
+ }
}
}
close(PATCH);
@@ -286,6 +312,13 @@ foreach my $file (@files) {
}
}
+if ($keywords) {
+ @keyword_tvi = sort_and_uniq(@keyword_tvi);
+ foreach my $line (@keyword_tvi) {
+ add_categories($line);
+ }
+}
+
if ($email) {
foreach my $chief (@penguin_chief) {
if ($chief =~ m/^(.*):(.*)/) {
@@ -384,6 +417,7 @@ Output type options:
Other options:
--pattern-depth => Number of pattern directory traversals (default: 0 (all))
+ --keywords => scan patch for keywords (default: 1 (on))
--version => show version
--help => show this help information
@@ -486,7 +520,6 @@ sub format_email {
}
sub find_starting_index {
-
my ($index) = @_;
while ($index > 0) {
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 6d69c7ccdcc7..80599e3a7994 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -30,7 +30,7 @@ silentoldconfig: $(obj)/conf
$< -s $(Kconfig)
localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
- $(Q)perl $< $(Kconfig) > .tmp.config
+ $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config
$(Q)if [ -f .config ]; then \
cmp -s .tmp.config .config || \
(mv -f .config .config.old.1; \
@@ -44,7 +44,7 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
$(Q)rm -f .tmp.config
localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
- $(Q)perl $< $(Kconfig) > .tmp.config
+ $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config
$(Q)sed -i s/=m/=y/ .tmp.config
$(Q)if [ -f .config ]; then \
cmp -s .tmp.config .config || \
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index dc3e81807d13..fdc7113b08d1 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -160,7 +160,15 @@ typedef unsigned int flex_uint32_t;
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
#endif
/* The state buf must be large enough to hold one state per character in the main buffer.
@@ -802,7 +810,7 @@ static int last_ts, first_ts;
static void zconf_endhelp(void);
static void zconf_endfile(void);
-void new_string(void)
+static void new_string(void)
{
text = malloc(START_STRSIZE);
text_asize = START_STRSIZE;
@@ -810,7 +818,7 @@ void new_string(void)
*text = 0;
}
-void append_string(const char *str, int size)
+static void append_string(const char *str, int size)
{
int new_size = text_size + size + 1;
if (new_size > text_asize) {
@@ -824,7 +832,7 @@ void append_string(const char *str, int size)
text[text_size] = 0;
}
-void alloc_string(const char *str, int size)
+static void alloc_string(const char *str, int size)
{
text = malloc(size + 1);
memcpy(text, str, size);
@@ -914,7 +922,12 @@ static int input (void );
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
#endif
/* Copy whatever the last rule matched to the standard output. */
@@ -922,7 +935,7 @@ static int input (void );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO fwrite( zconftext, zconfleng, 1, zconfout )
+#define ECHO do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0)
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -2060,8 +2073,8 @@ YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
* scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
*
* @return the newly allocated buffer state object.
*/
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index 95984db8e1e0..0d800820c3cd 100644
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -43,7 +43,6 @@
# make oldconfig
#
my $config = ".config";
-my $linuxpath = ".";
my $uname = `uname -r`;
chomp $uname;
@@ -111,7 +110,11 @@ sub find_config {
find_config;
-my @makefiles = `find $linuxpath -name Makefile`;
+# Get the build source and top level Kconfig file (passed in)
+my $ksource = $ARGV[0];
+my $kconfig = $ARGV[1];
+
+my @makefiles = `find $ksource -name Makefile`;
my %depends;
my %selects;
my %prompts;
@@ -119,9 +122,6 @@ my %objects;
my $var;
my $cont = 0;
-# Get the top level Kconfig file (passed in)
-my $kconfig = $ARGV[0];
-
# prevent recursion
my %read_kconfigs;
@@ -132,7 +132,7 @@ sub read_kconfig {
my $config;
my @kconfigs;
- open(KIN, $kconfig) || die "Can't open $kconfig";
+ open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig";
while (<KIN>) {
chomp;
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
index 25ef5d01c0af..d8bc74249622 100644
--- a/scripts/kconfig/zconf.gperf
+++ b/scripts/kconfig/zconf.gperf
@@ -9,6 +9,8 @@
struct kconf_id;
+static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
+
%%
mainmenu, T_MAINMENU, TF_COMMAND
menu, T_MENU, TF_COMMAND
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
index 5c73d51339d8..c1748faf4634 100644
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -30,6 +30,8 @@
#endif
struct kconf_id;
+
+static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
/* maximum key range = 47, duplicates = 0 */
#ifdef __GNUC__
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 21ff69c9ad4e..d8f7236cb0a3 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -39,7 +39,7 @@ static int last_ts, first_ts;
static void zconf_endhelp(void);
static void zconf_endfile(void);
-void new_string(void)
+static void new_string(void)
{
text = malloc(START_STRSIZE);
text_asize = START_STRSIZE;
@@ -47,7 +47,7 @@ void new_string(void)
*text = 0;
}
-void append_string(const char *str, int size)
+static void append_string(const char *str, int size)
{
int new_size = text_size + size + 1;
if (new_size > text_asize) {
@@ -61,7 +61,7 @@ void append_string(const char *str, int size)
text[text_size] = 0;
}
-void alloc_string(const char *str, int size)
+static void alloc_string(const char *str, int size)
{
text = malloc(size + 1);
memcpy(text, str, size);
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index 95df833b5a9d..6e9dcd59aa87 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -1,24 +1,23 @@
-/* A Bison parser, made by GNU Bison 2.3. */
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* A Bison parser, made by GNU Bison 2.4.1. */
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
+
+ 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.
-
+ the Free Software Foundation, either version 3 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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -29,7 +28,7 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
@@ -47,7 +46,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.3"
+#define YYBISON_VERSION "2.4.1"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -55,94 +54,23 @@
/* Pure parsers. */
#define YYPURE 0
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
/* Using locations. */
#define YYLSP_NEEDED 0
/* Substitute the variable and function names. */
-#define yyparse zconfparse
-#define yylex zconflex
-#define yyerror zconferror
-#define yylval zconflval
-#define yychar zconfchar
-#define yydebug zconfdebug
-#define yynerrs zconfnerrs
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- T_MAINMENU = 258,
- T_MENU = 259,
- T_ENDMENU = 260,
- T_SOURCE = 261,
- T_CHOICE = 262,
- T_ENDCHOICE = 263,
- T_COMMENT = 264,
- T_CONFIG = 265,
- T_MENUCONFIG = 266,
- T_HELP = 267,
- T_HELPTEXT = 268,
- T_IF = 269,
- T_ENDIF = 270,
- T_DEPENDS = 271,
- T_OPTIONAL = 272,
- T_PROMPT = 273,
- T_TYPE = 274,
- T_DEFAULT = 275,
- T_SELECT = 276,
- T_RANGE = 277,
- T_OPTION = 278,
- T_ON = 279,
- T_WORD = 280,
- T_WORD_QUOTE = 281,
- T_UNEQUAL = 282,
- T_CLOSE_PAREN = 283,
- T_OPEN_PAREN = 284,
- T_EOL = 285,
- T_OR = 286,
- T_AND = 287,
- T_EQUAL = 288,
- T_NOT = 289
- };
-#endif
-/* Tokens. */
-#define T_MAINMENU 258
-#define T_MENU 259
-#define T_ENDMENU 260
-#define T_SOURCE 261
-#define T_CHOICE 262
-#define T_ENDCHOICE 263
-#define T_COMMENT 264
-#define T_CONFIG 265
-#define T_MENUCONFIG 266
-#define T_HELP 267
-#define T_HELPTEXT 268
-#define T_IF 269
-#define T_ENDIF 270
-#define T_DEPENDS 271
-#define T_OPTIONAL 272
-#define T_PROMPT 273
-#define T_TYPE 274
-#define T_DEFAULT 275
-#define T_SELECT 276
-#define T_RANGE 277
-#define T_OPTION 278
-#define T_ON 279
-#define T_WORD 280
-#define T_WORD_QUOTE 281
-#define T_UNEQUAL 282
-#define T_CLOSE_PAREN 283
-#define T_OPEN_PAREN 284
-#define T_EOL 285
-#define T_OR 286
-#define T_AND 287
-#define T_EQUAL 288
-#define T_NOT 289
-
-
+#define yyparse zconfparse
+#define yylex zconflex
+#define yyerror zconferror
+#define yylval zconflval
+#define yychar zconfchar
+#define yydebug zconfdebug
+#define yynerrs zconfnerrs
/* Copy the first part of user declarations. */
@@ -163,8 +91,6 @@
#define LKC_DIRECT_LINK
#include "lkc.h"
-#include "zconf.hash.c"
-
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001
@@ -188,6 +114,7 @@ static struct menu *current_menu, *current_entry;
#endif
+
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
@@ -206,31 +133,77 @@ static struct menu *current_menu, *current_entry;
# define YYTOKEN_TABLE 0
#endif
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ T_MAINMENU = 258,
+ T_MENU = 259,
+ T_ENDMENU = 260,
+ T_SOURCE = 261,
+ T_CHOICE = 262,
+ T_ENDCHOICE = 263,
+ T_COMMENT = 264,
+ T_CONFIG = 265,
+ T_MENUCONFIG = 266,
+ T_HELP = 267,
+ T_HELPTEXT = 268,
+ T_IF = 269,
+ T_ENDIF = 270,
+ T_DEPENDS = 271,
+ T_OPTIONAL = 272,
+ T_PROMPT = 273,
+ T_TYPE = 274,
+ T_DEFAULT = 275,
+ T_SELECT = 276,
+ T_RANGE = 277,
+ T_OPTION = 278,
+ T_ON = 279,
+ T_WORD = 280,
+ T_WORD_QUOTE = 281,
+ T_UNEQUAL = 282,
+ T_CLOSE_PAREN = 283,
+ T_OPEN_PAREN = 284,
+ T_EOL = 285,
+ T_OR = 286,
+ T_AND = 287,
+ T_EQUAL = 288,
+ T_NOT = 289
+ };
+#endif
+
+
+
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-
{
+
+
char *string;
struct file *file;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
struct kconf_id *id;
-}
-/* Line 187 of yacc.c. */
- YYSTYPE;
+
+
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
#endif
-
/* Copy the second part of user declarations. */
-/* Line 216 of yacc.c. */
+/* Include zconf.hash.c here so it can see the token constants. */
+#include "zconf.hash.c"
+
#ifdef short
@@ -306,14 +279,14 @@ typedef short int yytype_int16;
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static int
-YYID (int i)
+YYID (int yyi)
#else
static int
-YYID (i)
- int i;
+YYID (yyi)
+ int yyi;
#endif
{
- return i;
+ return yyi;
}
#endif
@@ -394,9 +367,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- yytype_int16 yyss;
- YYSTYPE yyvs;
- };
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
/* The size of the maximum gap between one aligned stack and the next. */
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -430,12 +403,12 @@ union yyalloc
elements in the stack, and YYPTR gives the new location of the
stack. Advance YYPTR to a properly aligned location for the next
stack. */
-# define YYSTACK_RELOCATE(Stack) \
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
do \
{ \
YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack, Stack, yysize); \
- Stack = &yyptr->Stack; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
@@ -558,18 +531,18 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 104, 104, 106, 108, 109, 110, 111, 112, 113,
- 114, 118, 122, 122, 122, 122, 122, 122, 122, 126,
- 127, 128, 129, 130, 131, 135, 136, 142, 150, 156,
- 164, 174, 176, 177, 178, 179, 180, 181, 184, 192,
- 198, 208, 214, 220, 223, 225, 236, 237, 242, 251,
- 256, 264, 267, 269, 270, 271, 272, 273, 276, 282,
- 293, 299, 309, 311, 316, 324, 332, 335, 337, 338,
- 339, 344, 351, 356, 364, 367, 369, 370, 371, 374,
- 382, 389, 396, 402, 409, 411, 412, 413, 416, 424,
- 426, 431, 432, 435, 436, 437, 441, 442, 445, 446,
- 449, 450, 451, 452, 453, 454, 455, 458, 459, 462,
- 463
+ 0, 107, 107, 109, 111, 112, 113, 114, 115, 116,
+ 117, 121, 125, 125, 125, 125, 125, 125, 125, 129,
+ 130, 131, 132, 133, 134, 138, 139, 145, 153, 159,
+ 167, 177, 179, 180, 181, 182, 183, 184, 187, 195,
+ 201, 211, 217, 223, 226, 228, 239, 240, 245, 254,
+ 259, 267, 270, 272, 273, 274, 275, 276, 279, 285,
+ 296, 302, 312, 314, 319, 327, 335, 338, 340, 341,
+ 342, 347, 354, 359, 367, 370, 372, 373, 374, 377,
+ 385, 392, 399, 405, 412, 414, 415, 416, 419, 427,
+ 429, 434, 435, 438, 439, 440, 444, 445, 448, 449,
+ 452, 453, 454, 455, 456, 457, 458, 461, 462, 465,
+ 466
};
#endif
@@ -985,17 +958,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
#else
static void
-yy_stack_print (bottom, top)
- yytype_int16 *bottom;
- yytype_int16 *top;
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
#endif
{
YYFPRINTF (stderr, "Stack now");
- for (; bottom <= top; ++bottom)
- YYFPRINTF (stderr, " %d", *bottom);
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
YYFPRINTF (stderr, "\n");
}
@@ -1029,11 +1005,11 @@ yy_reduce_print (yyvsp, yyrule)
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
- fprintf (stderr, " $%d = ", yyi + 1);
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
);
- fprintf (stderr, "\n");
+ YYFPRINTF (stderr, "\n");
}
}
@@ -1343,10 +1319,8 @@ yydestruct (yymsg, yytype, yyvaluep)
break;
}
}
-
/* Prevent warnings from -Wmissing-prototypes. */
-
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
@@ -1362,11 +1336,10 @@ int yyparse ();
#endif /* ! YYPARSE_PARAM */
-
-/* The look-ahead symbol. */
+/* The lookahead symbol. */
int yychar;
-/* The semantic value of the look-ahead symbol. */
+/* The semantic value of the lookahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
@@ -1374,9 +1347,9 @@ int yynerrs;
-/*----------.
-| yyparse. |
-`----------*/
+/*-------------------------.
+| yyparse or yypush_parse. |
+`-------------------------*/
#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1400,66 +1373,68 @@ yyparse ()
#endif
#endif
{
-
- int yystate;
- int yyn;
- int yyresult;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
- /* Look-ahead token as an internal (translated) token number. */
- int yytoken = 0;
-#if YYERROR_VERBOSE
- /* Buffer for error messages, and its allocated size. */
- char yymsgbuf[128];
- char *yymsg = yymsgbuf;
- YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
- /* Three stacks and their tools:
- `yyss': related to states,
- `yyvs': related to semantic values,
- `yyls': related to locations.
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss = yyssa;
- yytype_int16 *yyssp;
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs = yyvsa;
- YYSTYPE *yyvsp;
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
- YYSIZE_T yystacksize = YYINITDEPTH;
+ YYSIZE_T yystacksize;
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
int yylen = 0;
+ yytoken = 0;
+ yyss = yyssa;
+ yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
+ yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
-
yyssp = yyss;
yyvsp = yyvs;
@@ -1489,7 +1464,6 @@ yyparse ()
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;
-
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
@@ -1497,7 +1471,6 @@ yyparse ()
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
-
&yystacksize);
yyss = yyss1;
@@ -1520,9 +1493,8 @@ yyparse ()
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss);
- YYSTACK_RELOCATE (yyvs);
-
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
@@ -1533,7 +1505,6 @@ yyparse ()
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
-
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
@@ -1543,6 +1514,9 @@ yyparse ()
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
goto yybackup;
/*-----------.
@@ -1551,16 +1525,16 @@ yyparse ()
yybackup:
/* Do appropriate processing given the current state. Read a
- look-ahead token if we need one and don't already have one. */
+ lookahead token if we need one and don't already have one. */
- /* First try to decide what to do without reference to look-ahead token. */
+ /* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
- /* Not known => get a look-ahead token if don't already have one. */
+ /* Not known => get a lookahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
@@ -1592,20 +1566,16 @@ yybackup:
goto yyreduce;
}
- if (yyn == YYFINAL)
- YYACCEPT;
-
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus)
yyerrstatus--;
- /* Shift the look-ahead token. */
+ /* Shift the lookahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- /* Discard the shifted token unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
yystate = yyn;
*++yyvsp = yylval;
@@ -2029,7 +1999,6 @@ yyreduce:
break;
-/* Line 1267 of yacc.c. */
default: break;
}
@@ -2041,7 +2010,6 @@ yyreduce:
*++yyvsp = yyval;
-
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
@@ -2106,7 +2074,7 @@ yyerrlab:
if (yyerrstatus == 3)
{
- /* If just tried and failed to reuse look-ahead token after an
+ /* If just tried and failed to reuse lookahead token after an
error, discard it. */
if (yychar <= YYEOF)
@@ -2123,7 +2091,7 @@ yyerrlab:
}
}
- /* Else will try to reuse look-ahead token after shifting the error
+ /* Else will try to reuse lookahead token after shifting the error
token. */
goto yyerrlab1;
@@ -2180,9 +2148,6 @@ yyerrlab1:
YY_STACK_PRINT (yyss, yyssp);
}
- if (yyn == YYFINAL)
- YYACCEPT;
-
*++yyvsp = yylval;
@@ -2207,7 +2172,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#ifndef yyoverflow
+#if !defined(yyoverflow) || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -2218,7 +2183,7 @@ yyexhaustedlab:
#endif
yyreturn:
- if (yychar != YYEOF && yychar != YYEMPTY)
+ if (yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval);
/* Do not reclaim the symbols of the rule which action triggered
@@ -2284,7 +2249,7 @@ void conf_parse(const char *name)
sym_set_change_count(1);
}
-const char *zconf_tokenname(int token)
+static const char *zconf_tokenname(int token)
{
switch (token) {
case T_MENU: return "menu";
@@ -2348,7 +2313,7 @@ static void zconferror(const char *err)
#endif
}
-void print_quoted_string(FILE *out, const char *str)
+static void print_quoted_string(FILE *out, const char *str)
{
const char *p;
int len;
@@ -2365,7 +2330,7 @@ void print_quoted_string(FILE *out, const char *str)
putc('"', out);
}
-void print_symbol(FILE *out, struct menu *menu)
+static void print_symbol(FILE *out, struct menu *menu)
{
struct symbol *sym = menu->sym;
struct property *prop;
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 9710b82466f2..8c43491f8cc9 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -14,8 +14,6 @@
#define LKC_DIRECT_LINK
#include "lkc.h"
-#include "zconf.hash.c"
-
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001
@@ -100,6 +98,11 @@ static struct menu *current_menu, *current_entry;
menu_end_menu();
} if_entry menu_entry choice_entry
+%{
+/* Include zconf.hash.c here so it can see the token constants. */
+#include "zconf.hash.c"
+%}
+
%%
input: stmt_list;
@@ -501,7 +504,7 @@ void conf_parse(const char *name)
sym_set_change_count(1);
}
-const char *zconf_tokenname(int token)
+static const char *zconf_tokenname(int token)
{
switch (token) {
case T_MENU: return "menu";
@@ -565,7 +568,7 @@ static void zconferror(const char *err)
#endif
}
-void print_quoted_string(FILE *out, const char *str)
+static void print_quoted_string(FILE *out, const char *str)
{
const char *p;
int len;
@@ -582,7 +585,7 @@ void print_quoted_string(FILE *out, const char *str)
putc('"', out);
}
-void print_symbol(FILE *out, struct menu *menu)
+static void print_symbol(FILE *out, struct menu *menu)
{
struct symbol *sym = menu->sym;
struct property *prop;
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index ea9f8a58678f..241310e59cd6 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1852,10 +1852,17 @@ sub tracepoint_munge($) {
my $tracepointname = 0;
my $tracepointargs = 0;
- if($prototype =~ m/TRACE_EVENT\((.*?),/) {
+ if ($prototype =~ m/TRACE_EVENT\((.*?),/) {
$tracepointname = $1;
}
- if($prototype =~ m/TP_PROTO\((.*?)\)/) {
+ if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) {
+ $tracepointname = $1;
+ }
+ if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) {
+ $tracepointname = $2;
+ }
+ $tracepointname =~ s/^\s+//; #strip leading whitespace
+ if ($prototype =~ m/TP_PROTO\((.*?)\)/) {
$tracepointargs = $1;
}
if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
@@ -1920,7 +1927,9 @@ sub process_state3_function($$) {
if ($prototype =~ /SYSCALL_DEFINE/) {
syscall_munge();
}
- if ($prototype =~ /TRACE_EVENT/) {
+ if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ ||
+ $prototype =~ /DEFINE_SINGLE_EVENT/)
+ {
tracepoint_munge($file);
}
dump_function($prototype, $file);
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 090d300d7394..f0d14452632b 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -6,77 +6,93 @@
# all the offsets to the calls to mcount.
#
#
-# What we want to end up with is a section in vmlinux called
-# __mcount_loc that contains a list of pointers to all the
-# call sites in the kernel that call mcount. Later on boot up, the kernel
-# will read this list, save the locations and turn them into nops.
-# When tracing or profiling is later enabled, these locations will then
-# be converted back to pointers to some function.
+# What we want to end up with this is that each object file will have a
+# section called __mcount_loc that will hold the list of pointers to mcount
+# callers. After final linking, the vmlinux will have within .init.data the
+# list of all callers to mcount between __start_mcount_loc and __stop_mcount_loc.
+# Later on boot up, the kernel will read this list, save the locations and turn
+# them into nops. When tracing or profiling is later enabled, these locations
+# will then be converted back to pointers to some function.
#
# This is no easy feat. This script is called just after the original
# object is compiled and before it is linked.
#
-# The references to the call sites are offsets from the section of text
-# that the call site is in. Hence, all functions in a section that
-# has a call site to mcount, will have the offset from the beginning of
-# the section and not the beginning of the function.
+# When parse this object file using 'objdump', the references to the call
+# sites are offsets from the section that the call site is in. Hence, all
+# functions in a section that has a call site to mcount, will have the
+# offset from the beginning of the section and not the beginning of the
+# function.
+#
+# But where this section will reside finally in vmlinx is undetermined at
+# this point. So we can't use this kind of offsets to record the final
+# address of this call site.
+#
+# The trick is to change the call offset referring the start of a section to
+# referring a function symbol in this section. During the link step, 'ld' will
+# compute the final address according to the information we record.
#
-# The trick is to find a way to record the beginning of the section.
-# The way we do this is to look at the first function in the section
-# which will also be the location of that section after final link.
# e.g.
#
# .section ".sched.text", "ax"
-# .globl my_func
-# my_func:
# [...]
-# call mcount (offset: 0x5)
+# func1:
+# [...]
+# call mcount (offset: 0x10)
# [...]
# ret
-# other_func:
+# .globl fun2
+# func2: (offset: 0x20)
# [...]
-# call mcount (offset: 0x1b)
+# [...]
+# ret
+# func3:
+# [...]
+# call mcount (offset: 0x30)
# [...]
#
# Both relocation offsets for the mcounts in the above example will be
-# offset from .sched.text. If we make another file called tmp.s with:
+# offset from .sched.text. If we choose global symbol func2 as a reference and
+# make another file called tmp.s with the new offsets:
#
# .section __mcount_loc
-# .quad my_func + 0x5
-# .quad my_func + 0x1b
+# .quad func2 - 0x10
+# .quad func2 + 0x10
#
-# We can then compile this tmp.s into tmp.o, and link it to the original
+# We can then compile this tmp.s into tmp.o, and link it back to the original
# object.
#
-# But this gets hard if my_func is not globl (a static function).
-# In such a case we have:
+# In our algorithm, we will choose the first global function we meet in this
+# section as the reference. But this gets hard if there is no global functions
+# in this section. In such a case we have to select a local one. E.g. func1:
#
# .section ".sched.text", "ax"
-# my_func:
+# func1:
# [...]
-# call mcount (offset: 0x5)
+# call mcount (offset: 0x10)
# [...]
# ret
-# other_func:
+# func2:
# [...]
-# call mcount (offset: 0x1b)
+# call mcount (offset: 0x20)
# [...]
+# .section "other.section"
#
# If we make the tmp.s the same as above, when we link together with
-# the original object, we will end up with two symbols for my_func:
+# the original object, we will end up with two symbols for func1:
# one local, one global. After final compile, we will end up with
-# an undefined reference to my_func.
+# an undefined reference to func1 or a wrong reference to another global
+# func1 in other files.
#
# Since local objects can reference local variables, we need to find
# a way to make tmp.o reference the local objects of the original object
-# file after it is linked together. To do this, we convert the my_func
+# file after it is linked together. To do this, we convert func1
# into a global symbol before linking tmp.o. Then after we link tmp.o
-# we will only have a single symbol for my_func that is global.
-# We can convert my_func back into a local symbol and we are done.
+# we will only have a single symbol for func1 that is global.
+# We can convert func1 back into a local symbol and we are done.
#
# Here are the steps we take:
#
-# 1) Record all the local symbols by using 'nm'
+# 1) Record all the local and weak symbols by using 'nm'
# 2) Use objdump to find all the call site offsets and sections for
# mcount.
# 3) Compile the list into its own object.
@@ -86,10 +102,8 @@
# 6) Link together this new object with the list object.
# 7) Convert the local functions back to local symbols and rename
# the result as the original object.
-# End.
# 8) Link the object with the list object.
# 9) Move the result back to the original object.
-# End.
#
use strict;
@@ -99,7 +113,7 @@ $P =~ s@.*/@@g;
my $V = '0.1';
-if ($#ARGV < 7) {
+if ($#ARGV != 10) {
print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
print "version: $V\n";
exit(1);
@@ -109,7 +123,7 @@ my ($arch, $bits, $objdump, $objcopy, $cc,
$ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
# This file refers to mcount and shouldn't be ftraced, so lets' ignore it
-if ($inputfile eq "kernel/trace/ftrace.o") {
+if ($inputfile =~ m,kernel/trace/ftrace\.o$,) {
exit(0);
}
@@ -119,6 +133,7 @@ my %text_sections = (
".sched.text" => 1,
".spinlock.text" => 1,
".irqentry.text" => 1,
+ ".text.unlikely" => 1,
);
$objdump = "objdump" if ((length $objdump) == 0);
@@ -137,13 +152,47 @@ my %weak; # List of weak functions
my %convert; # List of local functions used that needs conversion
my $type;
-my $nm_regex; # Find the local functions (return function)
+my $local_regex; # Match a local function (return function)
+my $weak_regex; # Match a weak function (return function)
my $section_regex; # Find the start of a section
my $function_regex; # Find the name of a function
# (return offset and func name)
my $mcount_regex; # Find the call site to mcount (return offset)
my $alignment; # The .align value to use for $mcount_section
my $section_type; # Section header plus possible alignment command
+my $can_use_local = 0; # If we can use local function references
+
+# Shut up recordmcount if user has older objcopy
+my $quiet_recordmcount = ".tmp_quiet_recordmcount";
+my $print_warning = 1;
+$print_warning = 0 if ( -f $quiet_recordmcount);
+
+##
+# check_objcopy - whether objcopy supports --globalize-symbols
+#
+# --globalize-symbols came out in 2.17, we must test the version
+# of objcopy, and if it is less than 2.17, then we can not
+# record local functions.
+sub check_objcopy
+{
+ open (IN, "$objcopy --version |") or die "error running $objcopy";
+ while (<IN>) {
+ if (/objcopy.*\s(\d+)\.(\d+)/) {
+ $can_use_local = 1 if ($1 > 2 || ($1 == 2 && $2 >= 17));
+ last;
+ }
+ }
+ close (IN);
+
+ if (!$can_use_local && $print_warning) {
+ print STDERR "WARNING: could not find objcopy version or version " .
+ "is less than 2.17.\n" .
+ "\tLocal function references are disabled.\n";
+ open (QUIET, ">$quiet_recordmcount");
+ printf QUIET "Disables the warning from recordmcount.pl\n";
+ close QUIET;
+ }
+}
if ($arch eq "x86") {
if ($bits == 64) {
@@ -157,7 +206,8 @@ if ($arch eq "x86") {
# We base the defaults off of i386, the other archs may
# feel free to change them in the below if statements.
#
-$nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
+$local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
+$weak_regex = "^[0-9a-fA-F]+\\s+([wW])\\s+(\\S+)";
$section_regex = "Disassembly of section\\s+(\\S+):";
$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
@@ -206,7 +256,7 @@ if ($arch eq "x86_64") {
$cc .= " -m32";
} elsif ($arch eq "powerpc") {
- $nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
+ $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
$function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:";
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$";
@@ -278,44 +328,17 @@ if ($filename =~ m,^(.*)(\.\S),) {
my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s";
my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o";
-#
-# --globalize-symbols came out in 2.17, we must test the version
-# of objcopy, and if it is less than 2.17, then we can not
-# record local functions.
-my $use_locals = 01;
-my $local_warn_once = 0;
-my $found_version = 0;
-
-open (IN, "$objcopy --version |") || die "error running $objcopy";
-while (<IN>) {
- if (/objcopy.*\s(\d+)\.(\d+)/) {
- my $major = $1;
- my $minor = $2;
-
- $found_version = 1;
- if ($major < 2 ||
- ($major == 2 && $minor < 17)) {
- $use_locals = 0;
- }
- last;
- }
-}
-close (IN);
-
-if (!$found_version) {
- print STDERR "WARNING: could not find objcopy version.\n" .
- "\tDisabling local function references.\n";
-}
+check_objcopy();
#
# Step 1: find all the local (static functions) and weak symbols.
-# 't' is local, 'w/W' is weak (we never use a weak function)
+# 't' is local, 'w/W' is weak
#
open (IN, "$nm $inputfile|") || die "error running $nm";
while (<IN>) {
- if (/$nm_regex/) {
+ if (/$local_regex/) {
$locals{$1} = 1;
- } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) {
+ } elsif (/$weak_regex/) {
$weak{$2} = $1;
}
}
@@ -333,26 +356,20 @@ my $offset = 0; # offset of ref_func to section beginning
#
sub update_funcs
{
- return if ($#offsets < 0);
-
- defined($ref_func) || die "No function to reference";
+ return unless ($ref_func and @offsets);
- # A section only had a weak function, to represent it.
- # Unfortunately, a weak function may be overwritten by another
- # function of the same name, making all these offsets incorrect.
- # To be safe, we simply print a warning and bail.
+ # Sanity check on weak function. A weak function may be overwritten by
+ # another function of the same name, making all these offsets incorrect.
if (defined $weak{$ref_func}) {
- print STDERR
- "$inputfile: WARNING: referencing weak function" .
+ die "$inputfile: ERROR: referencing weak function" .
" $ref_func for mcount\n";
- return;
}
# is this function static? If so, note this fact.
if (defined $locals{$ref_func}) {
# only use locals if objcopy supports globalize-symbols
- if (!$use_locals) {
+ if (!$can_use_local) {
return;
}
$convert{$ref_func} = 1;
@@ -378,9 +395,27 @@ open(IN, "$objdump -hdr $inputfile|") || die "error running $objdump";
my $text;
+
+# read headers first
my $read_headers = 1;
while (<IN>) {
+
+ if ($read_headers && /$mcount_section/) {
+ #
+ # Somehow the make process can execute this script on an
+ # object twice. If it does, we would duplicate the mcount
+ # section and it will cause the function tracer self test
+ # to fail. Check if the mcount section exists, and if it does,
+ # warn and exit.
+ #
+ print STDERR "ERROR: $mcount_section already in $inputfile\n" .
+ "\tThis may be an indication that your build is corrupted.\n" .
+ "\tDelete $inputfile and try again. If the same object file\n" .
+ "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
+ exit(-1);
+ }
+
# is it a section?
if (/$section_regex/) {
$read_headers = 0;
@@ -392,7 +427,7 @@ while (<IN>) {
$read_function = 0;
}
# print out any recorded offsets
- update_funcs() if (defined($ref_func));
+ update_funcs();
# reset all markers and arrays
$text_found = 0;
@@ -421,21 +456,7 @@ while (<IN>) {
$offset = hex $1;
}
}
- } elsif ($read_headers && /$mcount_section/) {
- #
- # Somehow the make process can execute this script on an
- # object twice. If it does, we would duplicate the mcount
- # section and it will cause the function tracer self test
- # to fail. Check if the mcount section exists, and if it does,
- # warn and exit.
- #
- print STDERR "ERROR: $mcount_section already in $inputfile\n" .
- "\tThis may be an indication that your build is corrupted.\n" .
- "\tDelete $inputfile and try again. If the same object file\n" .
- "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
- exit(-1);
}
-
# is this a call site to mcount? If so, record it to print later
if ($text_found && /$mcount_regex/) {
$offsets[$#offsets + 1] = hex $1;
@@ -443,7 +464,7 @@ while (<IN>) {
}
# dump out anymore offsets that may have been found
-update_funcs() if (defined($ref_func));
+update_funcs();
# If we did not find any mcount callers, we are done (do nothing).
if (!$opened) {
diff --git a/scripts/selinux/Makefile b/scripts/selinux/Makefile
index ca4b1ec01822..e8049da1831f 100644
--- a/scripts/selinux/Makefile
+++ b/scripts/selinux/Makefile
@@ -1,2 +1,2 @@
-subdir-y := mdp
-subdir- += mdp
+subdir-y := mdp genheaders
+subdir- += mdp genheaders
diff --git a/scripts/selinux/genheaders/.gitignore b/scripts/selinux/genheaders/.gitignore
new file mode 100644
index 000000000000..4c0b646ff8d5
--- /dev/null
+++ b/scripts/selinux/genheaders/.gitignore
@@ -0,0 +1 @@
+genheaders
diff --git a/scripts/selinux/genheaders/Makefile b/scripts/selinux/genheaders/Makefile
new file mode 100644
index 000000000000..417b165008ee
--- /dev/null
+++ b/scripts/selinux/genheaders/Makefile
@@ -0,0 +1,5 @@
+hostprogs-y := genheaders
+HOST_EXTRACFLAGS += -Isecurity/selinux/include
+
+always := $(hostprogs-y)
+clean-files := $(hostprogs-y)
diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c
new file mode 100644
index 000000000000..24626968055d
--- /dev/null
+++ b/scripts/selinux/genheaders/genheaders.c
@@ -0,0 +1,118 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+struct security_class_mapping {
+ const char *name;
+ const char *perms[sizeof(unsigned) * 8 + 1];
+};
+
+#include "classmap.h"
+#include "initial_sid_to_string.h"
+
+#define max(x, y) (((int)(x) > (int)(y)) ? x : y)
+
+const char *progname;
+
+static void usage(void)
+{
+ printf("usage: %s flask.h av_permissions.h\n", progname);
+ exit(1);
+}
+
+static char *stoupperx(const char *s)
+{
+ char *s2 = strdup(s);
+ char *p;
+
+ if (!s2) {
+ fprintf(stderr, "%s: out of memory\n", progname);
+ exit(3);
+ }
+
+ for (p = s2; *p; p++)
+ *p = toupper(*p);
+ return s2;
+}
+
+int main(int argc, char *argv[])
+{
+ int i, j, k;
+ int isids_len;
+ FILE *fout;
+
+ progname = argv[0];
+
+ if (argc < 3)
+ usage();
+
+ fout = fopen(argv[1], "w");
+ if (!fout) {
+ fprintf(stderr, "Could not open %s for writing: %s\n",
+ argv[1], strerror(errno));
+ exit(2);
+ }
+
+ for (i = 0; secclass_map[i].name; i++) {
+ struct security_class_mapping *map = &secclass_map[i];
+ map->name = stoupperx(map->name);
+ for (j = 0; map->perms[j]; j++)
+ map->perms[j] = stoupperx(map->perms[j]);
+ }
+
+ isids_len = sizeof(initial_sid_to_string) / sizeof (char *);
+ for (i = 1; i < isids_len; i++)
+ initial_sid_to_string[i] = stoupperx(initial_sid_to_string[i]);
+
+ fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
+ fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n");
+
+ for (i = 0; secclass_map[i].name; i++) {
+ struct security_class_mapping *map = &secclass_map[i];
+ fprintf(fout, "#define SECCLASS_%s", map->name);
+ for (j = 0; j < max(1, 40 - strlen(map->name)); j++)
+ fprintf(fout, " ");
+ fprintf(fout, "%2d\n", i+1);
+ }
+
+ fprintf(fout, "\n");
+
+ for (i = 1; i < isids_len; i++) {
+ char *s = initial_sid_to_string[i];
+ fprintf(fout, "#define SECINITSID_%s", s);
+ for (j = 0; j < max(1, 40 - strlen(s)); j++)
+ fprintf(fout, " ");
+ fprintf(fout, "%2d\n", i);
+ }
+ fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1);
+ fprintf(fout, "\n#endif\n");
+ fclose(fout);
+
+ fout = fopen(argv[2], "w");
+ if (!fout) {
+ fprintf(stderr, "Could not open %s for writing: %s\n",
+ argv[2], strerror(errno));
+ exit(4);
+ }
+
+ fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
+ fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n");
+
+ for (i = 0; secclass_map[i].name; i++) {
+ struct security_class_mapping *map = &secclass_map[i];
+ for (j = 0; map->perms[j]; j++) {
+ fprintf(fout, "#define %s__%s", map->name,
+ map->perms[j]);
+ for (k = 0; k < max(1, 40 - strlen(map->name) - strlen(map->perms[j])); k++)
+ fprintf(fout, " ");
+ fprintf(fout, "0x%08xUL\n", (1<<j));
+ }
+ }
+
+ fprintf(fout, "\n#endif\n");
+ fclose(fout);
+ exit(0);
+}
diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
index b4ced8562587..62b34ce1f50d 100644
--- a/scripts/selinux/mdp/mdp.c
+++ b/scripts/selinux/mdp/mdp.c
@@ -29,86 +29,27 @@
#include <unistd.h>
#include <string.h>
-#include "flask.h"
-
static void usage(char *name)
{
printf("usage: %s [-m] policy_file context_file\n", name);
exit(1);
}
-static void find_common_name(char *cname, char *dest, int len)
-{
- char *start, *end;
-
- start = strchr(cname, '_')+1;
- end = strchr(start, '_');
- if (!start || !end || start-cname > len || end-start > len) {
- printf("Error with commons defines\n");
- exit(1);
- }
- strncpy(dest, start, end-start);
- dest[end-start] = '\0';
-}
-
-#define S_(x) x,
-static char *classlist[] = {
-#include "class_to_string.h"
- NULL
+/* Class/perm mapping support */
+struct security_class_mapping {
+ const char *name;
+ const char *perms[sizeof(unsigned) * 8 + 1];
};
-#undef S_
+#include "classmap.h"
#include "initial_sid_to_string.h"
-#define TB_(x) char *x[] = {
-#define TE_(x) NULL };
-#define S_(x) x,
-#include "common_perm_to_string.h"
-#undef TB_
-#undef TE_
-#undef S_
-
-struct common {
- char *cname;
- char **perms;
-};
-struct common common[] = {
-#define TB_(x) { #x, x },
-#define S_(x)
-#define TE_(x)
-#include "common_perm_to_string.h"
-#undef TB_
-#undef TE_
-#undef S_
-};
-
-#define S_(x, y, z) {x, #y},
-struct av_inherit {
- int class;
- char *common;
-};
-struct av_inherit av_inherit[] = {
-#include "av_inherit.h"
-};
-#undef S_
-
-#include "av_permissions.h"
-#define S_(x, y, z) {x, y, z},
-struct av_perms {
- int class;
- int perm_i;
- char *perm_s;
-};
-struct av_perms av_perms[] = {
-#include "av_perm_to_string.h"
-};
-#undef S_
-
int main(int argc, char *argv[])
{
int i, j, mls = 0;
+ int initial_sid_to_string_len;
char **arg, *polout, *ctxout;
- int classlist_len, initial_sid_to_string_len;
+
FILE *fout;
if (argc < 3)
@@ -127,64 +68,25 @@ int main(int argc, char *argv[])
usage(argv[0]);
}
- classlist_len = sizeof(classlist) / sizeof(char *);
/* print out the classes */
- for (i=1; i < classlist_len; i++) {
- if(classlist[i])
- fprintf(fout, "class %s\n", classlist[i]);
- else
- fprintf(fout, "class user%d\n", i);
- }
+ for (i = 0; secclass_map[i].name; i++)
+ fprintf(fout, "class %s\n", secclass_map[i].name);
fprintf(fout, "\n");
initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
/* print out the sids */
- for (i=1; i < initial_sid_to_string_len; i++)
+ for (i = 1; i < initial_sid_to_string_len; i++)
fprintf(fout, "sid %s\n", initial_sid_to_string[i]);
fprintf(fout, "\n");
- /* print out the commons */
- for (i=0; i< sizeof(common)/sizeof(struct common); i++) {
- char cname[101];
- find_common_name(common[i].cname, cname, 100);
- cname[100] = '\0';
- fprintf(fout, "common %s\n{\n", cname);
- for (j=0; common[i].perms[j]; j++)
- fprintf(fout, "\t%s\n", common[i].perms[j]);
- fprintf(fout, "}\n\n");
- }
- fprintf(fout, "\n");
-
/* print out the class permissions */
- for (i=1; i < classlist_len; i++) {
- if (classlist[i]) {
- int firstperm = -1, numperms = 0;
-
- fprintf(fout, "class %s\n", classlist[i]);
- /* does it inherit from a common? */
- for (j=0; j < sizeof(av_inherit)/sizeof(struct av_inherit); j++)
- if (av_inherit[j].class == i)
- fprintf(fout, "inherits %s\n", av_inherit[j].common);
-
- for (j=0; j < sizeof(av_perms)/sizeof(struct av_perms); j++) {
- if (av_perms[j].class == i) {
- if (firstperm == -1)
- firstperm = j;
- numperms++;
- }
- }
- if (!numperms) {
- fprintf(fout, "\n");
- continue;
- }
-
- fprintf(fout, "{\n");
- /* print out the av_perms */
- for (j=0; j < numperms; j++) {
- fprintf(fout, "\t%s\n", av_perms[firstperm+j].perm_s);
- }
- fprintf(fout, "}\n\n");
- }
+ for (i = 0; secclass_map[i].name; i++) {
+ struct security_class_mapping *map = &secclass_map[i];
+ fprintf(fout, "class %s\n", map->name);
+ fprintf(fout, "{\n");
+ for (j = 0; map->perms[j]; j++)
+ fprintf(fout, "\t%s\n", map->perms[j]);
+ fprintf(fout, "}\n\n");
}
fprintf(fout, "\n");
@@ -197,31 +99,34 @@ int main(int argc, char *argv[])
/* types, roles, and allows */
fprintf(fout, "type base_t;\n");
fprintf(fout, "role base_r types { base_t };\n");
- for (i=1; i < classlist_len; i++) {
- if (classlist[i])
- fprintf(fout, "allow base_t base_t:%s *;\n", classlist[i]);
- else
- fprintf(fout, "allow base_t base_t:user%d *;\n", i);
- }
+ for (i = 0; secclass_map[i].name; i++)
+ fprintf(fout, "allow base_t base_t:%s *;\n",
+ secclass_map[i].name);
fprintf(fout, "user user_u roles { base_r };\n");
fprintf(fout, "\n");
/* default sids */
- for (i=1; i < initial_sid_to_string_len; i++)
+ for (i = 1; i < initial_sid_to_string_len; i++)
fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]);
fprintf(fout, "\n");
-
fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n");
fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n");
+ fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n");
fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n");
fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n");
fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
+ fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n");
+ fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n");
+ fprintf(fout, "fs_use_xattr lustre user_u:base_r:base_t;\n");
+ fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n");
fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n");
+ fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n");
fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n");
+ fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n");
fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
diff --git a/security/Kconfig b/security/Kconfig
index fb363cd81cf6..226b9556b25f 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -91,28 +91,6 @@ config SECURITY_PATH
implement pathname based access controls.
If you are unsure how to answer this question, answer N.
-config SECURITY_FILE_CAPABILITIES
- bool "File POSIX Capabilities"
- default n
- help
- This enables filesystem capabilities, allowing you to give
- binaries a subset of root's powers without using setuid 0.
-
- If in doubt, answer N.
-
-config SECURITY_ROOTPLUG
- bool "Root Plug Support"
- depends on USB=y && SECURITY
- help
- This is a sample LSM module that should only be used as such.
- It prevents any programs running with egid == 0 if a specific
- USB device is not present in the system.
-
- See <http://www.linuxjournal.com/article.php?sid=6279> for
- more information about this module.
-
- If you are unsure how to answer this question, answer N.
-
config INTEL_TXT
bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
depends on HAVE_INTEL_TXT
@@ -165,5 +143,37 @@ source security/tomoyo/Kconfig
source security/integrity/ima/Kconfig
+choice
+ prompt "Default security module"
+ default DEFAULT_SECURITY_SELINUX if SECURITY_SELINUX
+ default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
+ default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
+ default DEFAULT_SECURITY_DAC
+
+ help
+ Select the security module that will be used by default if the
+ kernel parameter security= is not specified.
+
+ config DEFAULT_SECURITY_SELINUX
+ bool "SELinux" if SECURITY_SELINUX=y
+
+ config DEFAULT_SECURITY_SMACK
+ bool "Simplified Mandatory Access Control" if SECURITY_SMACK=y
+
+ config DEFAULT_SECURITY_TOMOYO
+ bool "TOMOYO" if SECURITY_TOMOYO=y
+
+ config DEFAULT_SECURITY_DAC
+ bool "Unix Discretionary Access Controls"
+
+endchoice
+
+config DEFAULT_SECURITY
+ string
+ default "selinux" if DEFAULT_SECURITY_SELINUX
+ default "smack" if DEFAULT_SECURITY_SMACK
+ default "tomoyo" if DEFAULT_SECURITY_TOMOYO
+ default "" if DEFAULT_SECURITY_DAC
+
endmenu
diff --git a/security/Makefile b/security/Makefile
index 95ecc06392d7..bb44e350c618 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
obj-$(CONFIG_AUDIT) += lsm_audit.o
obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
-obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
# Object integrity file lists
diff --git a/security/capability.c b/security/capability.c
index fce07a7bc825..5c700e1a4fd3 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -308,6 +308,22 @@ static int cap_path_truncate(struct path *path, loff_t length,
{
return 0;
}
+
+static int cap_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
+ mode_t mode)
+{
+ return 0;
+}
+
+static int cap_path_chown(struct path *path, uid_t uid, gid_t gid)
+{
+ return 0;
+}
+
+static int cap_path_chroot(struct path *root)
+{
+ return 0;
+}
#endif
static int cap_file_permission(struct file *file, int mask)
@@ -405,7 +421,7 @@ static int cap_kernel_create_files_as(struct cred *new, struct inode *inode)
return 0;
}
-static int cap_kernel_module_request(void)
+static int cap_kernel_module_request(char *kmod_name)
{
return 0;
}
@@ -977,6 +993,9 @@ void security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null(ops, path_link);
set_to_cap_if_null(ops, path_rename);
set_to_cap_if_null(ops, path_truncate);
+ set_to_cap_if_null(ops, path_chmod);
+ set_to_cap_if_null(ops, path_chown);
+ set_to_cap_if_null(ops, path_chroot);
#endif
set_to_cap_if_null(ops, file_permission);
set_to_cap_if_null(ops, file_alloc_security);
diff --git a/security/commoncap.c b/security/commoncap.c
index fe30751a6cd9..f800fdb3de94 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -1,4 +1,4 @@
-/* Common capabilities, needed by capability.o and root_plug.o
+/* Common capabilities, needed by capability.o.
*
* 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
@@ -173,7 +173,6 @@ int cap_capget(struct task_struct *target, kernel_cap_t *effective,
*/
static inline int cap_inh_is_capped(void)
{
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
/* they are so limited unless the current task has the CAP_SETPCAP
* capability
@@ -181,7 +180,6 @@ static inline int cap_inh_is_capped(void)
if (cap_capable(current, current_cred(), CAP_SETPCAP,
SECURITY_CAP_AUDIT) == 0)
return 0;
-#endif
return 1;
}
@@ -239,8 +237,6 @@ static inline void bprm_clear_caps(struct linux_binprm *bprm)
bprm->cap_effective = false;
}
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
-
/**
* cap_inode_need_killpriv - Determine if inode change affects privileges
* @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV
@@ -421,49 +417,6 @@ out:
return rc;
}
-#else
-int cap_inode_need_killpriv(struct dentry *dentry)
-{
- return 0;
-}
-
-int cap_inode_killpriv(struct dentry *dentry)
-{
- return 0;
-}
-
-int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps)
-{
- memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));
- return -ENODATA;
-}
-
-static inline int get_file_caps(struct linux_binprm *bprm, bool *effective)
-{
- bprm_clear_caps(bprm);
- return 0;
-}
-#endif
-
-/*
- * Determine whether a exec'ing process's new permitted capabilities should be
- * limited to just what it already has.
- *
- * This prevents processes that are being ptraced from gaining access to
- * CAP_SETPCAP, unless the process they're tracing already has it, and the
- * binary they're executing has filecaps that elevate it.
- *
- * Returns 1 if they should be limited, 0 if they are not.
- */
-static inline int cap_limit_ptraced_target(void)
-{
-#ifndef CONFIG_SECURITY_FILE_CAPABILITIES
- if (capable(CAP_SETPCAP))
- return 0;
-#endif
- return 1;
-}
-
/**
* cap_bprm_set_creds - Set up the proposed credentials for execve().
* @bprm: The execution parameters, including the proposed creds
@@ -523,9 +476,8 @@ skip:
new->euid = new->uid;
new->egid = new->gid;
}
- if (cap_limit_ptraced_target())
- new->cap_permitted = cap_intersect(new->cap_permitted,
- old->cap_permitted);
+ new->cap_permitted = cap_intersect(new->cap_permitted,
+ old->cap_permitted);
}
new->suid = new->fsuid = new->euid;
@@ -739,7 +691,6 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags)
return 0;
}
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
/*
* Rationale: code calling task_setscheduler, task_setioprio, and
* task_setnice, assumes that
@@ -820,22 +771,6 @@ static long cap_prctl_drop(struct cred *new, unsigned long cap)
return 0;
}
-#else
-int cap_task_setscheduler (struct task_struct *p, int policy,
- struct sched_param *lp)
-{
- return 0;
-}
-int cap_task_setioprio (struct task_struct *p, int ioprio)
-{
- return 0;
-}
-int cap_task_setnice (struct task_struct *p, int nice)
-{
- return 0;
-}
-#endif
-
/**
* cap_task_prctl - Implement process control functions for this security module
* @option: The process control function requested
@@ -866,7 +801,6 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
error = !!cap_raised(new->cap_bset, arg2);
goto no_change;
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
case PR_CAPBSET_DROP:
error = cap_prctl_drop(new, arg2);
if (error < 0)
@@ -917,8 +851,6 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
error = new->securebits;
goto no_change;
-#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
-
case PR_GET_KEEPCAPS:
if (issecure(SECURE_KEEP_CAPS))
error = 1;
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 53d9764e8f09..3d7846de8069 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -3,6 +3,7 @@
config IMA
bool "Integrity Measurement Architecture(IMA)"
depends on ACPI
+ depends on SECURITY
select SECURITYFS
select CRYPTO
select CRYPTO_HMAC
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index b8dd693f8790..a4e2b1dac943 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -58,11 +58,11 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode)
if (!ima_initialized)
return iint;
- iint = kmem_cache_alloc(iint_cache, GFP_KERNEL);
+ iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
if (!iint)
return iint;
- rc = radix_tree_preload(GFP_KERNEL);
+ rc = radix_tree_preload(GFP_NOFS);
if (rc < 0)
goto out;
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 2fb28efc5326..06ec722897be 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -873,7 +873,7 @@ static long get_instantiation_keyring(key_serial_t ringid,
/* otherwise specify the destination keyring recorded in the
* authorisation key (any KEY_SPEC_*_KEYRING) */
if (ringid >= KEY_SPEC_REQUESTOR_KEYRING) {
- *_dest_keyring = rka->dest_keyring;
+ *_dest_keyring = key_get(rka->dest_keyring);
return 0;
}
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 3bb90b6f1dd3..51bd0fd9c9f0 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -354,6 +354,10 @@ static void dump_common_audit_data(struct audit_buffer *ab,
}
break;
#endif
+ case LSM_AUDIT_DATA_KMOD:
+ audit_log_format(ab, " kmod=");
+ audit_log_untrustedstring(ab, a->u.kmod_name);
+ break;
} /* switch (a->type) */
}
diff --git a/security/min_addr.c b/security/min_addr.c
index c844eed7915d..fc43c9d37084 100644
--- a/security/min_addr.c
+++ b/security/min_addr.c
@@ -33,6 +33,9 @@ int mmap_min_addr_handler(struct ctl_table *table, int write,
{
int ret;
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
update_mmap_min_addr();
diff --git a/security/root_plug.c b/security/root_plug.c
deleted file mode 100644
index 2f7ffa67c4d2..000000000000
--- a/security/root_plug.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Root Plug sample LSM module
- *
- * Originally written for a Linux Journal.
- *
- * Copyright (C) 2002 Greg Kroah-Hartman <greg@kroah.com>
- *
- * Prevents any programs running with egid == 0 if a specific USB device
- * is not present in the system. Yes, it can be gotten around, but is a
- * nice starting point for people to play with, and learn the LSM
- * interface.
- *
- * If you want to turn this into something with a semblance of security,
- * you need to hook the task_* functions also.
- *
- * See http://www.linuxjournal.com/article.php?sid=6279 for more information
- * about this code.
- *
- * 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 of the
- * License.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/security.h>
-#include <linux/usb.h>
-#include <linux/moduleparam.h>
-
-/* default is a generic type of usb to serial converter */
-static int vendor_id = 0x0557;
-static int product_id = 0x2008;
-
-module_param(vendor_id, uint, 0400);
-module_param(product_id, uint, 0400);
-
-/* should we print out debug messages */
-static int debug = 0;
-
-module_param(debug, bool, 0600);
-
-#define MY_NAME "root_plug"
-
-#define root_dbg(fmt, arg...) \
- do { \
- if (debug) \
- printk(KERN_DEBUG "%s: %s: " fmt , \
- MY_NAME , __func__ , \
- ## arg); \
- } while (0)
-
-static int rootplug_bprm_check_security (struct linux_binprm *bprm)
-{
- struct usb_device *dev;
-
- root_dbg("file %s, e_uid = %d, e_gid = %d\n",
- bprm->filename, bprm->cred->euid, bprm->cred->egid);
-
- if (bprm->cred->egid == 0) {
- dev = usb_find_device(vendor_id, product_id);
- if (!dev) {
- root_dbg("e_gid = 0, and device not found, "
- "task not allowed to run...\n");
- return -EPERM;
- }
- usb_put_dev(dev);
- }
-
- return 0;
-}
-
-static struct security_operations rootplug_security_ops = {
- .bprm_check_security = rootplug_bprm_check_security,
-};
-
-static int __init rootplug_init (void)
-{
- /* register ourselves with the security framework */
- if (register_security (&rootplug_security_ops)) {
- printk (KERN_INFO
- "Failure registering Root Plug module with the kernel\n");
- return -EINVAL;
- }
- printk (KERN_INFO "Root Plug module initialized, "
- "vendor_id = %4.4x, product id = %4.4x\n", vendor_id, product_id);
- return 0;
-}
-
-security_initcall (rootplug_init);
diff --git a/security/security.c b/security/security.c
index c4c673240c1c..24e060be9fa5 100644
--- a/security/security.c
+++ b/security/security.c
@@ -16,9 +16,11 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/security.h>
+#include <linux/ima.h>
/* Boot-time LSM user choice */
-static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1];
+static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
+ CONFIG_DEFAULT_SECURITY;
/* things that live in capability.c */
extern struct security_operations default_security_ops;
@@ -79,8 +81,10 @@ __setup("security=", choose_lsm);
*
* Return true if:
* -The passed LSM is the one chosen by user at boot time,
- * -or user didn't specify a specific LSM and we're the first to ask
- * for registration permission,
+ * -or the passed LSM is configured as the default and the user did not
+ * choose an alternate LSM at boot time,
+ * -or there is no default LSM set and the user didn't specify a
+ * specific LSM and we're the first to ask for registration permission,
* -or the passed LSM is currently loaded.
* Otherwise, return false.
*/
@@ -235,7 +239,12 @@ int security_bprm_set_creds(struct linux_binprm *bprm)
int security_bprm_check(struct linux_binprm *bprm)
{
- return security_ops->bprm_check_security(bprm);
+ int ret;
+
+ ret = security_ops->bprm_check_security(bprm);
+ if (ret)
+ return ret;
+ return ima_bprm_check(bprm);
}
void security_bprm_committing_creds(struct linux_binprm *bprm)
@@ -352,12 +361,21 @@ EXPORT_SYMBOL(security_sb_parse_opts_str);
int security_inode_alloc(struct inode *inode)
{
+ int ret;
+
inode->i_security = NULL;
- return security_ops->inode_alloc_security(inode);
+ ret = security_ops->inode_alloc_security(inode);
+ if (ret)
+ return ret;
+ ret = ima_inode_alloc(inode);
+ if (ret)
+ security_inode_free(inode);
+ return ret;
}
void security_inode_free(struct inode *inode)
{
+ ima_inode_free(inode);
security_ops->inode_free_security(inode);
}
@@ -434,6 +452,26 @@ int security_path_truncate(struct path *path, loff_t length,
return 0;
return security_ops->path_truncate(path, length, time_attrs);
}
+
+int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
+ mode_t mode)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->path_chmod(dentry, mnt, mode);
+}
+
+int security_path_chown(struct path *path, uid_t uid, gid_t gid)
+{
+ if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
+ return 0;
+ return security_ops->path_chown(path, uid, gid);
+}
+
+int security_path_chroot(struct path *path)
+{
+ return security_ops->path_chroot(path);
+}
#endif
int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
@@ -628,6 +666,8 @@ int security_file_alloc(struct file *file)
void security_file_free(struct file *file)
{
security_ops->file_free_security(file);
+ if (file->f_dentry)
+ ima_file_free(file);
}
int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -639,7 +679,12 @@ int security_file_mmap(struct file *file, unsigned long reqprot,
unsigned long prot, unsigned long flags,
unsigned long addr, unsigned long addr_only)
{
- return security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
+ int ret;
+
+ ret = security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
+ if (ret)
+ return ret;
+ return ima_file_mmap(file, prot);
}
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
@@ -719,9 +764,9 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
return security_ops->kernel_create_files_as(new, inode);
}
-int security_kernel_module_request(void)
+int security_kernel_module_request(char *kmod_name)
{
- return security_ops->kernel_module_request();
+ return security_ops->kernel_module_request(kmod_name);
}
int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
diff --git a/security/selinux/.gitignore b/security/selinux/.gitignore
new file mode 100644
index 000000000000..2e5040a3d48b
--- /dev/null
+++ b/security/selinux/.gitignore
@@ -0,0 +1,2 @@
+av_permissions.h
+flask.h
diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index d47fc5e545e0..f013982df417 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -18,5 +18,13 @@ selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
selinux-$(CONFIG_NETLABEL) += netlabel.o
-EXTRA_CFLAGS += -Isecurity/selinux/include
+EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
+$(obj)/avc.o: $(obj)/flask.h
+
+quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h
+ cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h
+
+targets += flask.h
+$(obj)/flask.h: $(src)/include/classmap.h FORCE
+ $(call if_changed,flask)
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index b4b5da1c0a42..f2dde268165a 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -31,43 +31,7 @@
#include <net/ipv6.h>
#include "avc.h"
#include "avc_ss.h"
-
-static const struct av_perm_to_string av_perm_to_string[] = {
-#define S_(c, v, s) { c, v, s },
-#include "av_perm_to_string.h"
-#undef S_
-};
-
-static const char *class_to_string[] = {
-#define S_(s) s,
-#include "class_to_string.h"
-#undef S_
-};
-
-#define TB_(s) static const char *s[] = {
-#define TE_(s) };
-#define S_(s) s,
-#include "common_perm_to_string.h"
-#undef TB_
-#undef TE_
-#undef S_
-
-static const struct av_inherit av_inherit[] = {
-#define S_(c, i, b) { .tclass = c,\
- .common_pts = common_##i##_perm_to_string,\
- .common_base = b },
-#include "av_inherit.h"
-#undef S_
-};
-
-const struct selinux_class_perm selinux_class_perm = {
- .av_perm_to_string = av_perm_to_string,
- .av_pts_len = ARRAY_SIZE(av_perm_to_string),
- .class_to_string = class_to_string,
- .cts_len = ARRAY_SIZE(class_to_string),
- .av_inherit = av_inherit,
- .av_inherit_len = ARRAY_SIZE(av_inherit)
-};
+#include "classmap.h"
#define AVC_CACHE_SLOTS 512
#define AVC_DEF_CACHE_THRESHOLD 512
@@ -139,52 +103,28 @@ static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
*/
static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
{
- const char **common_pts = NULL;
- u32 common_base = 0;
- int i, i2, perm;
+ const char **perms;
+ int i, perm;
if (av == 0) {
audit_log_format(ab, " null");
return;
}
- for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
- if (av_inherit[i].tclass == tclass) {
- common_pts = av_inherit[i].common_pts;
- common_base = av_inherit[i].common_base;
- break;
- }
- }
+ perms = secclass_map[tclass-1].perms;
audit_log_format(ab, " {");
i = 0;
perm = 1;
- while (perm < common_base) {
- if (perm & av) {
- audit_log_format(ab, " %s", common_pts[i]);
+ while (i < (sizeof(av) * 8)) {
+ if ((perm & av) && perms[i]) {
+ audit_log_format(ab, " %s", perms[i]);
av &= ~perm;
}
i++;
perm <<= 1;
}
- while (i < sizeof(av) * 8) {
- if (perm & av) {
- for (i2 = 0; i2 < ARRAY_SIZE(av_perm_to_string); i2++) {
- if ((av_perm_to_string[i2].tclass == tclass) &&
- (av_perm_to_string[i2].value == perm))
- break;
- }
- if (i2 < ARRAY_SIZE(av_perm_to_string)) {
- audit_log_format(ab, " %s",
- av_perm_to_string[i2].name);
- av &= ~perm;
- }
- }
- i++;
- perm <<= 1;
- }
-
if (av)
audit_log_format(ab, " 0x%x", av);
@@ -219,8 +159,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
kfree(scontext);
}
- BUG_ON(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass]);
- audit_log_format(ab, " tclass=%s", class_to_string[tclass]);
+ BUG_ON(tclass >= ARRAY_SIZE(secclass_map));
+ audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name);
}
/**
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index bb230d5d7085..c96d63ec4753 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -91,7 +91,6 @@
#define NUM_SEL_MNT_OPTS 5
-extern unsigned int policydb_loaded_version;
extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
extern struct security_operations *security_ops;
@@ -3338,9 +3337,18 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
return 0;
}
-static int selinux_kernel_module_request(void)
+static int selinux_kernel_module_request(char *kmod_name)
{
- return task_has_system(current, SYSTEM__MODULE_REQUEST);
+ u32 sid;
+ struct common_audit_data ad;
+
+ sid = task_sid(current);
+
+ COMMON_AUDIT_DATA_INIT(&ad, KMOD);
+ ad.u.kmod_name = kmod_name;
+
+ return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM,
+ SYSTEM__MODULE_REQUEST, &ad);
}
static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
@@ -4714,10 +4722,7 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
if (err)
return err;
- if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
- err = selinux_nlmsg_perm(sk, skb);
-
- return err;
+ return selinux_nlmsg_perm(sk, skb);
}
static int selinux_netlink_recv(struct sk_buff *skb, int capability)
@@ -5830,12 +5835,12 @@ int selinux_disable(void)
selinux_disabled = 1;
selinux_enabled = 0;
- /* Try to destroy the avc node cache */
- avc_disable();
-
/* Reset security_ops to the secondary module, dummy or capability. */
security_ops = secondary_ops;
+ /* Try to destroy the avc node cache */
+ avc_disable();
+
/* Unregister netfilter hooks. */
selinux_nf_ip_exit();
diff --git a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h
deleted file mode 100644
index abedcd704dae..000000000000
--- a/security/selinux/include/av_inherit.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This file is automatically generated. Do not edit. */
- S_(SECCLASS_DIR, file, 0x00020000UL)
- S_(SECCLASS_FILE, file, 0x00020000UL)
- S_(SECCLASS_LNK_FILE, file, 0x00020000UL)
- S_(SECCLASS_CHR_FILE, file, 0x00020000UL)
- S_(SECCLASS_BLK_FILE, file, 0x00020000UL)
- S_(SECCLASS_SOCK_FILE, file, 0x00020000UL)
- S_(SECCLASS_FIFO_FILE, file, 0x00020000UL)
- S_(SECCLASS_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_TCP_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_UDP_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_RAWIP_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_PACKET_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_TUN_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_IPC, ipc, 0x00000200UL)
- S_(SECCLASS_SEM, ipc, 0x00000200UL)
- S_(SECCLASS_MSGQ, ipc, 0x00000200UL)
- S_(SECCLASS_SHM, ipc, 0x00000200UL)
- S_(SECCLASS_NETLINK_ROUTE_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_FIREWALL_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_NFLOG_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_XFRM_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_SELINUX_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_AUDIT_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_IP6FW_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_DNRT_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_APPLETALK_SOCKET, socket, 0x00400000UL)
- S_(SECCLASS_DCCP_SOCKET, socket, 0x00400000UL)
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
deleted file mode 100644
index 2b683ad83d21..000000000000
--- a/security/selinux/include/av_perm_to_string.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/* This file is automatically generated. Do not edit. */
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__MOUNT, "mount")
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__REMOUNT, "remount")
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__UNMOUNT, "unmount")
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__GETATTR, "getattr")
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELFROM, "relabelfrom")
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELTO, "relabelto")
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__TRANSITION, "transition")
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__ASSOCIATE, "associate")
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAMOD, "quotamod")
- S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAGET, "quotaget")
- S_(SECCLASS_DIR, DIR__ADD_NAME, "add_name")
- S_(SECCLASS_DIR, DIR__REMOVE_NAME, "remove_name")
- S_(SECCLASS_DIR, DIR__REPARENT, "reparent")
- S_(SECCLASS_DIR, DIR__SEARCH, "search")
- S_(SECCLASS_DIR, DIR__RMDIR, "rmdir")
- S_(SECCLASS_DIR, DIR__OPEN, "open")
- S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans")
- S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint")
- S_(SECCLASS_FILE, FILE__EXECMOD, "execmod")
- S_(SECCLASS_FILE, FILE__OPEN, "open")
- S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans")
- S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint")
- S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod")
- S_(SECCLASS_CHR_FILE, CHR_FILE__OPEN, "open")
- S_(SECCLASS_BLK_FILE, BLK_FILE__OPEN, "open")
- S_(SECCLASS_SOCK_FILE, SOCK_FILE__OPEN, "open")
- S_(SECCLASS_FIFO_FILE, FIFO_FILE__OPEN, "open")
- S_(SECCLASS_FD, FD__USE, "use")
- S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto")
- S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn")
- S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__ACCEPTFROM, "acceptfrom")
- S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind")
- S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NAME_CONNECT, "name_connect")
- S_(SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind")
- S_(SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind")
- S_(SECCLASS_NODE, NODE__TCP_RECV, "tcp_recv")
- S_(SECCLASS_NODE, NODE__TCP_SEND, "tcp_send")
- S_(SECCLASS_NODE, NODE__UDP_RECV, "udp_recv")
- S_(SECCLASS_NODE, NODE__UDP_SEND, "udp_send")
- S_(SECCLASS_NODE, NODE__RAWIP_RECV, "rawip_recv")
- S_(SECCLASS_NODE, NODE__RAWIP_SEND, "rawip_send")
- S_(SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest")
- S_(SECCLASS_NODE, NODE__DCCP_RECV, "dccp_recv")
- S_(SECCLASS_NODE, NODE__DCCP_SEND, "dccp_send")
- S_(SECCLASS_NODE, NODE__RECVFROM, "recvfrom")
- S_(SECCLASS_NODE, NODE__SENDTO, "sendto")
- S_(SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv")
- S_(SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send")
- S_(SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv")
- S_(SECCLASS_NETIF, NETIF__UDP_SEND, "udp_send")
- S_(SECCLASS_NETIF, NETIF__RAWIP_RECV, "rawip_recv")
- S_(SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send")
- S_(SECCLASS_NETIF, NETIF__DCCP_RECV, "dccp_recv")
- S_(SECCLASS_NETIF, NETIF__DCCP_SEND, "dccp_send")
- S_(SECCLASS_NETIF, NETIF__INGRESS, "ingress")
- S_(SECCLASS_NETIF, NETIF__EGRESS, "egress")
- S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto")
- S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn")
- S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom")
- S_(SECCLASS_PROCESS, PROCESS__FORK, "fork")
- S_(SECCLASS_PROCESS, PROCESS__TRANSITION, "transition")
- S_(SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld")
- S_(SECCLASS_PROCESS, PROCESS__SIGKILL, "sigkill")
- S_(SECCLASS_PROCESS, PROCESS__SIGSTOP, "sigstop")
- S_(SECCLASS_PROCESS, PROCESS__SIGNULL, "signull")
- S_(SECCLASS_PROCESS, PROCESS__SIGNAL, "signal")
- S_(SECCLASS_PROCESS, PROCESS__PTRACE, "ptrace")
- S_(SECCLASS_PROCESS, PROCESS__GETSCHED, "getsched")
- S_(SECCLASS_PROCESS, PROCESS__SETSCHED, "setsched")
- S_(SECCLASS_PROCESS, PROCESS__GETSESSION, "getsession")
- S_(SECCLASS_PROCESS, PROCESS__GETPGID, "getpgid")
- S_(SECCLASS_PROCESS, PROCESS__SETPGID, "setpgid")
- S_(SECCLASS_PROCESS, PROCESS__GETCAP, "getcap")
- S_(SECCLASS_PROCESS, PROCESS__SETCAP, "setcap")
- S_(SECCLASS_PROCESS, PROCESS__SHARE, "share")
- S_(SECCLASS_PROCESS, PROCESS__GETATTR, "getattr")
- S_(SECCLASS_PROCESS, PROCESS__SETEXEC, "setexec")
- S_(SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate")
- S_(SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure")
- S_(SECCLASS_PROCESS, PROCESS__SIGINH, "siginh")
- S_(SECCLASS_PROCESS, PROCESS__SETRLIMIT, "setrlimit")
- S_(SECCLASS_PROCESS, PROCESS__RLIMITINH, "rlimitinh")
- S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition")
- S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent")
- S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem")
- S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack")
- S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap")
- S_(SECCLASS_PROCESS, PROCESS__SETKEYCREATE, "setkeycreate")
- S_(SECCLASS_PROCESS, PROCESS__SETSOCKCREATE, "setsockcreate")
- S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
- S_(SECCLASS_MSG, MSG__SEND, "send")
- S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
- S_(SECCLASS_SHM, SHM__LOCK, "lock")
- S_(SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av")
- S_(SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE, "compute_create")
- S_(SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER, "compute_member")
- S_(SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, "check_context")
- S_(SECCLASS_SECURITY, SECURITY__LOAD_POLICY, "load_policy")
- S_(SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL, "compute_relabel")
- S_(SECCLASS_SECURITY, SECURITY__COMPUTE_USER, "compute_user")
- S_(SECCLASS_SECURITY, SECURITY__SETENFORCE, "setenforce")
- S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool")
- S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam")
- S_(SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT, "setcheckreqprot")
- S_(SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info")
- S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read")
- S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod")
- S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console")
- S_(SECCLASS_SYSTEM, SYSTEM__MODULE_REQUEST, "module_request")
- S_(SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown")
- S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override")
- S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search")
- S_(SECCLASS_CAPABILITY, CAPABILITY__FOWNER, "fowner")
- S_(SECCLASS_CAPABILITY, CAPABILITY__FSETID, "fsetid")
- S_(SECCLASS_CAPABILITY, CAPABILITY__KILL, "kill")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SETGID, "setgid")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SETUID, "setuid")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SETPCAP, "setpcap")
- S_(SECCLASS_CAPABILITY, CAPABILITY__LINUX_IMMUTABLE, "linux_immutable")
- S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BIND_SERVICE, "net_bind_service")
- S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BROADCAST, "net_broadcast")
- S_(SECCLASS_CAPABILITY, CAPABILITY__NET_ADMIN, "net_admin")
- S_(SECCLASS_CAPABILITY, CAPABILITY__NET_RAW, "net_raw")
- S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_LOCK, "ipc_lock")
- S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_OWNER, "ipc_owner")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_MODULE, "sys_module")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RAWIO, "sys_rawio")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_CHROOT, "sys_chroot")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PTRACE, "sys_ptrace")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PACCT, "sys_pacct")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_ADMIN, "sys_admin")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_BOOT, "sys_boot")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_NICE, "sys_nice")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RESOURCE, "sys_resource")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TIME, "sys_time")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TTY_CONFIG, "sys_tty_config")
- S_(SECCLASS_CAPABILITY, CAPABILITY__MKNOD, "mknod")
- S_(SECCLASS_CAPABILITY, CAPABILITY__LEASE, "lease")
- S_(SECCLASS_CAPABILITY, CAPABILITY__AUDIT_WRITE, "audit_write")
- S_(SECCLASS_CAPABILITY, CAPABILITY__AUDIT_CONTROL, "audit_control")
- S_(SECCLASS_CAPABILITY, CAPABILITY__SETFCAP, "setfcap")
- S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_OVERRIDE, "mac_override")
- S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_ADMIN, "mac_admin")
- S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_READ, "nlmsg_read")
- S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE, "nlmsg_write")
- S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_READ, "nlmsg_read")
- S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE, "nlmsg_write")
- S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_READ, "nlmsg_read")
- S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE, "nlmsg_write")
- S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_READ, "nlmsg_read")
- S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write")
- S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read")
- S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write")
- S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_RELAY, "nlmsg_relay")
- S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV, "nlmsg_readpriv")
- S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT, "nlmsg_tty_audit")
- S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read")
- S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write")
- S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto")
- S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom")
- S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext")
- S_(SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, "polmatch")
- S_(SECCLASS_PACKET, PACKET__SEND, "send")
- S_(SECCLASS_PACKET, PACKET__RECV, "recv")
- S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto")
- S_(SECCLASS_PACKET, PACKET__FLOW_IN, "flow_in")
- S_(SECCLASS_PACKET, PACKET__FLOW_OUT, "flow_out")
- S_(SECCLASS_PACKET, PACKET__FORWARD_IN, "forward_in")
- S_(SECCLASS_PACKET, PACKET__FORWARD_OUT, "forward_out")
- S_(SECCLASS_KEY, KEY__VIEW, "view")
- S_(SECCLASS_KEY, KEY__READ, "read")
- S_(SECCLASS_KEY, KEY__WRITE, "write")
- S_(SECCLASS_KEY, KEY__SEARCH, "search")
- S_(SECCLASS_KEY, KEY__LINK, "link")
- S_(SECCLASS_KEY, KEY__SETATTR, "setattr")
- S_(SECCLASS_KEY, KEY__CREATE, "create")
- S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
- S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
- S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
- S_(SECCLASS_PEER, PEER__RECV, "recv")
- S_(SECCLASS_KERNEL_SERVICE, KERNEL_SERVICE__USE_AS_OVERRIDE, "use_as_override")
- S_(SECCLASS_KERNEL_SERVICE, KERNEL_SERVICE__CREATE_FILES_AS, "create_files_as")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
deleted file mode 100644
index 0546d616ccac..000000000000
--- a/security/selinux/include/av_permissions.h
+++ /dev/null
@@ -1,870 +0,0 @@
-/* This file is automatically generated. Do not edit. */
-#define COMMON_FILE__IOCTL 0x00000001UL
-#define COMMON_FILE__READ 0x00000002UL
-#define COMMON_FILE__WRITE 0x00000004UL
-#define COMMON_FILE__CREATE 0x00000008UL
-#define COMMON_FILE__GETATTR 0x00000010UL
-#define COMMON_FILE__SETATTR 0x00000020UL
-#define COMMON_FILE__LOCK 0x00000040UL
-#define COMMON_FILE__RELABELFROM 0x00000080UL
-#define COMMON_FILE__RELABELTO 0x00000100UL
-#define COMMON_FILE__APPEND 0x00000200UL
-#define COMMON_FILE__UNLINK 0x00000400UL
-#define COMMON_FILE__LINK 0x00000800UL
-#define COMMON_FILE__RENAME 0x00001000UL
-#define COMMON_FILE__EXECUTE 0x00002000UL
-#define COMMON_FILE__SWAPON 0x00004000UL
-#define COMMON_FILE__QUOTAON 0x00008000UL
-#define COMMON_FILE__MOUNTON 0x00010000UL
-#define COMMON_SOCKET__IOCTL 0x00000001UL
-#define COMMON_SOCKET__READ 0x00000002UL
-#define COMMON_SOCKET__WRITE 0x00000004UL
-#define COMMON_SOCKET__CREATE 0x00000008UL
-#define COMMON_SOCKET__GETATTR 0x00000010UL
-#define COMMON_SOCKET__SETATTR 0x00000020UL
-#define COMMON_SOCKET__LOCK 0x00000040UL
-#define COMMON_SOCKET__RELABELFROM 0x00000080UL
-#define COMMON_SOCKET__RELABELTO 0x00000100UL
-#define COMMON_SOCKET__APPEND 0x00000200UL
-#define COMMON_SOCKET__BIND 0x00000400UL
-#define COMMON_SOCKET__CONNECT 0x00000800UL
-#define COMMON_SOCKET__LISTEN 0x00001000UL
-#define COMMON_SOCKET__ACCEPT 0x00002000UL
-#define COMMON_SOCKET__GETOPT 0x00004000UL
-#define COMMON_SOCKET__SETOPT 0x00008000UL
-#define COMMON_SOCKET__SHUTDOWN 0x00010000UL
-#define COMMON_SOCKET__RECVFROM 0x00020000UL
-#define COMMON_SOCKET__SENDTO 0x00040000UL
-#define COMMON_SOCKET__RECV_MSG 0x00080000UL
-#define COMMON_SOCKET__SEND_MSG 0x00100000UL
-#define COMMON_SOCKET__NAME_BIND 0x00200000UL
-#define COMMON_IPC__CREATE 0x00000001UL
-#define COMMON_IPC__DESTROY 0x00000002UL
-#define COMMON_IPC__GETATTR 0x00000004UL
-#define COMMON_IPC__SETATTR 0x00000008UL
-#define COMMON_IPC__READ 0x00000010UL
-#define COMMON_IPC__WRITE 0x00000020UL
-#define COMMON_IPC__ASSOCIATE 0x00000040UL
-#define COMMON_IPC__UNIX_READ 0x00000080UL
-#define COMMON_IPC__UNIX_WRITE 0x00000100UL
-#define FILESYSTEM__MOUNT 0x00000001UL
-#define FILESYSTEM__REMOUNT 0x00000002UL
-#define FILESYSTEM__UNMOUNT 0x00000004UL
-#define FILESYSTEM__GETATTR 0x00000008UL
-#define FILESYSTEM__RELABELFROM 0x00000010UL
-#define FILESYSTEM__RELABELTO 0x00000020UL
-#define FILESYSTEM__TRANSITION 0x00000040UL
-#define FILESYSTEM__ASSOCIATE 0x00000080UL
-#define FILESYSTEM__QUOTAMOD 0x00000100UL
-#define FILESYSTEM__QUOTAGET 0x00000200UL
-#define DIR__IOCTL 0x00000001UL
-#define DIR__READ 0x00000002UL
-#define DIR__WRITE 0x00000004UL
-#define DIR__CREATE 0x00000008UL
-#define DIR__GETATTR 0x00000010UL
-#define DIR__SETATTR 0x00000020UL
-#define DIR__LOCK 0x00000040UL
-#define DIR__RELABELFROM 0x00000080UL
-#define DIR__RELABELTO 0x00000100UL
-#define DIR__APPEND 0x00000200UL
-#define DIR__UNLINK 0x00000400UL
-#define DIR__LINK 0x00000800UL
-#define DIR__RENAME 0x00001000UL
-#define DIR__EXECUTE 0x00002000UL
-#define DIR__SWAPON 0x00004000UL
-#define DIR__QUOTAON 0x00008000UL
-#define DIR__MOUNTON 0x00010000UL
-#define DIR__ADD_NAME 0x00020000UL
-#define DIR__REMOVE_NAME 0x00040000UL
-#define DIR__REPARENT 0x00080000UL
-#define DIR__SEARCH 0x00100000UL
-#define DIR__RMDIR 0x00200000UL
-#define DIR__OPEN 0x00400000UL
-#define FILE__IOCTL 0x00000001UL
-#define FILE__READ 0x00000002UL
-#define FILE__WRITE 0x00000004UL
-#define FILE__CREATE 0x00000008UL
-#define FILE__GETATTR 0x00000010UL
-#define FILE__SETATTR 0x00000020UL
-#define FILE__LOCK 0x00000040UL
-#define FILE__RELABELFROM 0x00000080UL
-#define FILE__RELABELTO 0x00000100UL
-#define FILE__APPEND 0x00000200UL
-#define FILE__UNLINK 0x00000400UL
-#define FILE__LINK 0x00000800UL
-#define FILE__RENAME 0x00001000UL
-#define FILE__EXECUTE 0x00002000UL
-#define FILE__SWAPON 0x00004000UL
-#define FILE__QUOTAON 0x00008000UL
-#define FILE__MOUNTON 0x00010000UL
-#define FILE__EXECUTE_NO_TRANS 0x00020000UL
-#define FILE__ENTRYPOINT 0x00040000UL
-#define FILE__EXECMOD 0x00080000UL
-#define FILE__OPEN 0x00100000UL
-#define LNK_FILE__IOCTL 0x00000001UL
-#define LNK_FILE__READ 0x00000002UL
-#define LNK_FILE__WRITE 0x00000004UL
-#define LNK_FILE__CREATE 0x00000008UL
-#define LNK_FILE__GETATTR 0x00000010UL
-#define LNK_FILE__SETATTR 0x00000020UL
-#define LNK_FILE__LOCK 0x00000040UL
-#define LNK_FILE__RELABELFROM 0x00000080UL
-#define LNK_FILE__RELABELTO 0x00000100UL
-#define LNK_FILE__APPEND 0x00000200UL
-#define LNK_FILE__UNLINK 0x00000400UL
-#define LNK_FILE__LINK 0x00000800UL
-#define LNK_FILE__RENAME 0x00001000UL
-#define LNK_FILE__EXECUTE 0x00002000UL
-#define LNK_FILE__SWAPON 0x00004000UL
-#define LNK_FILE__QUOTAON 0x00008000UL
-#define LNK_FILE__MOUNTON 0x00010000UL
-#define CHR_FILE__IOCTL 0x00000001UL
-#define CHR_FILE__READ 0x00000002UL
-#define CHR_FILE__WRITE 0x00000004UL
-#define CHR_FILE__CREATE 0x00000008UL
-#define CHR_FILE__GETATTR 0x00000010UL
-#define CHR_FILE__SETATTR 0x00000020UL
-#define CHR_FILE__LOCK 0x00000040UL
-#define CHR_FILE__RELABELFROM 0x00000080UL
-#define CHR_FILE__RELABELTO 0x00000100UL
-#define CHR_FILE__APPEND 0x00000200UL
-#define CHR_FILE__UNLINK 0x00000400UL
-#define CHR_FILE__LINK 0x00000800UL
-#define CHR_FILE__RENAME 0x00001000UL
-#define CHR_FILE__EXECUTE 0x00002000UL
-#define CHR_FILE__SWAPON 0x00004000UL
-#define CHR_FILE__QUOTAON 0x00008000UL
-#define CHR_FILE__MOUNTON 0x00010000UL
-#define CHR_FILE__EXECUTE_NO_TRANS 0x00020000UL
-#define CHR_FILE__ENTRYPOINT 0x00040000UL
-#define CHR_FILE__EXECMOD 0x00080000UL
-#define CHR_FILE__OPEN 0x00100000UL
-#define BLK_FILE__IOCTL 0x00000001UL
-#define BLK_FILE__READ 0x00000002UL
-#define BLK_FILE__WRITE 0x00000004UL
-#define BLK_FILE__CREATE 0x00000008UL
-#define BLK_FILE__GETATTR 0x00000010UL
-#define BLK_FILE__SETATTR 0x00000020UL
-#define BLK_FILE__LOCK 0x00000040UL
-#define BLK_FILE__RELABELFROM 0x00000080UL
-#define BLK_FILE__RELABELTO 0x00000100UL
-#define BLK_FILE__APPEND 0x00000200UL
-#define BLK_FILE__UNLINK 0x00000400UL
-#define BLK_FILE__LINK 0x00000800UL
-#define BLK_FILE__RENAME 0x00001000UL
-#define BLK_FILE__EXECUTE 0x00002000UL
-#define BLK_FILE__SWAPON 0x00004000UL
-#define BLK_FILE__QUOTAON 0x00008000UL
-#define BLK_FILE__MOUNTON 0x00010000UL
-#define BLK_FILE__OPEN 0x00020000UL
-#define SOCK_FILE__IOCTL 0x00000001UL
-#define SOCK_FILE__READ 0x00000002UL
-#define SOCK_FILE__WRITE 0x00000004UL
-#define SOCK_FILE__CREATE 0x00000008UL
-#define SOCK_FILE__GETATTR 0x00000010UL
-#define SOCK_FILE__SETATTR 0x00000020UL
-#define SOCK_FILE__LOCK 0x00000040UL
-#define SOCK_FILE__RELABELFROM 0x00000080UL
-#define SOCK_FILE__RELABELTO 0x00000100UL
-#define SOCK_FILE__APPEND 0x00000200UL
-#define SOCK_FILE__UNLINK 0x00000400UL
-#define SOCK_FILE__LINK 0x00000800UL
-#define SOCK_FILE__RENAME 0x00001000UL
-#define SOCK_FILE__EXECUTE 0x00002000UL
-#define SOCK_FILE__SWAPON 0x00004000UL
-#define SOCK_FILE__QUOTAON 0x00008000UL
-#define SOCK_FILE__MOUNTON 0x00010000UL
-#define SOCK_FILE__OPEN 0x00020000UL
-#define FIFO_FILE__IOCTL 0x00000001UL
-#define FIFO_FILE__READ 0x00000002UL
-#define FIFO_FILE__WRITE 0x00000004UL
-#define FIFO_FILE__CREATE 0x00000008UL
-#define FIFO_FILE__GETATTR 0x00000010UL
-#define FIFO_FILE__SETATTR 0x00000020UL
-#define FIFO_FILE__LOCK 0x00000040UL
-#define FIFO_FILE__RELABELFROM 0x00000080UL
-#define FIFO_FILE__RELABELTO 0x00000100UL
-#define FIFO_FILE__APPEND 0x00000200UL
-#define FIFO_FILE__UNLINK 0x00000400UL
-#define FIFO_FILE__LINK 0x00000800UL
-#define FIFO_FILE__RENAME 0x00001000UL
-#define FIFO_FILE__EXECUTE 0x00002000UL
-#define FIFO_FILE__SWAPON 0x00004000UL
-#define FIFO_FILE__QUOTAON 0x00008000UL
-#define FIFO_FILE__MOUNTON 0x00010000UL
-#define FIFO_FILE__OPEN 0x00020000UL
-#define FD__USE 0x00000001UL
-#define SOCKET__IOCTL 0x00000001UL
-#define SOCKET__READ 0x00000002UL
-#define SOCKET__WRITE 0x00000004UL
-#define SOCKET__CREATE 0x00000008UL
-#define SOCKET__GETATTR 0x00000010UL
-#define SOCKET__SETATTR 0x00000020UL
-#define SOCKET__LOCK 0x00000040UL
-#define SOCKET__RELABELFROM 0x00000080UL
-#define SOCKET__RELABELTO 0x00000100UL
-#define SOCKET__APPEND 0x00000200UL
-#define SOCKET__BIND 0x00000400UL
-#define SOCKET__CONNECT 0x00000800UL
-#define SOCKET__LISTEN 0x00001000UL
-#define SOCKET__ACCEPT 0x00002000UL
-#define SOCKET__GETOPT 0x00004000UL
-#define SOCKET__SETOPT 0x00008000UL
-#define SOCKET__SHUTDOWN 0x00010000UL
-#define SOCKET__RECVFROM 0x00020000UL
-#define SOCKET__SENDTO 0x00040000UL
-#define SOCKET__RECV_MSG 0x00080000UL
-#define SOCKET__SEND_MSG 0x00100000UL
-#define SOCKET__NAME_BIND 0x00200000UL
-#define TCP_SOCKET__IOCTL 0x00000001UL
-#define TCP_SOCKET__READ 0x00000002UL
-#define TCP_SOCKET__WRITE 0x00000004UL
-#define TCP_SOCKET__CREATE 0x00000008UL
-#define TCP_SOCKET__GETATTR 0x00000010UL
-#define TCP_SOCKET__SETATTR 0x00000020UL
-#define TCP_SOCKET__LOCK 0x00000040UL
-#define TCP_SOCKET__RELABELFROM 0x00000080UL
-#define TCP_SOCKET__RELABELTO 0x00000100UL
-#define TCP_SOCKET__APPEND 0x00000200UL
-#define TCP_SOCKET__BIND 0x00000400UL
-#define TCP_SOCKET__CONNECT 0x00000800UL
-#define TCP_SOCKET__LISTEN 0x00001000UL
-#define TCP_SOCKET__ACCEPT 0x00002000UL
-#define TCP_SOCKET__GETOPT 0x00004000UL
-#define TCP_SOCKET__SETOPT 0x00008000UL
-#define TCP_SOCKET__SHUTDOWN 0x00010000UL
-#define TCP_SOCKET__RECVFROM 0x00020000UL
-#define TCP_SOCKET__SENDTO 0x00040000UL
-#define TCP_SOCKET__RECV_MSG 0x00080000UL
-#define TCP_SOCKET__SEND_MSG 0x00100000UL
-#define TCP_SOCKET__NAME_BIND 0x00200000UL
-#define TCP_SOCKET__CONNECTTO 0x00400000UL
-#define TCP_SOCKET__NEWCONN 0x00800000UL
-#define TCP_SOCKET__ACCEPTFROM 0x01000000UL
-#define TCP_SOCKET__NODE_BIND 0x02000000UL
-#define TCP_SOCKET__NAME_CONNECT 0x04000000UL
-#define UDP_SOCKET__IOCTL 0x00000001UL
-#define UDP_SOCKET__READ 0x00000002UL
-#define UDP_SOCKET__WRITE 0x00000004UL
-#define UDP_SOCKET__CREATE 0x00000008UL
-#define UDP_SOCKET__GETATTR 0x00000010UL
-#define UDP_SOCKET__SETATTR 0x00000020UL
-#define UDP_SOCKET__LOCK 0x00000040UL
-#define UDP_SOCKET__RELABELFROM 0x00000080UL
-#define UDP_SOCKET__RELABELTO 0x00000100UL
-#define UDP_SOCKET__APPEND 0x00000200UL
-#define UDP_SOCKET__BIND 0x00000400UL
-#define UDP_SOCKET__CONNECT 0x00000800UL
-#define UDP_SOCKET__LISTEN 0x00001000UL
-#define UDP_SOCKET__ACCEPT 0x00002000UL
-#define UDP_SOCKET__GETOPT 0x00004000UL
-#define UDP_SOCKET__SETOPT 0x00008000UL
-#define UDP_SOCKET__SHUTDOWN 0x00010000UL
-#define UDP_SOCKET__RECVFROM 0x00020000UL
-#define UDP_SOCKET__SENDTO 0x00040000UL
-#define UDP_SOCKET__RECV_MSG 0x00080000UL
-#define UDP_SOCKET__SEND_MSG 0x00100000UL
-#define UDP_SOCKET__NAME_BIND 0x00200000UL
-#define UDP_SOCKET__NODE_BIND 0x00400000UL
-#define RAWIP_SOCKET__IOCTL 0x00000001UL
-#define RAWIP_SOCKET__READ 0x00000002UL
-#define RAWIP_SOCKET__WRITE 0x00000004UL
-#define RAWIP_SOCKET__CREATE 0x00000008UL
-#define RAWIP_SOCKET__GETATTR 0x00000010UL
-#define RAWIP_SOCKET__SETATTR 0x00000020UL
-#define RAWIP_SOCKET__LOCK 0x00000040UL
-#define RAWIP_SOCKET__RELABELFROM 0x00000080UL
-#define RAWIP_SOCKET__RELABELTO 0x00000100UL
-#define RAWIP_SOCKET__APPEND 0x00000200UL
-#define RAWIP_SOCKET__BIND 0x00000400UL
-#define RAWIP_SOCKET__CONNECT 0x00000800UL
-#define RAWIP_SOCKET__LISTEN 0x00001000UL
-#define RAWIP_SOCKET__ACCEPT 0x00002000UL
-#define RAWIP_SOCKET__GETOPT 0x00004000UL
-#define RAWIP_SOCKET__SETOPT 0x00008000UL
-#define RAWIP_SOCKET__SHUTDOWN 0x00010000UL
-#define RAWIP_SOCKET__RECVFROM 0x00020000UL
-#define RAWIP_SOCKET__SENDTO 0x00040000UL
-#define RAWIP_SOCKET__RECV_MSG 0x00080000UL
-#define RAWIP_SOCKET__SEND_MSG 0x00100000UL
-#define RAWIP_SOCKET__NAME_BIND 0x00200000UL
-#define RAWIP_SOCKET__NODE_BIND 0x00400000UL
-#define NODE__TCP_RECV 0x00000001UL
-#define NODE__TCP_SEND 0x00000002UL
-#define NODE__UDP_RECV 0x00000004UL
-#define NODE__UDP_SEND 0x00000008UL
-#define NODE__RAWIP_RECV 0x00000010UL
-#define NODE__RAWIP_SEND 0x00000020UL
-#define NODE__ENFORCE_DEST 0x00000040UL
-#define NODE__DCCP_RECV 0x00000080UL
-#define NODE__DCCP_SEND 0x00000100UL
-#define NODE__RECVFROM 0x00000200UL
-#define NODE__SENDTO 0x00000400UL
-#define NETIF__TCP_RECV 0x00000001UL
-#define NETIF__TCP_SEND 0x00000002UL
-#define NETIF__UDP_RECV 0x00000004UL
-#define NETIF__UDP_SEND 0x00000008UL
-#define NETIF__RAWIP_RECV 0x00000010UL
-#define NETIF__RAWIP_SEND 0x00000020UL
-#define NETIF__DCCP_RECV 0x00000040UL
-#define NETIF__DCCP_SEND 0x00000080UL
-#define NETIF__INGRESS 0x00000100UL
-#define NETIF__EGRESS 0x00000200UL
-#define NETLINK_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_SOCKET__READ 0x00000002UL
-#define NETLINK_SOCKET__WRITE 0x00000004UL
-#define NETLINK_SOCKET__CREATE 0x00000008UL
-#define NETLINK_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_SOCKET__LOCK 0x00000040UL
-#define NETLINK_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_SOCKET__APPEND 0x00000200UL
-#define NETLINK_SOCKET__BIND 0x00000400UL
-#define NETLINK_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_SOCKET__NAME_BIND 0x00200000UL
-#define PACKET_SOCKET__IOCTL 0x00000001UL
-#define PACKET_SOCKET__READ 0x00000002UL
-#define PACKET_SOCKET__WRITE 0x00000004UL
-#define PACKET_SOCKET__CREATE 0x00000008UL
-#define PACKET_SOCKET__GETATTR 0x00000010UL
-#define PACKET_SOCKET__SETATTR 0x00000020UL
-#define PACKET_SOCKET__LOCK 0x00000040UL
-#define PACKET_SOCKET__RELABELFROM 0x00000080UL
-#define PACKET_SOCKET__RELABELTO 0x00000100UL
-#define PACKET_SOCKET__APPEND 0x00000200UL
-#define PACKET_SOCKET__BIND 0x00000400UL
-#define PACKET_SOCKET__CONNECT 0x00000800UL
-#define PACKET_SOCKET__LISTEN 0x00001000UL
-#define PACKET_SOCKET__ACCEPT 0x00002000UL
-#define PACKET_SOCKET__GETOPT 0x00004000UL
-#define PACKET_SOCKET__SETOPT 0x00008000UL
-#define PACKET_SOCKET__SHUTDOWN 0x00010000UL
-#define PACKET_SOCKET__RECVFROM 0x00020000UL
-#define PACKET_SOCKET__SENDTO 0x00040000UL
-#define PACKET_SOCKET__RECV_MSG 0x00080000UL
-#define PACKET_SOCKET__SEND_MSG 0x00100000UL
-#define PACKET_SOCKET__NAME_BIND 0x00200000UL
-#define KEY_SOCKET__IOCTL 0x00000001UL
-#define KEY_SOCKET__READ 0x00000002UL
-#define KEY_SOCKET__WRITE 0x00000004UL
-#define KEY_SOCKET__CREATE 0x00000008UL
-#define KEY_SOCKET__GETATTR 0x00000010UL
-#define KEY_SOCKET__SETATTR 0x00000020UL
-#define KEY_SOCKET__LOCK 0x00000040UL
-#define KEY_SOCKET__RELABELFROM 0x00000080UL
-#define KEY_SOCKET__RELABELTO 0x00000100UL
-#define KEY_SOCKET__APPEND 0x00000200UL
-#define KEY_SOCKET__BIND 0x00000400UL
-#define KEY_SOCKET__CONNECT 0x00000800UL
-#define KEY_SOCKET__LISTEN 0x00001000UL
-#define KEY_SOCKET__ACCEPT 0x00002000UL
-#define KEY_SOCKET__GETOPT 0x00004000UL
-#define KEY_SOCKET__SETOPT 0x00008000UL
-#define KEY_SOCKET__SHUTDOWN 0x00010000UL
-#define KEY_SOCKET__RECVFROM 0x00020000UL
-#define KEY_SOCKET__SENDTO 0x00040000UL
-#define KEY_SOCKET__RECV_MSG 0x00080000UL
-#define KEY_SOCKET__SEND_MSG 0x00100000UL
-#define KEY_SOCKET__NAME_BIND 0x00200000UL
-#define UNIX_STREAM_SOCKET__IOCTL 0x00000001UL
-#define UNIX_STREAM_SOCKET__READ 0x00000002UL
-#define UNIX_STREAM_SOCKET__WRITE 0x00000004UL
-#define UNIX_STREAM_SOCKET__CREATE 0x00000008UL
-#define UNIX_STREAM_SOCKET__GETATTR 0x00000010UL
-#define UNIX_STREAM_SOCKET__SETATTR 0x00000020UL
-#define UNIX_STREAM_SOCKET__LOCK 0x00000040UL
-#define UNIX_STREAM_SOCKET__RELABELFROM 0x00000080UL
-#define UNIX_STREAM_SOCKET__RELABELTO 0x00000100UL
-#define UNIX_STREAM_SOCKET__APPEND 0x00000200UL
-#define UNIX_STREAM_SOCKET__BIND 0x00000400UL
-#define UNIX_STREAM_SOCKET__CONNECT 0x00000800UL
-#define UNIX_STREAM_SOCKET__LISTEN 0x00001000UL
-#define UNIX_STREAM_SOCKET__ACCEPT 0x00002000UL
-#define UNIX_STREAM_SOCKET__GETOPT 0x00004000UL
-#define UNIX_STREAM_SOCKET__SETOPT 0x00008000UL
-#define UNIX_STREAM_SOCKET__SHUTDOWN 0x00010000UL
-#define UNIX_STREAM_SOCKET__RECVFROM 0x00020000UL
-#define UNIX_STREAM_SOCKET__SENDTO 0x00040000UL
-#define UNIX_STREAM_SOCKET__RECV_MSG 0x00080000UL
-#define UNIX_STREAM_SOCKET__SEND_MSG 0x00100000UL
-#define UNIX_STREAM_SOCKET__NAME_BIND 0x00200000UL
-#define UNIX_STREAM_SOCKET__CONNECTTO 0x00400000UL
-#define UNIX_STREAM_SOCKET__NEWCONN 0x00800000UL
-#define UNIX_STREAM_SOCKET__ACCEPTFROM 0x01000000UL
-#define UNIX_DGRAM_SOCKET__IOCTL 0x00000001UL
-#define UNIX_DGRAM_SOCKET__READ 0x00000002UL
-#define UNIX_DGRAM_SOCKET__WRITE 0x00000004UL
-#define UNIX_DGRAM_SOCKET__CREATE 0x00000008UL
-#define UNIX_DGRAM_SOCKET__GETATTR 0x00000010UL
-#define UNIX_DGRAM_SOCKET__SETATTR 0x00000020UL
-#define UNIX_DGRAM_SOCKET__LOCK 0x00000040UL
-#define UNIX_DGRAM_SOCKET__RELABELFROM 0x00000080UL
-#define UNIX_DGRAM_SOCKET__RELABELTO 0x00000100UL
-#define UNIX_DGRAM_SOCKET__APPEND 0x00000200UL
-#define UNIX_DGRAM_SOCKET__BIND 0x00000400UL
-#define UNIX_DGRAM_SOCKET__CONNECT 0x00000800UL
-#define UNIX_DGRAM_SOCKET__LISTEN 0x00001000UL
-#define UNIX_DGRAM_SOCKET__ACCEPT 0x00002000UL
-#define UNIX_DGRAM_SOCKET__GETOPT 0x00004000UL
-#define UNIX_DGRAM_SOCKET__SETOPT 0x00008000UL
-#define UNIX_DGRAM_SOCKET__SHUTDOWN 0x00010000UL
-#define UNIX_DGRAM_SOCKET__RECVFROM 0x00020000UL
-#define UNIX_DGRAM_SOCKET__SENDTO 0x00040000UL
-#define UNIX_DGRAM_SOCKET__RECV_MSG 0x00080000UL
-#define UNIX_DGRAM_SOCKET__SEND_MSG 0x00100000UL
-#define UNIX_DGRAM_SOCKET__NAME_BIND 0x00200000UL
-#define TUN_SOCKET__IOCTL 0x00000001UL
-#define TUN_SOCKET__READ 0x00000002UL
-#define TUN_SOCKET__WRITE 0x00000004UL
-#define TUN_SOCKET__CREATE 0x00000008UL
-#define TUN_SOCKET__GETATTR 0x00000010UL
-#define TUN_SOCKET__SETATTR 0x00000020UL
-#define TUN_SOCKET__LOCK 0x00000040UL
-#define TUN_SOCKET__RELABELFROM 0x00000080UL
-#define TUN_SOCKET__RELABELTO 0x00000100UL
-#define TUN_SOCKET__APPEND 0x00000200UL
-#define TUN_SOCKET__BIND 0x00000400UL
-#define TUN_SOCKET__CONNECT 0x00000800UL
-#define TUN_SOCKET__LISTEN 0x00001000UL
-#define TUN_SOCKET__ACCEPT 0x00002000UL
-#define TUN_SOCKET__GETOPT 0x00004000UL
-#define TUN_SOCKET__SETOPT 0x00008000UL
-#define TUN_SOCKET__SHUTDOWN 0x00010000UL
-#define TUN_SOCKET__RECVFROM 0x00020000UL
-#define TUN_SOCKET__SENDTO 0x00040000UL
-#define TUN_SOCKET__RECV_MSG 0x00080000UL
-#define TUN_SOCKET__SEND_MSG 0x00100000UL
-#define TUN_SOCKET__NAME_BIND 0x00200000UL
-#define PROCESS__FORK 0x00000001UL
-#define PROCESS__TRANSITION 0x00000002UL
-#define PROCESS__SIGCHLD 0x00000004UL
-#define PROCESS__SIGKILL 0x00000008UL
-#define PROCESS__SIGSTOP 0x00000010UL
-#define PROCESS__SIGNULL 0x00000020UL
-#define PROCESS__SIGNAL 0x00000040UL
-#define PROCESS__PTRACE 0x00000080UL
-#define PROCESS__GETSCHED 0x00000100UL
-#define PROCESS__SETSCHED 0x00000200UL
-#define PROCESS__GETSESSION 0x00000400UL
-#define PROCESS__GETPGID 0x00000800UL
-#define PROCESS__SETPGID 0x00001000UL
-#define PROCESS__GETCAP 0x00002000UL
-#define PROCESS__SETCAP 0x00004000UL
-#define PROCESS__SHARE 0x00008000UL
-#define PROCESS__GETATTR 0x00010000UL
-#define PROCESS__SETEXEC 0x00020000UL
-#define PROCESS__SETFSCREATE 0x00040000UL
-#define PROCESS__NOATSECURE 0x00080000UL
-#define PROCESS__SIGINH 0x00100000UL
-#define PROCESS__SETRLIMIT 0x00200000UL
-#define PROCESS__RLIMITINH 0x00400000UL
-#define PROCESS__DYNTRANSITION 0x00800000UL
-#define PROCESS__SETCURRENT 0x01000000UL
-#define PROCESS__EXECMEM 0x02000000UL
-#define PROCESS__EXECSTACK 0x04000000UL
-#define PROCESS__EXECHEAP 0x08000000UL
-#define PROCESS__SETKEYCREATE 0x10000000UL
-#define PROCESS__SETSOCKCREATE 0x20000000UL
-#define IPC__CREATE 0x00000001UL
-#define IPC__DESTROY 0x00000002UL
-#define IPC__GETATTR 0x00000004UL
-#define IPC__SETATTR 0x00000008UL
-#define IPC__READ 0x00000010UL
-#define IPC__WRITE 0x00000020UL
-#define IPC__ASSOCIATE 0x00000040UL
-#define IPC__UNIX_READ 0x00000080UL
-#define IPC__UNIX_WRITE 0x00000100UL
-#define SEM__CREATE 0x00000001UL
-#define SEM__DESTROY 0x00000002UL
-#define SEM__GETATTR 0x00000004UL
-#define SEM__SETATTR 0x00000008UL
-#define SEM__READ 0x00000010UL
-#define SEM__WRITE 0x00000020UL
-#define SEM__ASSOCIATE 0x00000040UL
-#define SEM__UNIX_READ 0x00000080UL
-#define SEM__UNIX_WRITE 0x00000100UL
-#define MSGQ__CREATE 0x00000001UL
-#define MSGQ__DESTROY 0x00000002UL
-#define MSGQ__GETATTR 0x00000004UL
-#define MSGQ__SETATTR 0x00000008UL
-#define MSGQ__READ 0x00000010UL
-#define MSGQ__WRITE 0x00000020UL
-#define MSGQ__ASSOCIATE 0x00000040UL
-#define MSGQ__UNIX_READ 0x00000080UL
-#define MSGQ__UNIX_WRITE 0x00000100UL
-#define MSGQ__ENQUEUE 0x00000200UL
-#define MSG__SEND 0x00000001UL
-#define MSG__RECEIVE 0x00000002UL
-#define SHM__CREATE 0x00000001UL
-#define SHM__DESTROY 0x00000002UL
-#define SHM__GETATTR 0x00000004UL
-#define SHM__SETATTR 0x00000008UL
-#define SHM__READ 0x00000010UL
-#define SHM__WRITE 0x00000020UL
-#define SHM__ASSOCIATE 0x00000040UL
-#define SHM__UNIX_READ 0x00000080UL
-#define SHM__UNIX_WRITE 0x00000100UL
-#define SHM__LOCK 0x00000200UL
-#define SECURITY__COMPUTE_AV 0x00000001UL
-#define SECURITY__COMPUTE_CREATE 0x00000002UL
-#define SECURITY__COMPUTE_MEMBER 0x00000004UL
-#define SECURITY__CHECK_CONTEXT 0x00000008UL
-#define SECURITY__LOAD_POLICY 0x00000010UL
-#define SECURITY__COMPUTE_RELABEL 0x00000020UL
-#define SECURITY__COMPUTE_USER 0x00000040UL
-#define SECURITY__SETENFORCE 0x00000080UL
-#define SECURITY__SETBOOL 0x00000100UL
-#define SECURITY__SETSECPARAM 0x00000200UL
-#define SECURITY__SETCHECKREQPROT 0x00000400UL
-#define SYSTEM__IPC_INFO 0x00000001UL
-#define SYSTEM__SYSLOG_READ 0x00000002UL
-#define SYSTEM__SYSLOG_MOD 0x00000004UL
-#define SYSTEM__SYSLOG_CONSOLE 0x00000008UL
-#define SYSTEM__MODULE_REQUEST 0x00000010UL
-#define CAPABILITY__CHOWN 0x00000001UL
-#define CAPABILITY__DAC_OVERRIDE 0x00000002UL
-#define CAPABILITY__DAC_READ_SEARCH 0x00000004UL
-#define CAPABILITY__FOWNER 0x00000008UL
-#define CAPABILITY__FSETID 0x00000010UL
-#define CAPABILITY__KILL 0x00000020UL
-#define CAPABILITY__SETGID 0x00000040UL
-#define CAPABILITY__SETUID 0x00000080UL
-#define CAPABILITY__SETPCAP 0x00000100UL
-#define CAPABILITY__LINUX_IMMUTABLE 0x00000200UL
-#define CAPABILITY__NET_BIND_SERVICE 0x00000400UL
-#define CAPABILITY__NET_BROADCAST 0x00000800UL
-#define CAPABILITY__NET_ADMIN 0x00001000UL
-#define CAPABILITY__NET_RAW 0x00002000UL
-#define CAPABILITY__IPC_LOCK 0x00004000UL
-#define CAPABILITY__IPC_OWNER 0x00008000UL
-#define CAPABILITY__SYS_MODULE 0x00010000UL
-#define CAPABILITY__SYS_RAWIO 0x00020000UL
-#define CAPABILITY__SYS_CHROOT 0x00040000UL
-#define CAPABILITY__SYS_PTRACE 0x00080000UL
-#define CAPABILITY__SYS_PACCT 0x00100000UL
-#define CAPABILITY__SYS_ADMIN 0x00200000UL
-#define CAPABILITY__SYS_BOOT 0x00400000UL
-#define CAPABILITY__SYS_NICE 0x00800000UL
-#define CAPABILITY__SYS_RESOURCE 0x01000000UL
-#define CAPABILITY__SYS_TIME 0x02000000UL
-#define CAPABILITY__SYS_TTY_CONFIG 0x04000000UL
-#define CAPABILITY__MKNOD 0x08000000UL
-#define CAPABILITY__LEASE 0x10000000UL
-#define CAPABILITY__AUDIT_WRITE 0x20000000UL
-#define CAPABILITY__AUDIT_CONTROL 0x40000000UL
-#define CAPABILITY__SETFCAP 0x80000000UL
-#define CAPABILITY2__MAC_OVERRIDE 0x00000001UL
-#define CAPABILITY2__MAC_ADMIN 0x00000002UL
-#define NETLINK_ROUTE_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_ROUTE_SOCKET__READ 0x00000002UL
-#define NETLINK_ROUTE_SOCKET__WRITE 0x00000004UL
-#define NETLINK_ROUTE_SOCKET__CREATE 0x00000008UL
-#define NETLINK_ROUTE_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_ROUTE_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_ROUTE_SOCKET__LOCK 0x00000040UL
-#define NETLINK_ROUTE_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_ROUTE_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_ROUTE_SOCKET__APPEND 0x00000200UL
-#define NETLINK_ROUTE_SOCKET__BIND 0x00000400UL
-#define NETLINK_ROUTE_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_ROUTE_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_ROUTE_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_ROUTE_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_ROUTE_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_ROUTE_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_ROUTE_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_ROUTE_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_ROUTE_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_ROUTE_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_ROUTE_SOCKET__NAME_BIND 0x00200000UL
-#define NETLINK_ROUTE_SOCKET__NLMSG_READ 0x00400000UL
-#define NETLINK_ROUTE_SOCKET__NLMSG_WRITE 0x00800000UL
-#define NETLINK_FIREWALL_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_FIREWALL_SOCKET__READ 0x00000002UL
-#define NETLINK_FIREWALL_SOCKET__WRITE 0x00000004UL
-#define NETLINK_FIREWALL_SOCKET__CREATE 0x00000008UL
-#define NETLINK_FIREWALL_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_FIREWALL_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_FIREWALL_SOCKET__LOCK 0x00000040UL
-#define NETLINK_FIREWALL_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_FIREWALL_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_FIREWALL_SOCKET__APPEND 0x00000200UL
-#define NETLINK_FIREWALL_SOCKET__BIND 0x00000400UL
-#define NETLINK_FIREWALL_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_FIREWALL_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_FIREWALL_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_FIREWALL_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_FIREWALL_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_FIREWALL_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_FIREWALL_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_FIREWALL_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_FIREWALL_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_FIREWALL_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_FIREWALL_SOCKET__NAME_BIND 0x00200000UL
-#define NETLINK_FIREWALL_SOCKET__NLMSG_READ 0x00400000UL
-#define NETLINK_FIREWALL_SOCKET__NLMSG_WRITE 0x00800000UL
-#define NETLINK_TCPDIAG_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_TCPDIAG_SOCKET__READ 0x00000002UL
-#define NETLINK_TCPDIAG_SOCKET__WRITE 0x00000004UL
-#define NETLINK_TCPDIAG_SOCKET__CREATE 0x00000008UL
-#define NETLINK_TCPDIAG_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_TCPDIAG_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_TCPDIAG_SOCKET__LOCK 0x00000040UL
-#define NETLINK_TCPDIAG_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_TCPDIAG_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_TCPDIAG_SOCKET__APPEND 0x00000200UL
-#define NETLINK_TCPDIAG_SOCKET__BIND 0x00000400UL
-#define NETLINK_TCPDIAG_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_TCPDIAG_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_TCPDIAG_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_TCPDIAG_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_TCPDIAG_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_TCPDIAG_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_TCPDIAG_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_TCPDIAG_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_TCPDIAG_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_TCPDIAG_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_TCPDIAG_SOCKET__NAME_BIND 0x00200000UL
-#define NETLINK_TCPDIAG_SOCKET__NLMSG_READ 0x00400000UL
-#define NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE 0x00800000UL
-#define NETLINK_NFLOG_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_NFLOG_SOCKET__READ 0x00000002UL
-#define NETLINK_NFLOG_SOCKET__WRITE 0x00000004UL
-#define NETLINK_NFLOG_SOCKET__CREATE 0x00000008UL
-#define NETLINK_NFLOG_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_NFLOG_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_NFLOG_SOCKET__LOCK 0x00000040UL
-#define NETLINK_NFLOG_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_NFLOG_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_NFLOG_SOCKET__APPEND 0x00000200UL
-#define NETLINK_NFLOG_SOCKET__BIND 0x00000400UL
-#define NETLINK_NFLOG_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_NFLOG_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_NFLOG_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_NFLOG_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_NFLOG_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_NFLOG_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_NFLOG_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_NFLOG_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_NFLOG_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_NFLOG_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_NFLOG_SOCKET__NAME_BIND 0x00200000UL
-#define NETLINK_XFRM_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_XFRM_SOCKET__READ 0x00000002UL
-#define NETLINK_XFRM_SOCKET__WRITE 0x00000004UL
-#define NETLINK_XFRM_SOCKET__CREATE 0x00000008UL
-#define NETLINK_XFRM_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_XFRM_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_XFRM_SOCKET__LOCK 0x00000040UL
-#define NETLINK_XFRM_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_XFRM_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_XFRM_SOCKET__APPEND 0x00000200UL
-#define NETLINK_XFRM_SOCKET__BIND 0x00000400UL
-#define NETLINK_XFRM_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_XFRM_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_XFRM_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_XFRM_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_XFRM_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_XFRM_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_XFRM_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_XFRM_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_XFRM_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_XFRM_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_XFRM_SOCKET__NAME_BIND 0x00200000UL
-#define NETLINK_XFRM_SOCKET__NLMSG_READ 0x00400000UL
-#define NETLINK_XFRM_SOCKET__NLMSG_WRITE 0x00800000UL
-#define NETLINK_SELINUX_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_SELINUX_SOCKET__READ 0x00000002UL
-#define NETLINK_SELINUX_SOCKET__WRITE 0x00000004UL
-#define NETLINK_SELINUX_SOCKET__CREATE 0x00000008UL
-#define NETLINK_SELINUX_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_SELINUX_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_SELINUX_SOCKET__LOCK 0x00000040UL
-#define NETLINK_SELINUX_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_SELINUX_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_SELINUX_SOCKET__APPEND 0x00000200UL
-#define NETLINK_SELINUX_SOCKET__BIND 0x00000400UL
-#define NETLINK_SELINUX_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_SELINUX_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_SELINUX_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_SELINUX_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_SELINUX_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_SELINUX_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_SELINUX_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_SELINUX_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_SELINUX_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_SELINUX_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_SELINUX_SOCKET__NAME_BIND 0x00200000UL
-#define NETLINK_AUDIT_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_AUDIT_SOCKET__READ 0x00000002UL
-#define NETLINK_AUDIT_SOCKET__WRITE 0x00000004UL
-#define NETLINK_AUDIT_SOCKET__CREATE 0x00000008UL
-#define NETLINK_AUDIT_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_AUDIT_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_AUDIT_SOCKET__LOCK 0x00000040UL
-#define NETLINK_AUDIT_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_AUDIT_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_AUDIT_SOCKET__APPEND 0x00000200UL
-#define NETLINK_AUDIT_SOCKET__BIND 0x00000400UL
-#define NETLINK_AUDIT_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_AUDIT_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_AUDIT_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_AUDIT_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_AUDIT_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_AUDIT_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_AUDIT_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_AUDIT_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_AUDIT_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_AUDIT_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_AUDIT_SOCKET__NAME_BIND 0x00200000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_READ 0x00400000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_WRITE 0x00800000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_RELAY 0x01000000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_READPRIV 0x02000000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT 0x04000000UL
-#define NETLINK_IP6FW_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_IP6FW_SOCKET__READ 0x00000002UL
-#define NETLINK_IP6FW_SOCKET__WRITE 0x00000004UL
-#define NETLINK_IP6FW_SOCKET__CREATE 0x00000008UL
-#define NETLINK_IP6FW_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_IP6FW_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_IP6FW_SOCKET__LOCK 0x00000040UL
-#define NETLINK_IP6FW_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_IP6FW_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_IP6FW_SOCKET__APPEND 0x00000200UL
-#define NETLINK_IP6FW_SOCKET__BIND 0x00000400UL
-#define NETLINK_IP6FW_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_IP6FW_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_IP6FW_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_IP6FW_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_IP6FW_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_IP6FW_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_IP6FW_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_IP6FW_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_IP6FW_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_IP6FW_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_IP6FW_SOCKET__NAME_BIND 0x00200000UL
-#define NETLINK_IP6FW_SOCKET__NLMSG_READ 0x00400000UL
-#define NETLINK_IP6FW_SOCKET__NLMSG_WRITE 0x00800000UL
-#define NETLINK_DNRT_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_DNRT_SOCKET__READ 0x00000002UL
-#define NETLINK_DNRT_SOCKET__WRITE 0x00000004UL
-#define NETLINK_DNRT_SOCKET__CREATE 0x00000008UL
-#define NETLINK_DNRT_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_DNRT_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_DNRT_SOCKET__LOCK 0x00000040UL
-#define NETLINK_DNRT_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_DNRT_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_DNRT_SOCKET__APPEND 0x00000200UL
-#define NETLINK_DNRT_SOCKET__BIND 0x00000400UL
-#define NETLINK_DNRT_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_DNRT_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_DNRT_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_DNRT_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_DNRT_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_DNRT_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_DNRT_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_DNRT_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_DNRT_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_DNRT_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_DNRT_SOCKET__NAME_BIND 0x00200000UL
-#define ASSOCIATION__SENDTO 0x00000001UL
-#define ASSOCIATION__RECVFROM 0x00000002UL
-#define ASSOCIATION__SETCONTEXT 0x00000004UL
-#define ASSOCIATION__POLMATCH 0x00000008UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__READ 0x00000002UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__WRITE 0x00000004UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__CREATE 0x00000008UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__GETATTR 0x00000010UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__LOCK 0x00000040UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__APPEND 0x00000200UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__BIND 0x00000400UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__LISTEN 0x00001000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__ACCEPT 0x00002000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SETOPT 0x00008000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__RECV_MSG 0x00080000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SEND_MSG 0x00100000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__NAME_BIND 0x00200000UL
-#define APPLETALK_SOCKET__IOCTL 0x00000001UL
-#define APPLETALK_SOCKET__READ 0x00000002UL
-#define APPLETALK_SOCKET__WRITE 0x00000004UL
-#define APPLETALK_SOCKET__CREATE 0x00000008UL
-#define APPLETALK_SOCKET__GETATTR 0x00000010UL
-#define APPLETALK_SOCKET__SETATTR 0x00000020UL
-#define APPLETALK_SOCKET__LOCK 0x00000040UL
-#define APPLETALK_SOCKET__RELABELFROM 0x00000080UL
-#define APPLETALK_SOCKET__RELABELTO 0x00000100UL
-#define APPLETALK_SOCKET__APPEND 0x00000200UL
-#define APPLETALK_SOCKET__BIND 0x00000400UL
-#define APPLETALK_SOCKET__CONNECT 0x00000800UL
-#define APPLETALK_SOCKET__LISTEN 0x00001000UL
-#define APPLETALK_SOCKET__ACCEPT 0x00002000UL
-#define APPLETALK_SOCKET__GETOPT 0x00004000UL
-#define APPLETALK_SOCKET__SETOPT 0x00008000UL
-#define APPLETALK_SOCKET__SHUTDOWN 0x00010000UL
-#define APPLETALK_SOCKET__RECVFROM 0x00020000UL
-#define APPLETALK_SOCKET__SENDTO 0x00040000UL
-#define APPLETALK_SOCKET__RECV_MSG 0x00080000UL
-#define APPLETALK_SOCKET__SEND_MSG 0x00100000UL
-#define APPLETALK_SOCKET__NAME_BIND 0x00200000UL
-#define PACKET__SEND 0x00000001UL
-#define PACKET__RECV 0x00000002UL
-#define PACKET__RELABELTO 0x00000004UL
-#define PACKET__FLOW_IN 0x00000008UL
-#define PACKET__FLOW_OUT 0x00000010UL
-#define PACKET__FORWARD_IN 0x00000020UL
-#define PACKET__FORWARD_OUT 0x00000040UL
-#define KEY__VIEW 0x00000001UL
-#define KEY__READ 0x00000002UL
-#define KEY__WRITE 0x00000004UL
-#define KEY__SEARCH 0x00000008UL
-#define KEY__LINK 0x00000010UL
-#define KEY__SETATTR 0x00000020UL
-#define KEY__CREATE 0x00000040UL
-#define DCCP_SOCKET__IOCTL 0x00000001UL
-#define DCCP_SOCKET__READ 0x00000002UL
-#define DCCP_SOCKET__WRITE 0x00000004UL
-#define DCCP_SOCKET__CREATE 0x00000008UL
-#define DCCP_SOCKET__GETATTR 0x00000010UL
-#define DCCP_SOCKET__SETATTR 0x00000020UL
-#define DCCP_SOCKET__LOCK 0x00000040UL
-#define DCCP_SOCKET__RELABELFROM 0x00000080UL
-#define DCCP_SOCKET__RELABELTO 0x00000100UL
-#define DCCP_SOCKET__APPEND 0x00000200UL
-#define DCCP_SOCKET__BIND 0x00000400UL
-#define DCCP_SOCKET__CONNECT 0x00000800UL
-#define DCCP_SOCKET__LISTEN 0x00001000UL
-#define DCCP_SOCKET__ACCEPT 0x00002000UL
-#define DCCP_SOCKET__GETOPT 0x00004000UL
-#define DCCP_SOCKET__SETOPT 0x00008000UL
-#define DCCP_SOCKET__SHUTDOWN 0x00010000UL
-#define DCCP_SOCKET__RECVFROM 0x00020000UL
-#define DCCP_SOCKET__SENDTO 0x00040000UL
-#define DCCP_SOCKET__RECV_MSG 0x00080000UL
-#define DCCP_SOCKET__SEND_MSG 0x00100000UL
-#define DCCP_SOCKET__NAME_BIND 0x00200000UL
-#define DCCP_SOCKET__NODE_BIND 0x00400000UL
-#define DCCP_SOCKET__NAME_CONNECT 0x00800000UL
-#define MEMPROTECT__MMAP_ZERO 0x00000001UL
-#define PEER__RECV 0x00000001UL
-#define KERNEL_SERVICE__USE_AS_OVERRIDE 0x00000001UL
-#define KERNEL_SERVICE__CREATE_FILES_AS 0x00000002UL
diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h
index bb1ec801bdfe..4677aa519b04 100644
--- a/security/selinux/include/avc_ss.h
+++ b/security/selinux/include/avc_ss.h
@@ -10,26 +10,13 @@
int avc_ss_reset(u32 seqno);
-struct av_perm_to_string {
- u16 tclass;
- u32 value;
+/* Class/perm mapping support */
+struct security_class_mapping {
const char *name;
+ const char *perms[sizeof(u32) * 8 + 1];
};
-struct av_inherit {
- const char **common_pts;
- u32 common_base;
- u16 tclass;
-};
-
-struct selinux_class_perm {
- const struct av_perm_to_string *av_perm_to_string;
- u32 av_pts_len;
- u32 cts_len;
- const char **class_to_string;
- const struct av_inherit *av_inherit;
- u32 av_inherit_len;
-};
+extern struct security_class_mapping secclass_map[];
#endif /* _SELINUX_AVC_SS_H_ */
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
deleted file mode 100644
index 7ab9299bfb6b..000000000000
--- a/security/selinux/include/class_to_string.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* This file is automatically generated. Do not edit. */
-/*
- * Security object class definitions
- */
- S_(NULL)
- S_("security")
- S_("process")
- S_("system")
- S_("capability")
- S_("filesystem")
- S_("file")
- S_("dir")
- S_("fd")
- S_("lnk_file")
- S_("chr_file")
- S_("blk_file")
- S_("sock_file")
- S_("fifo_file")
- S_("socket")
- S_("tcp_socket")
- S_("udp_socket")
- S_("rawip_socket")
- S_("node")
- S_("netif")
- S_("netlink_socket")
- S_("packet_socket")
- S_("key_socket")
- S_("unix_stream_socket")
- S_("unix_dgram_socket")
- S_("sem")
- S_("msg")
- S_("msgq")
- S_("shm")
- S_("ipc")
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_("netlink_route_socket")
- S_("netlink_firewall_socket")
- S_("netlink_tcpdiag_socket")
- S_("netlink_nflog_socket")
- S_("netlink_xfrm_socket")
- S_("netlink_selinux_socket")
- S_("netlink_audit_socket")
- S_("netlink_ip6fw_socket")
- S_("netlink_dnrt_socket")
- S_(NULL)
- S_(NULL)
- S_("association")
- S_("netlink_kobject_uevent_socket")
- S_("appletalk_socket")
- S_("packet")
- S_("key")
- S_(NULL)
- S_("dccp_socket")
- S_("memprotect")
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_("peer")
- S_("capability2")
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_(NULL)
- S_("kernel_service")
- S_("tun_socket")
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
new file mode 100644
index 000000000000..8b32e959bb2e
--- /dev/null
+++ b/security/selinux/include/classmap.h
@@ -0,0 +1,150 @@
+#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \
+ "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append"
+
+#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \
+ "rename", "execute", "swapon", "quotaon", "mounton"
+
+#define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \
+ "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \
+ "sendto", "recv_msg", "send_msg", "name_bind"
+
+#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \
+ "write", "associate", "unix_read", "unix_write"
+
+struct security_class_mapping secclass_map[] = {
+ { "security",
+ { "compute_av", "compute_create", "compute_member",
+ "check_context", "load_policy", "compute_relabel",
+ "compute_user", "setenforce", "setbool", "setsecparam",
+ "setcheckreqprot", NULL } },
+ { "process",
+ { "fork", "transition", "sigchld", "sigkill",
+ "sigstop", "signull", "signal", "ptrace", "getsched", "setsched",
+ "getsession", "getpgid", "setpgid", "getcap", "setcap", "share",
+ "getattr", "setexec", "setfscreate", "noatsecure", "siginh",
+ "setrlimit", "rlimitinh", "dyntransition", "setcurrent",
+ "execmem", "execstack", "execheap", "setkeycreate",
+ "setsockcreate", NULL } },
+ { "system",
+ { "ipc_info", "syslog_read", "syslog_mod",
+ "syslog_console", "module_request", NULL } },
+ { "capability",
+ { "chown", "dac_override", "dac_read_search",
+ "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap",
+ "linux_immutable", "net_bind_service", "net_broadcast",
+ "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module",
+ "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin",
+ "sys_boot", "sys_nice", "sys_resource", "sys_time",
+ "sys_tty_config", "mknod", "lease", "audit_write",
+ "audit_control", "setfcap", NULL } },
+ { "filesystem",
+ { "mount", "remount", "unmount", "getattr",
+ "relabelfrom", "relabelto", "transition", "associate", "quotamod",
+ "quotaget", NULL } },
+ { "file",
+ { COMMON_FILE_PERMS,
+ "execute_no_trans", "entrypoint", "execmod", "open", NULL } },
+ { "dir",
+ { COMMON_FILE_PERMS, "add_name", "remove_name",
+ "reparent", "search", "rmdir", "open", NULL } },
+ { "fd", { "use", NULL } },
+ { "lnk_file",
+ { COMMON_FILE_PERMS, NULL } },
+ { "chr_file",
+ { COMMON_FILE_PERMS,
+ "execute_no_trans", "entrypoint", "execmod", "open", NULL } },
+ { "blk_file",
+ { COMMON_FILE_PERMS, "open", NULL } },
+ { "sock_file",
+ { COMMON_FILE_PERMS, "open", NULL } },
+ { "fifo_file",
+ { COMMON_FILE_PERMS, "open", NULL } },
+ { "socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "tcp_socket",
+ { COMMON_SOCK_PERMS,
+ "connectto", "newconn", "acceptfrom", "node_bind", "name_connect",
+ NULL } },
+ { "udp_socket",
+ { COMMON_SOCK_PERMS,
+ "node_bind", NULL } },
+ { "rawip_socket",
+ { COMMON_SOCK_PERMS,
+ "node_bind", NULL } },
+ { "node",
+ { "tcp_recv", "tcp_send", "udp_recv", "udp_send",
+ "rawip_recv", "rawip_send", "enforce_dest",
+ "dccp_recv", "dccp_send", "recvfrom", "sendto", NULL } },
+ { "netif",
+ { "tcp_recv", "tcp_send", "udp_recv", "udp_send",
+ "rawip_recv", "rawip_send", "dccp_recv", "dccp_send",
+ "ingress", "egress", NULL } },
+ { "netlink_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "packet_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "key_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "unix_stream_socket",
+ { COMMON_SOCK_PERMS, "connectto", "newconn", "acceptfrom", NULL
+ } },
+ { "unix_dgram_socket",
+ { COMMON_SOCK_PERMS, NULL
+ } },
+ { "sem",
+ { COMMON_IPC_PERMS, NULL } },
+ { "msg", { "send", "receive", NULL } },
+ { "msgq",
+ { COMMON_IPC_PERMS, "enqueue", NULL } },
+ { "shm",
+ { COMMON_IPC_PERMS, "lock", NULL } },
+ { "ipc",
+ { COMMON_IPC_PERMS, NULL } },
+ { "netlink_route_socket",
+ { COMMON_SOCK_PERMS,
+ "nlmsg_read", "nlmsg_write", NULL } },
+ { "netlink_firewall_socket",
+ { COMMON_SOCK_PERMS,
+ "nlmsg_read", "nlmsg_write", NULL } },
+ { "netlink_tcpdiag_socket",
+ { COMMON_SOCK_PERMS,
+ "nlmsg_read", "nlmsg_write", NULL } },
+ { "netlink_nflog_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "netlink_xfrm_socket",
+ { COMMON_SOCK_PERMS,
+ "nlmsg_read", "nlmsg_write", NULL } },
+ { "netlink_selinux_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "netlink_audit_socket",
+ { COMMON_SOCK_PERMS,
+ "nlmsg_read", "nlmsg_write", "nlmsg_relay", "nlmsg_readpriv",
+ "nlmsg_tty_audit", NULL } },
+ { "netlink_ip6fw_socket",
+ { COMMON_SOCK_PERMS,
+ "nlmsg_read", "nlmsg_write", NULL } },
+ { "netlink_dnrt_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "association",
+ { "sendto", "recvfrom", "setcontext", "polmatch", NULL } },
+ { "netlink_kobject_uevent_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "appletalk_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "packet",
+ { "send", "recv", "relabelto", "flow_in", "flow_out",
+ "forward_in", "forward_out", NULL } },
+ { "key",
+ { "view", "read", "write", "search", "link", "setattr", "create",
+ NULL } },
+ { "dccp_socket",
+ { COMMON_SOCK_PERMS,
+ "node_bind", "name_connect", NULL } },
+ { "memprotect", { "mmap_zero", NULL } },
+ { "peer", { "recv", NULL } },
+ { "capability2", { "mac_override", "mac_admin", NULL } },
+ { "kernel_service", { "use_as_override", "create_files_as", NULL } },
+ { "tun_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { NULL }
+ };
diff --git a/security/selinux/include/common_perm_to_string.h b/security/selinux/include/common_perm_to_string.h
deleted file mode 100644
index ce5b6e2fe9dd..000000000000
--- a/security/selinux/include/common_perm_to_string.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* This file is automatically generated. Do not edit. */
-TB_(common_file_perm_to_string)
- S_("ioctl")
- S_("read")
- S_("write")
- S_("create")
- S_("getattr")
- S_("setattr")
- S_("lock")
- S_("relabelfrom")
- S_("relabelto")
- S_("append")
- S_("unlink")
- S_("link")
- S_("rename")
- S_("execute")
- S_("swapon")
- S_("quotaon")
- S_("mounton")
-TE_(common_file_perm_to_string)
-
-TB_(common_socket_perm_to_string)
- S_("ioctl")
- S_("read")
- S_("write")
- S_("create")
- S_("getattr")
- S_("setattr")
- S_("lock")
- S_("relabelfrom")
- S_("relabelto")
- S_("append")
- S_("bind")
- S_("connect")
- S_("listen")
- S_("accept")
- S_("getopt")
- S_("setopt")
- S_("shutdown")
- S_("recvfrom")
- S_("sendto")
- S_("recv_msg")
- S_("send_msg")
- S_("name_bind")
-TE_(common_socket_perm_to_string)
-
-TB_(common_ipc_perm_to_string)
- S_("create")
- S_("destroy")
- S_("getattr")
- S_("setattr")
- S_("read")
- S_("write")
- S_("associate")
- S_("unix_read")
- S_("unix_write")
-TE_(common_ipc_perm_to_string)
-
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
deleted file mode 100644
index f248500a1e3c..000000000000
--- a/security/selinux/include/flask.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* This file is automatically generated. Do not edit. */
-#ifndef _SELINUX_FLASK_H_
-#define _SELINUX_FLASK_H_
-
-/*
- * Security object class definitions
- */
-#define SECCLASS_SECURITY 1
-#define SECCLASS_PROCESS 2
-#define SECCLASS_SYSTEM 3
-#define SECCLASS_CAPABILITY 4
-#define SECCLASS_FILESYSTEM 5
-#define SECCLASS_FILE 6
-#define SECCLASS_DIR 7
-#define SECCLASS_FD 8
-#define SECCLASS_LNK_FILE 9
-#define SECCLASS_CHR_FILE 10
-#define SECCLASS_BLK_FILE 11
-#define SECCLASS_SOCK_FILE 12
-#define SECCLASS_FIFO_FILE 13
-#define SECCLASS_SOCKET 14
-#define SECCLASS_TCP_SOCKET 15
-#define SECCLASS_UDP_SOCKET 16
-#define SECCLASS_RAWIP_SOCKET 17
-#define SECCLASS_NODE 18
-#define SECCLASS_NETIF 19
-#define SECCLASS_NETLINK_SOCKET 20
-#define SECCLASS_PACKET_SOCKET 21
-#define SECCLASS_KEY_SOCKET 22
-#define SECCLASS_UNIX_STREAM_SOCKET 23
-#define SECCLASS_UNIX_DGRAM_SOCKET 24
-#define SECCLASS_SEM 25
-#define SECCLASS_MSG 26
-#define SECCLASS_MSGQ 27
-#define SECCLASS_SHM 28
-#define SECCLASS_IPC 29
-#define SECCLASS_NETLINK_ROUTE_SOCKET 43
-#define SECCLASS_NETLINK_FIREWALL_SOCKET 44
-#define SECCLASS_NETLINK_TCPDIAG_SOCKET 45
-#define SECCLASS_NETLINK_NFLOG_SOCKET 46
-#define SECCLASS_NETLINK_XFRM_SOCKET 47
-#define SECCLASS_NETLINK_SELINUX_SOCKET 48
-#define SECCLASS_NETLINK_AUDIT_SOCKET 49
-#define SECCLASS_NETLINK_IP6FW_SOCKET 50
-#define SECCLASS_NETLINK_DNRT_SOCKET 51
-#define SECCLASS_ASSOCIATION 54
-#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55
-#define SECCLASS_APPLETALK_SOCKET 56
-#define SECCLASS_PACKET 57
-#define SECCLASS_KEY 58
-#define SECCLASS_DCCP_SOCKET 60
-#define SECCLASS_MEMPROTECT 61
-#define SECCLASS_PEER 68
-#define SECCLASS_CAPABILITY2 69
-#define SECCLASS_KERNEL_SERVICE 74
-#define SECCLASS_TUN_SOCKET 75
-
-/*
- * Security identifier indices for initial entities
- */
-#define SECINITSID_KERNEL 1
-#define SECINITSID_SECURITY 2
-#define SECINITSID_UNLABELED 3
-#define SECINITSID_FS 4
-#define SECINITSID_FILE 5
-#define SECINITSID_FILE_LABELS 6
-#define SECINITSID_INIT 7
-#define SECINITSID_ANY_SOCKET 8
-#define SECINITSID_PORT 9
-#define SECINITSID_NETIF 10
-#define SECINITSID_NETMSG 11
-#define SECINITSID_NODE 12
-#define SECINITSID_IGMP_PACKET 13
-#define SECINITSID_ICMP_SOCKET 14
-#define SECINITSID_TCP_SOCKET 15
-#define SECINITSID_SYSCTL_MODPROBE 16
-#define SECINITSID_SYSCTL 17
-#define SECINITSID_SYSCTL_FS 18
-#define SECINITSID_SYSCTL_KERNEL 19
-#define SECINITSID_SYSCTL_NET 20
-#define SECINITSID_SYSCTL_NET_UNIX 21
-#define SECINITSID_SYSCTL_VM 22
-#define SECINITSID_SYSCTL_DEV 23
-#define SECINITSID_KMOD 24
-#define SECINITSID_POLICY 25
-#define SECINITSID_SCMP_PACKET 26
-#define SECINITSID_DEVNULL 27
-
-#define SECINITSID_NUM 27
-
-#endif
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index ca835795a8b3..2553266ad793 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -97,11 +97,18 @@ struct av_decision {
#define AVD_FLAGS_PERMISSIVE 0x0001
int security_compute_av(u32 ssid, u32 tsid,
- u16 tclass, u32 requested,
- struct av_decision *avd);
+ u16 tclass, u32 requested,
+ struct av_decision *avd);
+
+int security_compute_av_user(u32 ssid, u32 tsid,
+ u16 tclass, u32 requested,
+ struct av_decision *avd);
int security_transition_sid(u32 ssid, u32 tsid,
- u16 tclass, u32 *out_sid);
+ u16 tclass, u32 *out_sid);
+
+int security_transition_sid_user(u32 ssid, u32 tsid,
+ u16 tclass, u32 *out_sid);
int security_member_sid(u32 ssid, u32 tsid,
u16 tclass, u32 *out_sid);
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index b4fc506e7a87..fab36fdf2769 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -522,7 +522,7 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
if (length < 0)
goto out2;
- length = security_compute_av(ssid, tsid, tclass, req, &avd);
+ length = security_compute_av_user(ssid, tsid, tclass, req, &avd);
if (length < 0)
goto out2;
@@ -571,7 +571,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
if (length < 0)
goto out2;
- length = security_transition_sid(ssid, tsid, tclass, &newsid);
+ length = security_transition_sid_user(ssid, tsid, tclass, &newsid);
if (length < 0)
goto out2;
diff --git a/security/selinux/ss/Makefile b/security/selinux/ss/Makefile
index bad78779b9b0..15d4e62917de 100644
--- a/security/selinux/ss/Makefile
+++ b/security/selinux/ss/Makefile
@@ -2,7 +2,7 @@
# Makefile for building the SELinux security server as part of the kernel tree.
#
-EXTRA_CFLAGS += -Isecurity/selinux/include
+EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
obj-y := ss.o
ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index b5407f16c2a4..3f2b2706b5bb 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -532,7 +532,7 @@ int mls_compute_sid(struct context *scontext,
}
/* Fallthrough */
case AVTAB_CHANGE:
- if (tclass == SECCLASS_PROCESS)
+ if (tclass == policydb.process_class)
/* Use the process MLS attributes. */
return mls_context_cpy(newcontext, scontext);
else
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 72e4a54973aa..f03667213ea8 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -713,7 +713,6 @@ void policydb_destroy(struct policydb *p)
ebitmap_destroy(&p->type_attr_map[i]);
}
kfree(p->type_attr_map);
- kfree(p->undefined_perms);
ebitmap_destroy(&p->policycaps);
ebitmap_destroy(&p->permissive_map);
@@ -1640,6 +1639,40 @@ static int policydb_bounds_sanity_check(struct policydb *p)
extern int ss_initialized;
+u16 string_to_security_class(struct policydb *p, const char *name)
+{
+ struct class_datum *cladatum;
+
+ cladatum = hashtab_search(p->p_classes.table, name);
+ if (!cladatum)
+ return 0;
+
+ return cladatum->value;
+}
+
+u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name)
+{
+ struct class_datum *cladatum;
+ struct perm_datum *perdatum = NULL;
+ struct common_datum *comdatum;
+
+ if (!tclass || tclass > p->p_classes.nprim)
+ return 0;
+
+ cladatum = p->class_val_to_struct[tclass-1];
+ comdatum = cladatum->comdatum;
+ if (comdatum)
+ perdatum = hashtab_search(comdatum->permissions.table,
+ name);
+ if (!perdatum)
+ perdatum = hashtab_search(cladatum->permissions.table,
+ name);
+ if (!perdatum)
+ return 0;
+
+ return 1U << (perdatum->value-1);
+}
+
/*
* Read the configuration data from a policy database binary
* representation file into a policy database structure.
@@ -1861,6 +1894,16 @@ int policydb_read(struct policydb *p, void *fp)
if (rc)
goto bad;
+ p->process_class = string_to_security_class(p, "process");
+ if (!p->process_class)
+ goto bad;
+ p->process_trans_perms = string_to_av_perm(p, p->process_class,
+ "transition");
+ p->process_trans_perms |= string_to_av_perm(p, p->process_class,
+ "dyntransition");
+ if (!p->process_trans_perms)
+ goto bad;
+
for (i = 0; i < info->ocon_num; i++) {
rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0)
@@ -2101,7 +2144,7 @@ int policydb_read(struct policydb *p, void *fp)
goto bad;
rt->target_class = le32_to_cpu(buf[0]);
} else
- rt->target_class = SECCLASS_PROCESS;
+ rt->target_class = p->process_class;
if (!policydb_type_isvalid(p, rt->source_type) ||
!policydb_type_isvalid(p, rt->target_type) ||
!policydb_class_isvalid(p, rt->target_class)) {
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 55152d498b53..cdcc5700946f 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -254,7 +254,9 @@ struct policydb {
unsigned int reject_unknown : 1;
unsigned int allow_unknown : 1;
- u32 *undefined_perms;
+
+ u16 process_class;
+ u32 process_trans_perms;
};
extern void policydb_destroy(struct policydb *p);
@@ -295,5 +297,8 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
return 0;
}
+extern u16 string_to_security_class(struct policydb *p, const char *name);
+extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
+
#endif /* _SS_POLICYDB_H_ */
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ff17820d35ec..d6bb20cbad62 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -65,16 +65,10 @@
#include "audit.h"
extern void selnl_notify_policyload(u32 seqno);
-unsigned int policydb_loaded_version;
int selinux_policycap_netpeer;
int selinux_policycap_openperm;
-/*
- * This is declared in avc.c
- */
-extern const struct selinux_class_perm selinux_class_perm;
-
static DEFINE_RWLOCK(policy_rwlock);
static struct sidtab sidtab;
@@ -98,6 +92,165 @@ static int context_struct_compute_av(struct context *scontext,
u16 tclass,
u32 requested,
struct av_decision *avd);
+
+struct selinux_mapping {
+ u16 value; /* policy value */
+ unsigned num_perms;
+ u32 perms[sizeof(u32) * 8];
+};
+
+static struct selinux_mapping *current_mapping;
+static u16 current_mapping_size;
+
+static int selinux_set_mapping(struct policydb *pol,
+ struct security_class_mapping *map,
+ struct selinux_mapping **out_map_p,
+ u16 *out_map_size)
+{
+ struct selinux_mapping *out_map = NULL;
+ size_t size = sizeof(struct selinux_mapping);
+ u16 i, j;
+ unsigned k;
+ bool print_unknown_handle = false;
+
+ /* Find number of classes in the input mapping */
+ if (!map)
+ return -EINVAL;
+ i = 0;
+ while (map[i].name)
+ i++;
+
+ /* Allocate space for the class records, plus one for class zero */
+ out_map = kcalloc(++i, size, GFP_ATOMIC);
+ if (!out_map)
+ return -ENOMEM;
+
+ /* Store the raw class and permission values */
+ j = 0;
+ while (map[j].name) {
+ struct security_class_mapping *p_in = map + (j++);
+ struct selinux_mapping *p_out = out_map + j;
+
+ /* An empty class string skips ahead */
+ if (!strcmp(p_in->name, "")) {
+ p_out->num_perms = 0;
+ continue;
+ }
+
+ p_out->value = string_to_security_class(pol, p_in->name);
+ if (!p_out->value) {
+ printk(KERN_INFO
+ "SELinux: Class %s not defined in policy.\n",
+ p_in->name);
+ if (pol->reject_unknown)
+ goto err;
+ p_out->num_perms = 0;
+ print_unknown_handle = true;
+ continue;
+ }
+
+ k = 0;
+ while (p_in->perms && p_in->perms[k]) {
+ /* An empty permission string skips ahead */
+ if (!*p_in->perms[k]) {
+ k++;
+ continue;
+ }
+ p_out->perms[k] = string_to_av_perm(pol, p_out->value,
+ p_in->perms[k]);
+ if (!p_out->perms[k]) {
+ printk(KERN_INFO
+ "SELinux: Permission %s in class %s not defined in policy.\n",
+ p_in->perms[k], p_in->name);
+ if (pol->reject_unknown)
+ goto err;
+ print_unknown_handle = true;
+ }
+
+ k++;
+ }
+ p_out->num_perms = k;
+ }
+
+ if (print_unknown_handle)
+ printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
+ pol->allow_unknown ? "allowed" : "denied");
+
+ *out_map_p = out_map;
+ *out_map_size = i;
+ return 0;
+err:
+ kfree(out_map);
+ return -EINVAL;
+}
+
+/*
+ * Get real, policy values from mapped values
+ */
+
+static u16 unmap_class(u16 tclass)
+{
+ if (tclass < current_mapping_size)
+ return current_mapping[tclass].value;
+
+ return tclass;
+}
+
+static u32 unmap_perm(u16 tclass, u32 tperm)
+{
+ if (tclass < current_mapping_size) {
+ unsigned i;
+ u32 kperm = 0;
+
+ for (i = 0; i < current_mapping[tclass].num_perms; i++)
+ if (tperm & (1<<i)) {
+ kperm |= current_mapping[tclass].perms[i];
+ tperm &= ~(1<<i);
+ }
+ return kperm;
+ }
+
+ return tperm;
+}
+
+static void map_decision(u16 tclass, struct av_decision *avd,
+ int allow_unknown)
+{
+ if (tclass < current_mapping_size) {
+ unsigned i, n = current_mapping[tclass].num_perms;
+ u32 result;
+
+ for (i = 0, result = 0; i < n; i++) {
+ if (avd->allowed & current_mapping[tclass].perms[i])
+ result |= 1<<i;
+ if (allow_unknown && !current_mapping[tclass].perms[i])
+ result |= 1<<i;
+ }
+ avd->allowed = result;
+
+ for (i = 0, result = 0; i < n; i++)
+ if (avd->auditallow & current_mapping[tclass].perms[i])
+ result |= 1<<i;
+ avd->auditallow = result;
+
+ for (i = 0, result = 0; i < n; i++) {
+ if (avd->auditdeny & current_mapping[tclass].perms[i])
+ result |= 1<<i;
+ if (!allow_unknown && !current_mapping[tclass].perms[i])
+ result |= 1<<i;
+ }
+ /*
+ * In case the kernel has a bug and requests a permission
+ * between num_perms and the maximum permission number, we
+ * should audit that denial
+ */
+ for (; i < (sizeof(u32)*8); i++)
+ result |= 1<<i;
+ avd->auditdeny = result;
+ }
+}
+
+
/*
* Return the boolean value of a constraint expression
* when it is applied to the specified source and target
@@ -467,21 +620,9 @@ static int context_struct_compute_av(struct context *scontext,
struct class_datum *tclass_datum;
struct ebitmap *sattr, *tattr;
struct ebitmap_node *snode, *tnode;
- const struct selinux_class_perm *kdefs = &selinux_class_perm;
unsigned int i, j;
/*
- * Remap extended Netlink classes for old policy versions.
- * Do this here rather than socket_type_to_security_class()
- * in case a newer policy version is loaded, allowing sockets
- * to remain in the correct class.
- */
- if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
- if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
- tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
- tclass = SECCLASS_NETLINK_SOCKET;
-
- /*
* Initialize the access vectors to the default values.
*/
avd->allowed = 0;
@@ -490,33 +631,11 @@ static int context_struct_compute_av(struct context *scontext,
avd->seqno = latest_granting;
avd->flags = 0;
- /*
- * Check for all the invalid cases.
- * - tclass 0
- * - tclass > policy and > kernel
- * - tclass > policy but is a userspace class
- * - tclass > policy but we do not allow unknowns
- */
- if (unlikely(!tclass))
- goto inval_class;
- if (unlikely(tclass > policydb.p_classes.nprim))
- if (tclass > kdefs->cts_len ||
- !kdefs->class_to_string[tclass] ||
- !policydb.allow_unknown)
- goto inval_class;
-
- /*
- * Kernel class and we allow unknown so pad the allow decision
- * the pad will be all 1 for unknown classes.
- */
- if (tclass <= kdefs->cts_len && policydb.allow_unknown)
- avd->allowed = policydb.undefined_perms[tclass - 1];
-
- /*
- * Not in policy. Since decision is completed (all 1 or all 0) return.
- */
- if (unlikely(tclass > policydb.p_classes.nprim))
- return 0;
+ if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
+ if (printk_ratelimit())
+ printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass);
+ return -EINVAL;
+ }
tclass_datum = policydb.class_val_to_struct[tclass - 1];
@@ -568,8 +687,8 @@ static int context_struct_compute_av(struct context *scontext,
* role is changing, then check the (current_role, new_role)
* pair.
*/
- if (tclass == SECCLASS_PROCESS &&
- (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) &&
+ if (tclass == policydb.process_class &&
+ (avd->allowed & policydb.process_trans_perms) &&
scontext->role != tcontext->role) {
for (ra = policydb.role_allow; ra; ra = ra->next) {
if (scontext->role == ra->role &&
@@ -577,8 +696,7 @@ static int context_struct_compute_av(struct context *scontext,
break;
}
if (!ra)
- avd->allowed &= ~(PROCESS__TRANSITION |
- PROCESS__DYNTRANSITION);
+ avd->allowed &= ~policydb.process_trans_perms;
}
/*
@@ -590,21 +708,6 @@ static int context_struct_compute_av(struct context *scontext,
tclass, requested, avd);
return 0;
-
-inval_class:
- if (!tclass || tclass > kdefs->cts_len ||
- !kdefs->class_to_string[tclass]) {
- if (printk_ratelimit())
- printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
- __func__, tclass);
- return -EINVAL;
- }
-
- /*
- * Known to the kernel, but not to the policy.
- * Handle as a denial (allowed is 0).
- */
- return 0;
}
static int security_validtrans_handle_fail(struct context *ocontext,
@@ -636,13 +739,14 @@ out:
}
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
- u16 tclass)
+ u16 orig_tclass)
{
struct context *ocontext;
struct context *ncontext;
struct context *tcontext;
struct class_datum *tclass_datum;
struct constraint_node *constraint;
+ u16 tclass;
int rc = 0;
if (!ss_initialized)
@@ -650,16 +754,7 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
read_lock(&policy_rwlock);
- /*
- * Remap extended Netlink classes for old policy versions.
- * Do this here rather than socket_type_to_security_class()
- * in case a newer policy version is loaded, allowing sockets
- * to remain in the correct class.
- */
- if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
- if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
- tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
- tclass = SECCLASS_NETLINK_SOCKET;
+ tclass = unmap_class(orig_tclass);
if (!tclass || tclass > policydb.p_classes.nprim) {
printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
@@ -792,6 +887,38 @@ out:
}
+static int security_compute_av_core(u32 ssid,
+ u32 tsid,
+ u16 tclass,
+ u32 requested,
+ struct av_decision *avd)
+{
+ struct context *scontext = NULL, *tcontext = NULL;
+ int rc = 0;
+
+ scontext = sidtab_search(&sidtab, ssid);
+ if (!scontext) {
+ printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
+ __func__, ssid);
+ return -EINVAL;
+ }
+ tcontext = sidtab_search(&sidtab, tsid);
+ if (!tcontext) {
+ printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
+ __func__, tsid);
+ return -EINVAL;
+ }
+
+ rc = context_struct_compute_av(scontext, tcontext, tclass,
+ requested, avd);
+
+ /* permissive domain? */
+ if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
+ avd->flags |= AVD_FLAGS_PERMISSIVE;
+
+ return rc;
+}
+
/**
* security_compute_av - Compute access vector decisions.
* @ssid: source security identifier
@@ -807,12 +934,49 @@ out:
*/
int security_compute_av(u32 ssid,
u32 tsid,
- u16 tclass,
- u32 requested,
+ u16 orig_tclass,
+ u32 orig_requested,
struct av_decision *avd)
{
- struct context *scontext = NULL, *tcontext = NULL;
- int rc = 0;
+ u16 tclass;
+ u32 requested;
+ int rc;
+
+ read_lock(&policy_rwlock);
+
+ if (!ss_initialized)
+ goto allow;
+
+ requested = unmap_perm(orig_tclass, orig_requested);
+ tclass = unmap_class(orig_tclass);
+ if (unlikely(orig_tclass && !tclass)) {
+ if (policydb.allow_unknown)
+ goto allow;
+ rc = -EINVAL;
+ goto out;
+ }
+ rc = security_compute_av_core(ssid, tsid, tclass, requested, avd);
+ map_decision(orig_tclass, avd, policydb.allow_unknown);
+out:
+ read_unlock(&policy_rwlock);
+ return rc;
+allow:
+ avd->allowed = 0xffffffff;
+ avd->auditallow = 0;
+ avd->auditdeny = 0xffffffff;
+ avd->seqno = latest_granting;
+ avd->flags = 0;
+ rc = 0;
+ goto out;
+}
+
+int security_compute_av_user(u32 ssid,
+ u32 tsid,
+ u16 tclass,
+ u32 requested,
+ struct av_decision *avd)
+{
+ int rc;
if (!ss_initialized) {
avd->allowed = 0xffffffff;
@@ -823,29 +987,7 @@ int security_compute_av(u32 ssid,
}
read_lock(&policy_rwlock);
-
- scontext = sidtab_search(&sidtab, ssid);
- if (!scontext) {
- printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
- __func__, ssid);
- rc = -EINVAL;
- goto out;
- }
- tcontext = sidtab_search(&sidtab, tsid);
- if (!tcontext) {
- printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
- __func__, tsid);
- rc = -EINVAL;
- goto out;
- }
-
- rc = context_struct_compute_av(scontext, tcontext, tclass,
- requested, avd);
-
- /* permissive domain? */
- if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
- avd->flags |= AVD_FLAGS_PERMISSIVE;
-out:
+ rc = security_compute_av_core(ssid, tsid, tclass, requested, avd);
read_unlock(&policy_rwlock);
return rc;
}
@@ -1204,20 +1346,22 @@ out:
static int security_compute_sid(u32 ssid,
u32 tsid,
- u16 tclass,
+ u16 orig_tclass,
u32 specified,
- u32 *out_sid)
+ u32 *out_sid,
+ bool kern)
{
struct context *scontext = NULL, *tcontext = NULL, newcontext;
struct role_trans *roletr = NULL;
struct avtab_key avkey;
struct avtab_datum *avdatum;
struct avtab_node *node;
+ u16 tclass;
int rc = 0;
if (!ss_initialized) {
- switch (tclass) {
- case SECCLASS_PROCESS:
+ switch (orig_tclass) {
+ case SECCLASS_PROCESS: /* kernel value */
*out_sid = ssid;
break;
default:
@@ -1231,6 +1375,11 @@ static int security_compute_sid(u32 ssid,
read_lock(&policy_rwlock);
+ if (kern)
+ tclass = unmap_class(orig_tclass);
+ else
+ tclass = orig_tclass;
+
scontext = sidtab_search(&sidtab, ssid);
if (!scontext) {
printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
@@ -1260,13 +1409,11 @@ static int security_compute_sid(u32 ssid,
}
/* Set the role and type to default values. */
- switch (tclass) {
- case SECCLASS_PROCESS:
+ if (tclass == policydb.process_class) {
/* Use the current role and type of process. */
newcontext.role = scontext->role;
newcontext.type = scontext->type;
- break;
- default:
+ } else {
/* Use the well-defined object role. */
newcontext.role = OBJECT_R_VAL;
/* Use the type of the related object. */
@@ -1297,8 +1444,7 @@ static int security_compute_sid(u32 ssid,
}
/* Check for class-specific changes. */
- switch (tclass) {
- case SECCLASS_PROCESS:
+ if (tclass == policydb.process_class) {
if (specified & AVTAB_TRANSITION) {
/* Look for a role transition rule. */
for (roletr = policydb.role_tr; roletr;
@@ -1311,9 +1457,6 @@ static int security_compute_sid(u32 ssid,
}
}
}
- break;
- default:
- break;
}
/* Set the MLS attributes.
@@ -1358,7 +1501,17 @@ int security_transition_sid(u32 ssid,
u16 tclass,
u32 *out_sid)
{
- return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
+ return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
+ out_sid, true);
+}
+
+int security_transition_sid_user(u32 ssid,
+ u32 tsid,
+ u16 tclass,
+ u32 *out_sid)
+{
+ return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
+ out_sid, false);
}
/**
@@ -1379,7 +1532,8 @@ int security_member_sid(u32 ssid,
u16 tclass,
u32 *out_sid)
{
- return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
+ return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid,
+ false);
}
/**
@@ -1400,144 +1554,8 @@ int security_change_sid(u32 ssid,
u16 tclass,
u32 *out_sid)
{
- return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
-}
-
-/*
- * Verify that each kernel class that is defined in the
- * policy is correct
- */
-static int validate_classes(struct policydb *p)
-{
- int i, j;
- struct class_datum *cladatum;
- struct perm_datum *perdatum;
- u32 nprim, tmp, common_pts_len, perm_val, pol_val;
- u16 class_val;
- const struct selinux_class_perm *kdefs = &selinux_class_perm;
- const char *def_class, *def_perm, *pol_class;
- struct symtab *perms;
- bool print_unknown_handle = 0;
-
- if (p->allow_unknown) {
- u32 num_classes = kdefs->cts_len;
- p->undefined_perms = kcalloc(num_classes, sizeof(u32), GFP_KERNEL);
- if (!p->undefined_perms)
- return -ENOMEM;
- }
-
- for (i = 1; i < kdefs->cts_len; i++) {
- def_class = kdefs->class_to_string[i];
- if (!def_class)
- continue;
- if (i > p->p_classes.nprim) {
- printk(KERN_INFO
- "SELinux: class %s not defined in policy\n",
- def_class);
- if (p->reject_unknown)
- return -EINVAL;
- if (p->allow_unknown)
- p->undefined_perms[i-1] = ~0U;
- print_unknown_handle = 1;
- continue;
- }
- pol_class = p->p_class_val_to_name[i-1];
- if (strcmp(pol_class, def_class)) {
- printk(KERN_ERR
- "SELinux: class %d is incorrect, found %s but should be %s\n",
- i, pol_class, def_class);
- return -EINVAL;
- }
- }
- for (i = 0; i < kdefs->av_pts_len; i++) {
- class_val = kdefs->av_perm_to_string[i].tclass;
- perm_val = kdefs->av_perm_to_string[i].value;
- def_perm = kdefs->av_perm_to_string[i].name;
- if (class_val > p->p_classes.nprim)
- continue;
- pol_class = p->p_class_val_to_name[class_val-1];
- cladatum = hashtab_search(p->p_classes.table, pol_class);
- BUG_ON(!cladatum);
- perms = &cladatum->permissions;
- nprim = 1 << (perms->nprim - 1);
- if (perm_val > nprim) {
- printk(KERN_INFO
- "SELinux: permission %s in class %s not defined in policy\n",
- def_perm, pol_class);
- if (p->reject_unknown)
- return -EINVAL;
- if (p->allow_unknown)
- p->undefined_perms[class_val-1] |= perm_val;
- print_unknown_handle = 1;
- continue;
- }
- perdatum = hashtab_search(perms->table, def_perm);
- if (perdatum == NULL) {
- printk(KERN_ERR
- "SELinux: permission %s in class %s not found in policy, bad policy\n",
- def_perm, pol_class);
- return -EINVAL;
- }
- pol_val = 1 << (perdatum->value - 1);
- if (pol_val != perm_val) {
- printk(KERN_ERR
- "SELinux: permission %s in class %s has incorrect value\n",
- def_perm, pol_class);
- return -EINVAL;
- }
- }
- for (i = 0; i < kdefs->av_inherit_len; i++) {
- class_val = kdefs->av_inherit[i].tclass;
- if (class_val > p->p_classes.nprim)
- continue;
- pol_class = p->p_class_val_to_name[class_val-1];
- cladatum = hashtab_search(p->p_classes.table, pol_class);
- BUG_ON(!cladatum);
- if (!cladatum->comdatum) {
- printk(KERN_ERR
- "SELinux: class %s should have an inherits clause but does not\n",
- pol_class);
- return -EINVAL;
- }
- tmp = kdefs->av_inherit[i].common_base;
- common_pts_len = 0;
- while (!(tmp & 0x01)) {
- common_pts_len++;
- tmp >>= 1;
- }
- perms = &cladatum->comdatum->permissions;
- for (j = 0; j < common_pts_len; j++) {
- def_perm = kdefs->av_inherit[i].common_pts[j];
- if (j >= perms->nprim) {
- printk(KERN_INFO
- "SELinux: permission %s in class %s not defined in policy\n",
- def_perm, pol_class);
- if (p->reject_unknown)
- return -EINVAL;
- if (p->allow_unknown)
- p->undefined_perms[class_val-1] |= (1 << j);
- print_unknown_handle = 1;
- continue;
- }
- perdatum = hashtab_search(perms->table, def_perm);
- if (perdatum == NULL) {
- printk(KERN_ERR
- "SELinux: permission %s in class %s not found in policy, bad policy\n",
- def_perm, pol_class);
- return -EINVAL;
- }
- if (perdatum->value != j + 1) {
- printk(KERN_ERR
- "SELinux: permission %s in class %s has incorrect value\n",
- def_perm, pol_class);
- return -EINVAL;
- }
- }
- }
- if (print_unknown_handle)
- printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
- (security_get_allow_unknown() ? "allowed" : "denied"));
- return 0;
+ return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid,
+ false);
}
/* Clone the SID into the new SID table. */
@@ -1710,8 +1728,10 @@ int security_load_policy(void *data, size_t len)
{
struct policydb oldpolicydb, newpolicydb;
struct sidtab oldsidtab, newsidtab;
+ struct selinux_mapping *oldmap, *map = NULL;
struct convert_context_args args;
u32 seqno;
+ u16 map_size;
int rc = 0;
struct policy_file file = { data, len }, *fp = &file;
@@ -1721,22 +1741,19 @@ int security_load_policy(void *data, size_t len)
avtab_cache_destroy();
return -EINVAL;
}
- if (policydb_load_isids(&policydb, &sidtab)) {
+ if (selinux_set_mapping(&policydb, secclass_map,
+ &current_mapping,
+ &current_mapping_size)) {
policydb_destroy(&policydb);
avtab_cache_destroy();
return -EINVAL;
}
- /* Verify that the kernel defined classes are correct. */
- if (validate_classes(&policydb)) {
- printk(KERN_ERR
- "SELinux: the definition of a class is incorrect\n");
- sidtab_destroy(&sidtab);
+ if (policydb_load_isids(&policydb, &sidtab)) {
policydb_destroy(&policydb);
avtab_cache_destroy();
return -EINVAL;
}
security_load_policycaps();
- policydb_loaded_version = policydb.policyvers;
ss_initialized = 1;
seqno = ++latest_granting;
selinux_complete_init();
@@ -1759,13 +1776,9 @@ int security_load_policy(void *data, size_t len)
return -ENOMEM;
}
- /* Verify that the kernel defined classes are correct. */
- if (validate_classes(&newpolicydb)) {
- printk(KERN_ERR
- "SELinux: the definition of a class is incorrect\n");
- rc = -EINVAL;
+ if (selinux_set_mapping(&newpolicydb, secclass_map,
+ &map, &map_size))
goto err;
- }
rc = security_preserve_bools(&newpolicydb);
if (rc) {
@@ -1799,13 +1812,16 @@ int security_load_policy(void *data, size_t len)
memcpy(&policydb, &newpolicydb, sizeof policydb);
sidtab_set(&sidtab, &newsidtab);
security_load_policycaps();
+ oldmap = current_mapping;
+ current_mapping = map;
+ current_mapping_size = map_size;
seqno = ++latest_granting;
- policydb_loaded_version = policydb.policyvers;
write_unlock_irq(&policy_rwlock);
/* Free the old policydb and SID table. */
policydb_destroy(&oldpolicydb);
sidtab_destroy(&oldsidtab);
+ kfree(oldmap);
avc_ss_reset(seqno);
selnl_notify_policyload(seqno);
@@ -1815,6 +1831,7 @@ int security_load_policy(void *data, size_t len)
return 0;
err:
+ kfree(map);
sidtab_destroy(&newsidtab);
policydb_destroy(&newpolicydb);
return rc;
@@ -2091,7 +2108,7 @@ out_unlock:
}
for (i = 0, j = 0; i < mynel; i++) {
rc = avc_has_perm_noaudit(fromsid, mysids[i],
- SECCLASS_PROCESS,
+ SECCLASS_PROCESS, /* kernel value */
PROCESS__TRANSITION, AVC_STRICT,
NULL);
if (!rc)
@@ -2119,10 +2136,11 @@ out:
*/
int security_genfs_sid(const char *fstype,
char *path,
- u16 sclass,
+ u16 orig_sclass,
u32 *sid)
{
int len;
+ u16 sclass;
struct genfs *genfs;
struct ocontext *c;
int rc = 0, cmp = 0;
@@ -2132,6 +2150,8 @@ int security_genfs_sid(const char *fstype,
read_lock(&policy_rwlock);
+ sclass = unmap_class(orig_sclass);
+
for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
cmp = strcmp(fstype, genfs->fstype);
if (cmp <= 0)
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 3c8bd8ee0b95..e0d0354008b7 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -187,6 +187,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
const s8 pattern_type, const s8 end_type,
const char *function)
{
+ const char *const start = filename;
+ bool in_repetition = false;
bool contains_pattern = false;
unsigned char c;
unsigned char d;
@@ -212,9 +214,13 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
if (c == '/')
goto out;
}
- while ((c = *filename++) != '\0') {
+ while (1) {
+ c = *filename++;
+ if (!c)
+ break;
if (c == '\\') {
- switch ((c = *filename++)) {
+ c = *filename++;
+ switch (c) {
case '\\': /* "\\" */
continue;
case '$': /* "\$" */
@@ -231,6 +237,22 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
break; /* Must not contain pattern */
contains_pattern = true;
continue;
+ case '{': /* "/\{" */
+ if (filename - 3 < start ||
+ *(filename - 3) != '/')
+ break;
+ if (pattern_type == -1)
+ break; /* Must not contain pattern */
+ contains_pattern = true;
+ in_repetition = true;
+ continue;
+ case '}': /* "\}/" */
+ if (*filename != '/')
+ break;
+ if (!in_repetition)
+ break;
+ in_repetition = false;
+ continue;
case '0': /* "\ooo" */
case '1':
case '2':
@@ -246,6 +268,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
continue; /* pattern is not \000 */
}
goto out;
+ } else if (in_repetition && c == '/') {
+ goto out;
} else if (tomoyo_is_invalid(c)) {
goto out;
}
@@ -254,6 +278,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
if (!contains_pattern)
goto out;
}
+ if (in_repetition)
+ goto out;
return true;
out:
printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function,
@@ -360,33 +386,6 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
}
/**
- * tomoyo_path_depth - Evaluate the number of '/' in a string.
- *
- * @pathname: The string to evaluate.
- *
- * Returns path depth of the string.
- *
- * I score 2 for each of the '/' in the @pathname
- * and score 1 if the @pathname ends with '/'.
- */
-static int tomoyo_path_depth(const char *pathname)
-{
- int i = 0;
-
- if (pathname) {
- const char *ep = pathname + strlen(pathname);
- if (pathname < ep--) {
- if (*ep != '/')
- i++;
- while (pathname <= ep)
- if (*ep-- == '/')
- i += 2;
- }
- }
- return i;
-}
-
-/**
* tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
*
* @filename: The string to evaluate.
@@ -444,11 +443,10 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
ptr->is_dir = len && (name[len - 1] == '/');
ptr->is_patterned = (ptr->const_len < len);
ptr->hash = full_name_hash(name, len);
- ptr->depth = tomoyo_path_depth(name);
}
/**
- * tomoyo_file_matches_to_pattern2 - Pattern matching without '/' character
+ * tomoyo_file_matches_pattern2 - Pattern matching without '/' character
* and "\-" pattern.
*
* @filename: The start of string to check.
@@ -458,10 +456,10 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
*
* Returns true if @filename matches @pattern, false otherwise.
*/
-static bool tomoyo_file_matches_to_pattern2(const char *filename,
- const char *filename_end,
- const char *pattern,
- const char *pattern_end)
+static bool tomoyo_file_matches_pattern2(const char *filename,
+ const char *filename_end,
+ const char *pattern,
+ const char *pattern_end)
{
while (filename < filename_end && pattern < pattern_end) {
char c;
@@ -519,7 +517,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
case '*':
case '@':
for (i = 0; i <= filename_end - filename; i++) {
- if (tomoyo_file_matches_to_pattern2(
+ if (tomoyo_file_matches_pattern2(
filename + i, filename_end,
pattern + 1, pattern_end))
return true;
@@ -550,7 +548,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
j++;
}
for (i = 1; i <= j; i++) {
- if (tomoyo_file_matches_to_pattern2(
+ if (tomoyo_file_matches_pattern2(
filename + i, filename_end,
pattern + 1, pattern_end))
return true;
@@ -567,7 +565,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
}
/**
- * tomoyo_file_matches_to_pattern - Pattern matching without without '/' character.
+ * tomoyo_file_matches_pattern - Pattern matching without without '/' character.
*
* @filename: The start of string to check.
* @filename_end: The end of string to check.
@@ -576,7 +574,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
*
* Returns true if @filename matches @pattern, false otherwise.
*/
-static bool tomoyo_file_matches_to_pattern(const char *filename,
+static bool tomoyo_file_matches_pattern(const char *filename,
const char *filename_end,
const char *pattern,
const char *pattern_end)
@@ -589,10 +587,10 @@ static bool tomoyo_file_matches_to_pattern(const char *filename,
/* Split at "\-" pattern. */
if (*pattern++ != '\\' || *pattern++ != '-')
continue;
- result = tomoyo_file_matches_to_pattern2(filename,
- filename_end,
- pattern_start,
- pattern - 2);
+ result = tomoyo_file_matches_pattern2(filename,
+ filename_end,
+ pattern_start,
+ pattern - 2);
if (first)
result = !result;
if (result)
@@ -600,13 +598,79 @@ static bool tomoyo_file_matches_to_pattern(const char *filename,
first = false;
pattern_start = pattern;
}
- result = tomoyo_file_matches_to_pattern2(filename, filename_end,
- pattern_start, pattern_end);
+ result = tomoyo_file_matches_pattern2(filename, filename_end,
+ pattern_start, pattern_end);
return first ? result : !result;
}
/**
+ * tomoyo_path_matches_pattern2 - Do pathname pattern matching.
+ *
+ * @f: The start of string to check.
+ * @p: The start of pattern to compare.
+ *
+ * Returns true if @f matches @p, false otherwise.
+ */
+static bool tomoyo_path_matches_pattern2(const char *f, const char *p)
+{
+ const char *f_delimiter;
+ const char *p_delimiter;
+
+ while (*f && *p) {
+ f_delimiter = strchr(f, '/');
+ if (!f_delimiter)
+ f_delimiter = f + strlen(f);
+ p_delimiter = strchr(p, '/');
+ if (!p_delimiter)
+ p_delimiter = p + strlen(p);
+ if (*p == '\\' && *(p + 1) == '{')
+ goto recursive;
+ if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
+ p_delimiter))
+ return false;
+ f = f_delimiter;
+ if (*f)
+ f++;
+ p = p_delimiter;
+ if (*p)
+ p++;
+ }
+ /* Ignore trailing "\*" and "\@" in @pattern. */
+ while (*p == '\\' &&
+ (*(p + 1) == '*' || *(p + 1) == '@'))
+ p += 2;
+ return !*f && !*p;
+ recursive:
+ /*
+ * The "\{" pattern is permitted only after '/' character.
+ * This guarantees that below "*(p - 1)" is safe.
+ * Also, the "\}" pattern is permitted only before '/' character
+ * so that "\{" + "\}" pair will not break the "\-" operator.
+ */
+ if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
+ *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
+ return false; /* Bad pattern. */
+ do {
+ /* Compare current component with pattern. */
+ if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
+ p_delimiter - 2))
+ break;
+ /* Proceed to next component. */
+ f = f_delimiter;
+ if (!*f)
+ break;
+ f++;
+ /* Continue comparison. */
+ if (tomoyo_path_matches_pattern2(f, p_delimiter + 1))
+ return true;
+ f_delimiter = strchr(f, '/');
+ } while (f_delimiter);
+ return false; /* Not matched. */
+}
+
+/**
* tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
+ *
* @filename: The filename to check.
* @pattern: The pattern to compare.
*
@@ -615,24 +679,24 @@ static bool tomoyo_file_matches_to_pattern(const char *filename,
* The following patterns are available.
* \\ \ itself.
* \ooo Octal representation of a byte.
- * \* More than or equals to 0 character other than '/'.
- * \@ More than or equals to 0 character other than '/' or '.'.
+ * \* Zero or more repetitions of characters other than '/'.
+ * \@ Zero or more repetitions of characters other than '/' or '.'.
* \? 1 byte character other than '/'.
- * \$ More than or equals to 1 decimal digit.
+ * \$ One or more repetitions of decimal digits.
* \+ 1 decimal digit.
- * \X More than or equals to 1 hexadecimal digit.
+ * \X One or more repetitions of hexadecimal digits.
* \x 1 hexadecimal digit.
- * \A More than or equals to 1 alphabet character.
+ * \A One or more repetitions of alphabet characters.
* \a 1 alphabet character.
+ *
* \- Subtraction operator.
+ *
+ * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
+ * /dir/dir/dir/ ).
*/
bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
const struct tomoyo_path_info *pattern)
{
- /*
- if (!filename || !pattern)
- return false;
- */
const char *f = filename->name;
const char *p = pattern->name;
const int len = pattern->const_len;
@@ -640,37 +704,15 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
/* If @pattern doesn't contain pattern, I can use strcmp(). */
if (!pattern->is_patterned)
return !tomoyo_pathcmp(filename, pattern);
- /* Dont compare if the number of '/' differs. */
- if (filename->depth != pattern->depth)
+ /* Don't compare directory and non-directory. */
+ if (filename->is_dir != pattern->is_dir)
return false;
/* Compare the initial length without patterns. */
if (strncmp(f, p, len))
return false;
f += len;
p += len;
- /* Main loop. Compare each directory component. */
- while (*f && *p) {
- const char *f_delimiter = strchr(f, '/');
- const char *p_delimiter = strchr(p, '/');
- if (!f_delimiter)
- f_delimiter = f + strlen(f);
- if (!p_delimiter)
- p_delimiter = p + strlen(p);
- if (!tomoyo_file_matches_to_pattern(f, f_delimiter,
- p, p_delimiter))
- return false;
- f = f_delimiter;
- if (*f)
- f++;
- p = p_delimiter;
- if (*p)
- p++;
- }
- /* Ignore trailing "\*" and "\@" in @pattern. */
- while (*p == '\\' &&
- (*(p + 1) == '*' || *(p + 1) == '@'))
- p += 2;
- return !*f && !*p;
+ return tomoyo_path_matches_pattern2(f, p);
}
/**
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 31df541911f7..92169d29b2db 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -56,9 +56,6 @@ struct tomoyo_page_buffer {
* (5) "is_patterned" is a bool which is true if "name" contains wildcard
* characters, false otherwise. This allows TOMOYO to use "hash" and
* strcmp() for string comparison if "is_patterned" is false.
- * (6) "depth" is calculated using the number of "/" characters in "name".
- * This allows TOMOYO to avoid comparing two pathnames which never match
- * (e.g. whether "/var/www/html/index.html" matches "/tmp/sh-thd-\$").
*/
struct tomoyo_path_info {
const char *name;
@@ -66,7 +63,6 @@ struct tomoyo_path_info {
u16 const_len; /* = tomoyo_const_part_length(name) */
bool is_dir; /* = tomoyo_strendswith(name, "/") */
bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
- u16 depth; /* = tomoyo_path_depth(name) */
};
/*
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 5f2e33263371..917f564cdab1 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -13,6 +13,8 @@
#include <linux/mount.h>
#include <linux/mnt_namespace.h>
#include <linux/fs_struct.h>
+#include <linux/hash.h>
+
#include "common.h"
#include "realpath.h"
@@ -263,7 +265,8 @@ static unsigned int tomoyo_quota_for_savename;
* table. Frequency of appending strings is very low. So we don't need
* large (e.g. 64k) hash size. 256 will be sufficient.
*/
-#define TOMOYO_MAX_HASH 256
+#define TOMOYO_HASH_BITS 8
+#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS)
/*
* tomoyo_name_entry is a structure which is used for linking
@@ -315,6 +318,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
struct tomoyo_free_memory_block_list *fmb;
int len;
char *cp;
+ struct list_head *head;
if (!name)
return NULL;
@@ -325,9 +329,10 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
return NULL;
}
hash = full_name_hash((const unsigned char *) name, len - 1);
+ head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
+
mutex_lock(&lock);
- list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH],
- list) {
+ list_for_each_entry(ptr, head, list) {
if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name))
goto out;
}
@@ -365,7 +370,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
tomoyo_fill_path_info(&ptr->entry);
fmb->ptr += len;
fmb->len -= len;
- list_add_tail(&ptr->list, &tomoyo_name_list[hash % TOMOYO_MAX_HASH]);
+ list_add_tail(&ptr->list, head);
if (fmb->len == 0) {
list_del(&fmb->list);
kfree(fmb);
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 1f0f8213e2d5..6c160a038b23 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -504,6 +504,10 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
int err;
aaci_pcm_hw_free(substream);
+ if (aacirun->pcm_open) {
+ snd_ac97_pcm_close(aacirun->pcm);
+ aacirun->pcm_open = 0;
+ }
err = devdma_hw_alloc(NULL, substream,
params_buffer_bytes(params));
@@ -517,7 +521,7 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
else
err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
params_channels(params),
- aacirun->pcm->r[1].slots);
+ aacirun->pcm->r[0].slots);
if (err)
goto out;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 0c1440121c22..c69c60b2a48a 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -953,11 +953,12 @@ static int snd_pcm_dev_register(struct snd_device *device)
struct snd_pcm_substream *substream;
struct snd_pcm_notify *notify;
char str[16];
- struct snd_pcm *pcm = device->device_data;
+ struct snd_pcm *pcm;
struct device *dev;
- if (snd_BUG_ON(!pcm || !device))
+ if (snd_BUG_ON(!device || !device->device_data))
return -ENXIO;
+ pcm = device->device_data;
mutex_lock(&register_mutex);
err = snd_pcm_add(pcm);
if (err) {
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index c0adc14c91f0..70d6f25ba526 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -248,7 +248,8 @@ static int assign_substream(struct snd_rawmidi *rmidi, int subdevice,
list_for_each_entry(substream, &s->substreams, list) {
if (substream->opened) {
if (stream == SNDRV_RAWMIDI_STREAM_INPUT ||
- !(mode & SNDRV_RAWMIDI_LFLG_APPEND))
+ !(mode & SNDRV_RAWMIDI_LFLG_APPEND) ||
+ !substream->append)
continue;
}
if (subdevice < 0 || subdevice == substream->number) {
@@ -266,17 +267,21 @@ static int open_substream(struct snd_rawmidi *rmidi,
{
int err;
- err = snd_rawmidi_runtime_create(substream);
- if (err < 0)
- return err;
- err = substream->ops->open(substream);
- if (err < 0)
- return err;
- substream->opened = 1;
- if (substream->use_count++ == 0)
+ if (substream->use_count == 0) {
+ err = snd_rawmidi_runtime_create(substream);
+ if (err < 0)
+ return err;
+ err = substream->ops->open(substream);
+ if (err < 0) {
+ snd_rawmidi_runtime_free(substream);
+ return err;
+ }
+ substream->opened = 1;
substream->active_sensing = 0;
- if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
- substream->append = 1;
+ if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
+ substream->append = 1;
+ }
+ substream->use_count++;
rmidi->streams[substream->stream].substream_opened++;
return 0;
}
@@ -297,27 +302,27 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
SNDRV_RAWMIDI_STREAM_INPUT,
mode, &sinput);
if (err < 0)
- goto __error;
+ return err;
}
if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
err = assign_substream(rmidi, subdevice,
SNDRV_RAWMIDI_STREAM_OUTPUT,
mode, &soutput);
if (err < 0)
- goto __error;
+ return err;
}
if (sinput) {
err = open_substream(rmidi, sinput, mode);
if (err < 0)
- goto __error;
+ return err;
}
if (soutput) {
err = open_substream(rmidi, soutput, mode);
if (err < 0) {
if (sinput)
close_substream(rmidi, sinput, 0);
- goto __error;
+ return err;
}
}
@@ -325,13 +330,6 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
rfile->input = sinput;
rfile->output = soutput;
return 0;
-
- __error:
- if (sinput && sinput->runtime)
- snd_rawmidi_runtime_free(sinput);
- if (soutput && soutput->runtime)
- snd_rawmidi_runtime_free(soutput);
- return err;
}
/* called from sound/core/seq/seq_midi.c */
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 6ba066c41d2e..252e04ce602f 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -165,7 +165,7 @@ MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
module_param_array(pcm_devs, int, NULL, 0444);
MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
module_param_array(pcm_substreams, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-16) for dummy driver.");
+MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
//module_param_array(midi_devs, int, NULL, 0444);
//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
module_param(fake_buffer, bool, 0444);
@@ -808,8 +808,6 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
unsigned int idx;
int err;
- if (snd_BUG_ON(!dummy))
- return -EINVAL;
spin_lock_init(&dummy->mixer_lock);
strcpy(card->mixername, "Dummy Mixer");
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index 84cc2658c05b..e1145ac6e908 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -39,25 +39,20 @@ static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
/* write the port and returns the next expire time in ns;
* called at the trigger-start and in hrtimer callback
*/
-static unsigned long pcsp_timer_update(struct hrtimer *handle)
+static u64 pcsp_timer_update(struct snd_pcsp *chip)
{
unsigned char timer_cnt, val;
u64 ns;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
- struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
unsigned long flags;
if (chip->thalf) {
outb(chip->val61, 0x61);
chip->thalf = 0;
- if (!atomic_read(&chip->timer_active))
- return 0;
return chip->ns_rem;
}
- if (!atomic_read(&chip->timer_active))
- return 0;
substream = chip->playback_substream;
if (!substream)
return 0;
@@ -88,24 +83,17 @@ static unsigned long pcsp_timer_update(struct hrtimer *handle)
return ns;
}
-enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
+static void pcsp_pointer_update(struct snd_pcsp *chip)
{
- struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
struct snd_pcm_substream *substream;
- int periods_elapsed, pointer_update;
size_t period_bytes, buffer_bytes;
- unsigned long ns;
+ int periods_elapsed;
unsigned long flags;
- pointer_update = !chip->thalf;
- ns = pcsp_timer_update(handle);
- if (!ns)
- return HRTIMER_NORESTART;
-
/* update the playback position */
substream = chip->playback_substream;
if (!substream)
- return HRTIMER_NORESTART;
+ return;
period_bytes = snd_pcm_lib_period_bytes(substream);
buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
@@ -134,6 +122,26 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
if (periods_elapsed)
tasklet_schedule(&pcsp_pcm_tasklet);
+}
+
+enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
+{
+ struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
+ int pointer_update;
+ u64 ns;
+
+ if (!atomic_read(&chip->timer_active) || !chip->playback_substream)
+ return HRTIMER_NORESTART;
+
+ pointer_update = !chip->thalf;
+ ns = pcsp_timer_update(chip);
+ if (!ns) {
+ printk(KERN_WARNING "PCSP: unexpected stop\n");
+ return HRTIMER_NORESTART;
+ }
+
+ if (pointer_update)
+ pcsp_pointer_update(chip);
hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns));
@@ -142,8 +150,6 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
static int pcsp_start_playing(struct snd_pcsp *chip)
{
- unsigned long ns;
-
#if PCSP_DEBUG
printk(KERN_INFO "PCSP: start_playing called\n");
#endif
@@ -159,11 +165,7 @@ static int pcsp_start_playing(struct snd_pcsp *chip)
atomic_set(&chip->timer_active, 1);
chip->thalf = 0;
- ns = pcsp_timer_update(&pcsp_chip.timer);
- if (!ns)
- return -EIO;
-
- hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL);
+ hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL);
return 0;
}
@@ -232,21 +234,22 @@ static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
+ pcsp_sync_stop(chip);
+ chip->playback_ptr = 0;
+ chip->period_ptr = 0;
+ chip->fmt_size =
+ snd_pcm_format_physical_width(substream->runtime->format) >> 3;
+ chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
#if PCSP_DEBUG
printk(KERN_INFO "PCSP: prepare called, "
- "size=%zi psize=%zi f=%zi f1=%i\n",
+ "size=%zi psize=%zi f=%zi f1=%i fsize=%i\n",
snd_pcm_lib_buffer_bytes(substream),
snd_pcm_lib_period_bytes(substream),
snd_pcm_lib_buffer_bytes(substream) /
snd_pcm_lib_period_bytes(substream),
- substream->runtime->periods);
+ substream->runtime->periods,
+ chip->fmt_size);
#endif
- pcsp_sync_stop(chip);
- chip->playback_ptr = 0;
- chip->period_ptr = 0;
- chip->fmt_size =
- snd_pcm_format_physical_width(substream->runtime->format) >> 3;
- chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
return 0;
}
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c
index 199b03377142..903bc846763f 100644
--- a/sound/drivers/pcsp/pcsp_mixer.c
+++ b/sound/drivers/pcsp/pcsp_mixer.c
@@ -72,7 +72,7 @@ static int pcsp_treble_put(struct snd_kcontrol *kcontrol,
if (treble != chip->treble) {
chip->treble = treble;
#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: rate set to %i\n", PCSP_RATE());
+ printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE());
#endif
changed = 1;
}
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index 793b7f478433..3f3c3f71db4b 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -219,7 +219,9 @@ static int shared_resources_initialised;
* Mid level stuff
*/
-struct sound_settings dmasound = { .lock = SPIN_LOCK_UNLOCKED };
+struct sound_settings dmasound = {
+ .lock = __SPIN_LOCK_UNLOCKED(dmasound.lock)
+};
static inline void sound_silence(void)
{
diff --git a/sound/oss/hex2hex.c b/sound/oss/hex2hex.c
index 5460faae98c9..041ef5c52bc2 100644
--- a/sound/oss/hex2hex.c
+++ b/sound/oss/hex2hex.c
@@ -12,7 +12,7 @@
#define MAX_SIZE (256*1024)
unsigned char buf[MAX_SIZE];
-int loadhex(FILE *inf, unsigned char *buf)
+static int loadhex(FILE *inf, unsigned char *buf)
{
int l=0, c, i;
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c
index 77d0e5efda76..ce4db49291f7 100644
--- a/sound/oss/sb_common.c
+++ b/sound/oss/sb_common.c
@@ -157,7 +157,7 @@ static void sb_intr (sb_devc *devc)
break;
default:
- /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */
+ /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
;
}
}
@@ -177,7 +177,7 @@ static void sb_intr (sb_devc *devc)
break;
default:
- /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */
+ /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
;
}
}
diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c
index 180e95c87e3e..51a3d381a59e 100644
--- a/sound/oss/sb_ess.c
+++ b/sound/oss/sb_ess.c
@@ -782,7 +782,7 @@ printk(KERN_INFO "FKS: ess_handle_channel %s irq_mode=%d\n", channel, irq_mode);
break;
default:;
- /* printk(KERN_WARN "ESS: Unexpected interrupt\n"); */
+ /* printk(KERN_WARNING "ESS: Unexpected interrupt\n"); */
}
}
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index e924492df21d..f47f9e226b08 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -624,6 +624,9 @@ snd_harmony_pcm_init(struct snd_harmony *h)
struct snd_pcm *pcm;
int err;
+ if (snd_BUG_ON(!h))
+ return -EINVAL;
+
harmony_disable_interrupts(h);
err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm);
@@ -865,11 +868,12 @@ snd_harmony_mixer_reset(struct snd_harmony *h)
static int __devinit
snd_harmony_mixer_init(struct snd_harmony *h)
{
- struct snd_card *card = h->card;
+ struct snd_card *card;
int idx, err;
if (snd_BUG_ON(!h))
return -EINVAL;
+ card = h->card;
strcpy(card->mixername, "Harmony Gain control interface");
for (idx = 0; idx < HARMONY_CONTROLS; idx++) {
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index fb5ee3cc3968..75c602b5b132 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -259,7 +259,6 @@ config SND_CS5530
config SND_CS5535AUDIO
tristate "CS5535/CS5536 Audio"
- depends on X86 && !X86_64
select SND_PCM
select SND_AC97_CODEC
help
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index b458d208720b..aaf4da68969c 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -973,7 +973,7 @@ static void snd_ali_free_voice(struct snd_ali * codec,
void *private_data;
snd_ali_printk("free_voice: channel=%d\n",pvoice->number);
- if (pvoice == NULL || !pvoice->use)
+ if (!pvoice->use)
return;
snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
spin_lock_irq(&codec->voice_alloc);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c9ad182e1b4b..6517f589d01d 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -722,9 +722,10 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
chip->last_cmd[addr]);
chip->single_cmd = 1;
bus->response_reset = 0;
- /* re-initialize CORB/RIRB */
+ /* release CORB/RIRB */
azx_free_cmd_io(chip);
- azx_init_cmd_io(chip);
+ /* disable unsolicited responses */
+ azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_UNSOL);
return -1;
}
@@ -865,7 +866,9 @@ static int azx_reset(struct azx *chip)
}
/* Accept unsolicited responses */
- azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL);
+ if (!chip->single_cmd)
+ azx_writel(chip, GCTL, azx_readl(chip, GCTL) |
+ ICH6_GCTL_UNSOL);
/* detect codecs */
if (!chip->codec_mask) {
@@ -980,7 +983,8 @@ static void azx_init_chip(struct azx *chip)
azx_int_enable(chip);
/* initialize the codec command I/O */
- azx_init_cmd_io(chip);
+ if (!chip->single_cmd)
+ azx_init_cmd_io(chip);
/* program the position buffer */
azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
@@ -2674,6 +2678,7 @@ static struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
+ { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 3fbbc8c01e70..905859d4f4df 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -110,6 +110,7 @@ struct conexant_spec {
unsigned int dell_automute;
unsigned int port_d_mode;
+ unsigned char ext_mic_bias;
};
static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -1927,6 +1928,11 @@ static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
#define CXT5066_SPDIF_OUT 0x21
+/* OLPC's microphone port is DC coupled for use with external sensors,
+ * therefore we use a 50% mic bias in order to center the input signal with
+ * the DC input range of the codec. */
+#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
+
static struct hda_channel_mode cxt5066_modes[1] = {
{ 2, NULL },
};
@@ -1980,9 +1986,10 @@ static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
/* toggle input of built-in and mic jack appropriately */
static void cxt5066_automic(struct hda_codec *codec)
{
- static struct hda_verb ext_mic_present[] = {
+ struct conexant_spec *spec = codec->spec;
+ struct hda_verb ext_mic_present[] = {
/* enable external mic, port B */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias},
/* switch to external mic input */
{0x17, AC_VERB_SET_CONNECT_SEL, 0},
@@ -2235,7 +2242,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
/* Port B: external microphone */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS},
/* Port C: internal microphone */
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -2325,6 +2332,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
CXT5066_LAPTOP),
SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
CXT5066_DELL_LAPTOP),
+ SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
{}
};
@@ -2352,6 +2360,7 @@ static int patch_cxt5066(struct hda_codec *codec)
spec->input_mux = &cxt5066_capture_source;
spec->port_d_mode = PIN_HP;
+ spec->ext_mic_bias = PIN_VREF80;
spec->num_init_verbs = 1;
spec->init_verbs[0] = cxt5066_init_verbs;
@@ -2383,6 +2392,7 @@ static int patch_cxt5066(struct hda_codec *codec)
spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
spec->mixers[spec->num_mixers++] = cxt5066_mixers;
spec->port_d_mode = 0;
+ spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS;
/* no S/PDIF out */
spec->multiout.dig_out_nid = 0;
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 9fb60276f5c9..6afdab09bab7 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -397,6 +397,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
{ .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
+ { .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
@@ -406,6 +407,7 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
MODULE_ALIAS("snd-hda-codec-id:10de0002");
MODULE_ALIAS("snd-hda-codec-id:10de0003");
+MODULE_ALIAS("snd-hda-codec-id:10de0005");
MODULE_ALIAS("snd-hda-codec-id:10de0006");
MODULE_ALIAS("snd-hda-codec-id:10de0007");
MODULE_ALIAS("snd-hda-codec-id:10de0067");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c08ca660daba..70583719282b 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -965,6 +965,8 @@ static void alc_automute_pin(struct hda_codec *codec)
unsigned int nid = spec->autocfg.hp_pins[0];
int i;
+ if (!nid)
+ return;
pincap = snd_hda_query_pin_caps(codec, nid);
if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -4682,9 +4684,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
spec->multiout.dig_out_nid = dig_nid;
else {
spec->multiout.slave_dig_outs = spec->slave_dig_outs;
- spec->slave_dig_outs[i - 1] = dig_nid;
- if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
+ if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
break;
+ spec->slave_dig_outs[i - 1] = dig_nid;
}
}
if (spec->autocfg.dig_in_pin)
@@ -6247,7 +6249,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
- SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
+ SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
@@ -8909,10 +8911,11 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
- /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
- * no perfect solution yet
+ /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
+ * so apparently no perfect solution yet
*/
SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
+ SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
{} /* terminator */
};
@@ -9811,9 +9814,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
spec->multiout.dig_out_nid = dig_nid;
else {
spec->multiout.slave_dig_outs = spec->slave_dig_outs;
- spec->slave_dig_outs[i - 1] = dig_nid;
- if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
+ if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
break;
+ spec->slave_dig_outs[i - 1] = dig_nid;
}
}
if (spec->autocfg.dig_in_pin)
@@ -11458,6 +11461,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
+ SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
+ SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
@@ -12602,7 +12607,8 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
ALC268_ACER_ASPIRE_ONE),
SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
- SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
+ SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
+ "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
/* almost compatible with toshiba but with optional digital outs;
* auto-probing seems working fine
*/
@@ -17374,7 +17380,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
/* create playback/capture controls for input pins */
#define alc662_auto_create_input_ctls \
- alc880_auto_create_input_ctls
+ alc882_auto_create_input_ctls
static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
hda_nid_t nid, int pin_type,
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 66c0876bf734..86de305fc9f2 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -28,6 +28,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pci.h>
+#include <linux/dmi.h>
#include <sound/core.h>
#include <sound/asoundef.h>
#include <sound/jack.h>
@@ -1589,6 +1590,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
"Dell Studio 17", STAC_DELL_M6_DMIC),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
"Dell Studio 1555", STAC_DELL_M6_DMIC),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
+ "Dell Studio 1557", STAC_DELL_M6_DMIC),
{} /* terminator */
};
@@ -1693,6 +1696,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
"DFI LanParty", STAC_92HD71BXX_REF),
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb,
"HP dv4-1222nr", STAC_HP_DV4_1222NR),
+ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
+ "HP", STAC_HP_DV5),
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
"HP", STAC_HP_DV5),
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
@@ -4665,6 +4670,26 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
}
}
+static int hp_bseries_system(u32 subsystem_id)
+{
+ switch (subsystem_id) {
+ case 0x103c307e:
+ case 0x103c307f:
+ case 0x103c3080:
+ case 0x103c3081:
+ case 0x103c1722:
+ case 0x103c1723:
+ case 0x103c1724:
+ case 0x103c1725:
+ case 0x103c1726:
+ case 0x103c1727:
+ case 0x103c1728:
+ case 0x103c1729:
+ return 1;
+ }
+ return 0;
+}
+
#ifdef CONFIG_PROC_FS
static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
struct hda_codec *codec, hda_nid_t nid)
@@ -4754,6 +4779,11 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
else
spec->gpio_data |= spec->gpio_led; /* white */
+ if (hp_bseries_system(codec->subsystem_id)) {
+ /* LED state is inverted on these systems */
+ spec->gpio_data ^= spec->gpio_led;
+ }
+
stac_gpio_set(codec, spec->gpio_mask,
spec->gpio_dir,
spec->gpio_data);
@@ -5243,6 +5273,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
{
struct sigmatel_spec *spec;
struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
+ unsigned int pin_cfg;
int err = 0;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -5426,6 +5457,45 @@ again:
break;
}
+ if (hp_bseries_system(codec->subsystem_id)) {
+ pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
+ if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
+ get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER ||
+ get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) {
+ /* It was changed in the BIOS to just satisfy MS DTM.
+ * Lets turn it back into slaved HP
+ */
+ pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE))
+ | (AC_JACK_HP_OUT <<
+ AC_DEFCFG_DEVICE_SHIFT);
+ pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC
+ | AC_DEFCFG_SEQUENCE)))
+ | 0x1f;
+ snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg);
+ }
+ }
+
+ if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
+ const struct dmi_device *dev = NULL;
+ while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
+ NULL, dev))) {
+ if (strcmp(dev->name, "HP_Mute_LED_1")) {
+ switch (codec->vendor_id) {
+ case 0x111d7608:
+ spec->gpio_led = 0x01;
+ break;
+ case 0x111d7600:
+ case 0x111d7601:
+ case 0x111d7602:
+ case 0x111d7603:
+ spec->gpio_led = 0x08;
+ break;
+ }
+ break;
+ }
+ }
+ }
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (spec->gpio_led) {
spec->gpio_mask |= spec->gpio_led;
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 9da2dae64c5b..d063149e7047 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -382,8 +382,8 @@ struct snd_ice1712 {
#ifdef CONFIG_PM
int (*pm_suspend)(struct snd_ice1712 *);
int (*pm_resume)(struct snd_ice1712 *);
- int pm_suspend_enabled:1;
- int pm_saved_is_spdif_master:1;
+ unsigned int pm_suspend_enabled:1;
+ unsigned int pm_saved_is_spdif_master:1;
unsigned int pm_saved_spdif_ctrl;
unsigned char pm_saved_spdif_cfg;
unsigned int pm_saved_route;
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index c75515f5be6f..6a9fee3ee78f 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -1100,7 +1100,7 @@ static void ak4396_init(struct snd_ice1712 *ice)
}
#ifdef CONFIG_PM
-static int __devinit prodigy_hd2_resume(struct snd_ice1712 *ice)
+static int prodigy_hd2_resume(struct snd_ice1712 *ice)
{
/* initialize ak4396 codec and restore previous mixer volumes */
struct prodigy_hifi_spec *spec = ice->spec;
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 754867ed4785..aac20fb4aad2 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1950,6 +1950,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
},
{
.subvendor = 0x104d,
+ .subdevice = 0x8144,
+ .name = "Sony",
+ .type = AC97_TUNE_INV_EAPD
+ },
+ {
+ .subvendor = 0x104d,
.subdevice = 0x8197,
.name = "Sony S1XP",
.type = AC97_TUNE_INV_EAPD
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 91683a349035..8a332d2f615c 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -386,6 +386,7 @@ struct via82xx {
struct snd_pcm *pcms[2];
struct snd_rawmidi *rmidi;
+ struct snd_kcontrol *dxs_controls[4];
struct snd_ac97_bus *ac97_bus;
struct snd_ac97 *ac97;
@@ -1216,9 +1217,9 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
/*
- * open callback for playback on via686 and via823x DSX
+ * open callback for playback on via686
*/
-static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
+static int snd_via686_playback_open(struct snd_pcm_substream *substream)
{
struct via82xx *chip = snd_pcm_substream_chip(substream);
struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
@@ -1230,6 +1231,32 @@ static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
}
/*
+ * open callback for playback on via823x DXS
+ */
+static int snd_via8233_playback_open(struct snd_pcm_substream *substream)
+{
+ struct via82xx *chip = snd_pcm_substream_chip(substream);
+ struct viadev *viadev;
+ unsigned int stream;
+ int err;
+
+ viadev = &chip->devs[chip->playback_devno + substream->number];
+ if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
+ return err;
+ stream = viadev->reg_offset / 0x10;
+ if (chip->dxs_controls[stream]) {
+ chip->playback_volume[stream][0] = 0;
+ chip->playback_volume[stream][1] = 0;
+ chip->dxs_controls[stream]->vd[0].access &=
+ ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO,
+ &chip->dxs_controls[stream]->id);
+ }
+ return 0;
+}
+
+/*
* open callback for playback on via823x multi-channel
*/
static int snd_via8233_multi_open(struct snd_pcm_substream *substream)
@@ -1302,10 +1329,26 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
return 0;
}
+static int snd_via8233_playback_close(struct snd_pcm_substream *substream)
+{
+ struct via82xx *chip = snd_pcm_substream_chip(substream);
+ struct viadev *viadev = substream->runtime->private_data;
+ unsigned int stream;
+
+ stream = viadev->reg_offset / 0x10;
+ if (chip->dxs_controls[stream]) {
+ chip->dxs_controls[stream]->vd[0].access |=
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO,
+ &chip->dxs_controls[stream]->id);
+ }
+ return snd_via82xx_pcm_close(substream);
+}
+
/* via686 playback callbacks */
static struct snd_pcm_ops snd_via686_playback_ops = {
- .open = snd_via82xx_playback_open,
+ .open = snd_via686_playback_open,
.close = snd_via82xx_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_via82xx_hw_params,
@@ -1331,8 +1374,8 @@ static struct snd_pcm_ops snd_via686_capture_ops = {
/* via823x DSX playback callbacks */
static struct snd_pcm_ops snd_via8233_playback_ops = {
- .open = snd_via82xx_playback_open,
- .close = snd_via82xx_pcm_close,
+ .open = snd_via8233_playback_open,
+ .close = snd_via8233_playback_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_via82xx_hw_params,
.hw_free = snd_via82xx_hw_free,
@@ -1709,8 +1752,9 @@ static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
.device = 0,
/* .subdevice set later */
.name = "PCM Playback Volume",
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE,
.info = snd_via8233_dxs_volume_info,
.get = snd_via8233_dxs_volume_get,
.put = snd_via8233_dxs_volume_put,
@@ -1948,6 +1992,7 @@ static int __devinit snd_via8233_init_misc(struct via82xx *chip)
err = snd_ctl_add(chip->card, kctl);
if (err < 0)
return err;
+ chip->dxs_controls[i] = kctl;
}
}
}
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 7dea74b71cf1..7717e01fc071 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -131,7 +131,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
return err;
}
- snd_card_set_dev(card, &handle_to_dev(link));
+ snd_card_set_dev(card, &link->dev);
pdacf->index = i;
card_list[i] = card;
@@ -142,12 +142,10 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.NumPorts1 = 16;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT | IRQ_FORCED_PULSE;
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE;
// link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
- link->irq.IRQInfo1 = 0 /* | IRQ_LEVEL_ID */;
link->irq.Handler = pdacf_interrupt;
- link->irq.Instance = pdacf;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
@@ -217,20 +215,25 @@ static void snd_pdacf_detach(struct pcmcia_device *link)
* configuration callback
*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int pdacf_config(struct pcmcia_device *link)
{
struct snd_pdacf *pdacf = link->priv;
- int last_fn, last_ret;
+ int ret;
snd_printdd(KERN_DEBUG "pdacf_config called\n");
link->conf.ConfigIndex = 0x5;
- CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_io(link, &link->io);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
goto failed;
@@ -238,8 +241,6 @@ static int pdacf_config(struct pcmcia_device *link)
link->dev_node = &pdacf->node;
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
pcmcia_disable_device(link);
return -ENODEV;
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 7445cc8a47d3..7be3b3357045 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -161,11 +161,9 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl,
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.NumPorts1 = 16;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = &snd_vx_irq_handler;
- link->irq.Instance = chip;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -213,14 +211,11 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq
* configuration callback
*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int vxpocket_config(struct pcmcia_device *link)
{
struct vx_core *chip = link->priv;
struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
- int last_fn, last_ret;
+ int ret;
snd_printdd(KERN_DEBUG "vxpocket_config called\n");
@@ -235,11 +230,19 @@ static int vxpocket_config(struct pcmcia_device *link)
strcpy(chip->card->driver, vxp440_hw.name);
}
- CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_request_io(link, &link->io);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
- chip->dev = &handle_to_dev(link);
+ chip->dev = &link->dev;
snd_card_set_dev(chip->card, chip->dev);
if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
@@ -248,8 +251,6 @@ static int vxpocket_config(struct pcmcia_device *link)
link->dev_node = &vxp->node;
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
pcmcia_disable_device(link);
return -ENODEV;
diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig
index bd2338ab2ced..0519c60f5be1 100644
--- a/sound/ppc/Kconfig
+++ b/sound/ppc/Kconfig
@@ -2,7 +2,7 @@
menuconfig SND_PPC
bool "PowerPC sound devices"
- depends on PPC64 || PPC32
+ depends on PPC
default y
help
Support for sound devices specific to PowerPC architectures.
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 583a3693df75..a0df401ebb9f 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -49,6 +49,7 @@ MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}");
+MODULE_FIRMWARE("aica_firmware.bin");
/* module parameters */
#define CARD_NAME "AICA"
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 0b8dcb5cd729..90a0264f7538 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -265,8 +265,8 @@ static const int bosr_usb_divisor_table[] = {
#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15))
static const unsigned short sr_valid_mask[] = {
LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/
- LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
LOWER_GROUP, /* Usb, bosr - 0*/
+ LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
UPPER_GROUP, /* Usb, bosr - 1*/
};
/*
@@ -625,11 +625,10 @@ static int tlv320aic23_resume(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
- int i;
u16 reg;
/* Sync reg_cache with the hardware */
- for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) {
+ for (reg = 0; reg < TLV320AIC23_RESET; reg++) {
u16 val = tlv320aic23_read_reg_cache(codec, reg);
tlv320aic23_write(codec, reg, val);
}
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 2dee9839be86..653a362425df 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -21,7 +21,18 @@ config SND_OMAP_SOC_AMS_DELTA
select SND_OMAP_SOC_MCBSP
select SND_SOC_CX20442
help
- Say Y if you want to add support for SoC audio on Amstrad Delta.
+ Say Y if you want to add support for SoC audio device connected to
+ a handset and a speakerphone found on Amstrad E3 (Delta) videophone.
+
+ Note that in order to get those devices fully supported, you have to
+ build the kernel with standard serial port driver included and
+ configured for at least 4 ports. Then, from userspace, you must load
+ a line discipline #19 on the modem (ttyS3) serial line. The simplest
+ way to achieve this is to install util-linux-ng and use the included
+ ldattach utility. This can be started automatically from udev,
+ a simple rule like this one should do the trick (it does for me):
+ ACTION=="add", KERNEL=="controlC0", \
+ RUN+="/usr/sbin/ldattach 19 /dev/ttyS3"
config SND_OMAP_SOC_OSK5912
tristate "SoC Audio support for omap osk5912"
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 5735945788bf..6a829eef2a4f 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -195,8 +195,12 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
else
omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
- omap_set_dma_src_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16);
- omap_set_dma_dest_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16);
+ if (!(cpu_class_is_omap1())) {
+ omap_set_dma_src_burst_mode(prtd->dma_ch,
+ OMAP_DMA_DATA_BURST_16);
+ omap_set_dma_dest_burst_mode(prtd->dma_ch,
+ OMAP_DMA_DATA_BURST_16);
+ }
return 0;
}
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 9114c263077b..13aa380de162 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -144,4 +144,4 @@ module_exit(omap3evm_soc_exit);
MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index ad219aaf7cb8..0cd06f5dd356 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -134,7 +134,7 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
* |P| <--- TWL4030 <--------- Line In and MICs
*/
static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("PCM DAC", "Playback", SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
0, 0, NULL, 0, omap3pandora_hp_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -181,6 +181,7 @@ static int omap3pandora_out_init(struct snd_soc_codec *codec)
snd_soc_dapm_nc_pin(codec, "CARKITR");
snd_soc_dapm_nc_pin(codec, "HFL");
snd_soc_dapm_nc_pin(codec, "HFR");
+ snd_soc_dapm_nc_pin(codec, "VIBRA");
ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
ARRAY_SIZE(omap3pandora_out_dapm_widgets));
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index 5cbbdc80fde3..1f35c6fcf5fd 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -75,11 +75,19 @@ static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream)
{
struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
dma_addr_t pos = prtd->dma_pos;
+ unsigned int limit;
int ret;
pr_debug("Entered %s\n", __func__);
- while (prtd->dma_loaded < prtd->dma_limit) {
+ if (s3c_dma_has_circular()) {
+ limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
+ } else
+ limit = prtd->dma_limit;
+
+ pr_debug("%s: loaded %d, limit %d\n", __func__, prtd->dma_loaded, limit);
+
+ while (prtd->dma_loaded < limit) {
unsigned long len = prtd->dma_period;
pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
@@ -123,7 +131,7 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
snd_pcm_period_elapsed(substream);
spin_lock(&prtd->lock);
- if (prtd->state & ST_RUNNING) {
+ if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
prtd->dma_loaded--;
s3c24xx_pcm_enqueue(substream);
}
@@ -164,6 +172,11 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
printk(KERN_ERR "failed to get dma channel\n");
return ret;
}
+
+ /* use the circular buffering if we have it available. */
+ if (s3c_dma_has_circular())
+ s3c2410_dma_setflags(prtd->params->channel,
+ S3C2410_DMAF_CIRCULAR);
}
s3c2410_dma_set_buffdone_fn(prtd->params->channel,
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 3c06c401d0fb..105a77eeded0 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -220,6 +220,8 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
goto err;
}
+ clk_enable(i2s->iis_cclk);
+
ret = s3c_i2sv2_probe(pdev, dai, i2s, 0);
if (ret)
goto err_clk;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 7ff04ad2a97e..0a1b2f64bbee 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -834,6 +834,9 @@ EXPORT_SYMBOL_GPL(snd_soc_resume_device);
#define soc_resume NULL
#endif
+static struct snd_soc_dai_ops null_dai_ops = {
+};
+
static void snd_soc_instantiate_card(struct snd_soc_card *card)
{
struct platform_device *pdev = container_of(card->dev,
@@ -877,6 +880,11 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
ac97 = 1;
}
+ for (i = 0; i < card->num_links; i++) {
+ if (!card->dai_link[i].codec_dai->ops)
+ card->dai_link[i].codec_dai->ops = &null_dai_ops;
+ }
+
/* If we have AC97 in the system then don't wait for the
* codec. This will need revisiting if we have to handle
* systems with mixed AC97 and non-AC97 parts. Only check for
@@ -2329,9 +2337,6 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
return 0;
}
-static struct snd_soc_dai_ops null_dai_ops = {
-};
-
/**
* snd_soc_register_dai - Register a DAI with the ASoC core
*
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 8de6f9dec4a2..66d4c165f99b 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -973,9 +973,19 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
if (!w->power_check)
continue;
- power = w->power_check(w);
- if (power)
- sys_power = 1;
+ /* If we're suspending then pull down all the
+ * power. */
+ switch (event) {
+ case SND_SOC_DAPM_STREAM_SUSPEND:
+ power = 0;
+ break;
+
+ default:
+ power = w->power_check(w);
+ if (power)
+ sys_power = 1;
+ break;
+ }
if (w->power == power)
continue;
@@ -999,8 +1009,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
case SND_SOC_DAPM_STREAM_RESUME:
sys_power = 1;
break;
+ case SND_SOC_DAPM_STREAM_SUSPEND:
+ sys_power = 0;
+ break;
case SND_SOC_DAPM_STREAM_NOP:
sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY;
+ break;
default:
break;
}
@@ -2072,9 +2086,9 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
}
}
}
- mutex_unlock(&codec->mutex);
dapm_power_widgets(codec, event);
+ mutex_unlock(&codec->mutex);
dump_dapm(codec, __func__);
return 0;
}
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 121af0644fd9..86b2c3b92df5 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -62,10 +62,14 @@ static void
activate_substream(struct snd_usb_caiaqdev *dev,
struct snd_pcm_substream *sub)
{
+ spin_lock(&dev->spinlock);
+
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
dev->sub_playback[sub->number] = sub;
else
dev->sub_capture[sub->number] = sub;
+
+ spin_unlock(&dev->spinlock);
}
static void
@@ -269,16 +273,22 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
{
int index = sub->number;
struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+ snd_pcm_uframes_t ptr;
+
+ spin_lock(&dev->spinlock);
if (dev->input_panic || dev->output_panic)
- return SNDRV_PCM_POS_XRUN;
+ ptr = SNDRV_PCM_POS_XRUN;
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return bytes_to_frames(sub->runtime,
+ ptr = bytes_to_frames(sub->runtime,
dev->audio_out_buf_pos[index]);
else
- return bytes_to_frames(sub->runtime,
+ ptr = bytes_to_frames(sub->runtime,
dev->audio_in_buf_pos[index]);
+
+ spin_unlock(&dev->spinlock);
+ return ptr;
}
/* operators for both playback and capture */
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 83e6c1312d47..a3f02dd97440 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -35,7 +35,7 @@
#include "input.h"
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("caiaq USB audio, version 1.3.19");
+MODULE_DESCRIPTION("caiaq USB audio, version 1.3.20");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
"{Native Instruments, RigKontrol3},"
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 8e7f78941ba6..e9a3a9dca15c 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -210,7 +210,7 @@ struct snd_usb_midi_endpoint_info {
/*
*/
-#define combine_word(s) ((*s) | ((unsigned int)(s)[1] << 8))
+#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8))
#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 9efcfd08d747..c998220b99c6 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -1071,6 +1071,15 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig
channels = (ftr[0] - 7) / csize - 1;
master_bits = snd_usb_combine_bytes(ftr + 6, csize);
+ /* master configuration quirks */
+ switch (state->chip->usb_id) {
+ case USB_ID(0x08bb, 0x2702):
+ snd_printk(KERN_INFO
+ "usbmixer: master volume quirk for PCM2702 chip\n");
+ /* disable non-functional volume control */
+ master_bits &= ~(1 << (USB_FEATURE_VOLUME - 1));
+ break;
+ }
if (channels > 0)
first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize);
else
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 0854f110bf7f..fe08660ce0bd 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -12,6 +12,7 @@ perf*.1
perf*.xml
perf*.html
common-cmds.h
+perf.data
tags
TAGS
cscope*
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
new file mode 100644
index 000000000000..ae525ac5a2ce
--- /dev/null
+++ b/tools/perf/Documentation/perf-bench.txt
@@ -0,0 +1,120 @@
+perf-bench(1)
+============
+
+NAME
+----
+perf-bench - General framework for benchmark suites
+
+SYNOPSIS
+--------
+[verse]
+'perf bench' [<common options>] <subsystem> <suite> [<options>]
+
+DESCRIPTION
+-----------
+This 'perf bench' command is general framework for benchmark suites.
+
+COMMON OPTIONS
+--------------
+-f::
+--format=::
+Specify format style.
+Current available format styles are,
+
+'default'::
+Default style. This is mainly for human reading.
+---------------------
+% perf bench sched pipe # with no style specify
+(executing 1000000 pipe operations between two tasks)
+ Total time:5.855 sec
+ 5.855061 usecs/op
+ 170792 ops/sec
+---------------------
+
+'simple'::
+This simple style is friendly for automated
+processing by scripts.
+---------------------
+% perf bench --format=simple sched pipe # specified simple
+5.988
+---------------------
+
+SUBSYSTEM
+---------
+
+'sched'::
+ Scheduler and IPC mechanisms.
+
+SUITES FOR 'sched'
+~~~~~~~~~~~~~~~~~~
+*messaging*::
+Suite for evaluating performance of scheduler and IPC mechanisms.
+Based on hackbench by Rusty Russell.
+
+Options of *pipe*
+^^^^^^^^^^^^^^^^^
+-p::
+--pipe::
+Use pipe() instead of socketpair()
+
+-t::
+--thread::
+Be multi thread instead of multi process
+
+-g::
+--group=::
+Specify number of groups
+
+-l::
+--loop=::
+Specify number of loops
+
+Example of *messaging*
+^^^^^^^^^^^^^^^^^^^^^^
+
+---------------------
+% perf bench sched messaging # run with default
+options (20 sender and receiver processes per group)
+(10 groups == 400 processes run)
+
+ Total time:0.308 sec
+
+% perf bench sched messaging -t -g 20 # be multi-thread,with 20 groups
+(20 sender and receiver threads per group)
+(20 groups == 800 threads run)
+
+ Total time:0.582 sec
+---------------------
+
+*pipe*::
+Suite for pipe() system call.
+Based on pipe-test-1m.c by Ingo Molnar.
+
+Options of *pipe*
+^^^^^^^^^^^^^^^^^
+-l::
+--loop=::
+Specify number of loops.
+
+Example of *pipe*
+^^^^^^^^^^^^^^^^^
+
+---------------------
+% perf bench sched pipe
+(executing 1000000 pipe operations between two tasks)
+
+ Total time:8.091 sec
+ 8.091833 usecs/op
+ 123581 ops/sec
+
+% perf bench sched pipe -l 1000 # loop 1000
+(executing 1000 pipe operations between two tasks)
+
+ Total time:0.016 sec
+ 16.948000 usecs/op
+ 59004 ops/sec
+---------------------
+
+SEE ALSO
+--------
+linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-buildid-list.txt b/tools/perf/Documentation/perf-buildid-list.txt
new file mode 100644
index 000000000000..01b642c0bf8f
--- /dev/null
+++ b/tools/perf/Documentation/perf-buildid-list.txt
@@ -0,0 +1,34 @@
+perf-buildid-list(1)
+====================
+
+NAME
+----
+perf-buildid-list - List the buildids in a perf.data file
+
+SYNOPSIS
+--------
+[verse]
+'perf buildid-list <options>'
+
+DESCRIPTION
+-----------
+This command displays the buildids found in a perf.data file, so that other
+tools can be used to fetch packages with matching symbol tables for use by
+perf report.
+
+OPTIONS
+-------
+-i::
+--input=::
+ Input file name. (default: perf.data)
+-f::
+--force::
+ Don't do ownership validation.
+-v::
+--verbose::
+ Be more verbose.
+
+SEE ALSO
+--------
+linkperf:perf-record[1], linkperf:perf-top[1],
+linkperf:perf-report[1]
diff --git a/tools/perf/Documentation/perf-kmem.txt b/tools/perf/Documentation/perf-kmem.txt
new file mode 100644
index 000000000000..44b0ce35c28a
--- /dev/null
+++ b/tools/perf/Documentation/perf-kmem.txt
@@ -0,0 +1,44 @@
+perf-kmem(1)
+==============
+
+NAME
+----
+perf-kmem - Tool to trace/measure kernel memory(slab) properties
+
+SYNOPSIS
+--------
+[verse]
+'perf kmem' {record} [<options>]
+
+DESCRIPTION
+-----------
+There's two variants of perf kmem:
+
+ 'perf kmem record <command>' to record the kmem events
+ of an arbitrary workload.
+
+ 'perf kmem' to report kernel memory statistics.
+
+OPTIONS
+-------
+-i <file>::
+--input=<file>::
+ Select the input file (default: perf.data)
+
+--stat=<caller|alloc>::
+ Select per callsite or per allocation statistics
+
+-s <key[,key2...]>::
+--sort=<key[,key2...]>::
+ Sort the output (default: frag,hit,bytes)
+
+-l <num>::
+--line=<num>::
+ Print n lines only
+
+--raw-ip::
+ Print raw ip instead of symbol
+
+SEE ALSO
+--------
+linkperf:perf-record[1]
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
new file mode 100644
index 000000000000..9270594e6dfd
--- /dev/null
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -0,0 +1,49 @@
+perf-probe(1)
+=============
+
+NAME
+----
+perf-probe - Define new dynamic tracepoints
+
+SYNOPSIS
+--------
+[verse]
+'perf probe' [options] --add 'PROBE' [--add 'PROBE' ...]
+or
+'perf probe' [options] 'PROBE' ['PROBE' ...]
+
+
+DESCRIPTION
+-----------
+This command defines dynamic tracepoint events, by symbol and registers
+without debuginfo, or by C expressions (C line numbers, C function names,
+and C local variables) with debuginfo.
+
+
+OPTIONS
+-------
+-k::
+--vmlinux=PATH::
+ Specify vmlinux path which has debuginfo (Dwarf binary).
+
+-v::
+--verbose::
+ Be more verbose (show parsed arguments, etc).
+
+-a::
+--add::
+ Define a probe point (see PROBE SYNTAX for detail)
+
+PROBE SYNTAX
+------------
+Probe points are defined by following syntax.
+
+ "FUNC[+OFFS|:RLN|%return][@SRC]|SRC:ALN [ARG ...]"
+
+'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, 'RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. In addition, 'SRC' specifies a source file which has that function.
+It is also possible to specify a probe point by the source line number by using 'SRC:ALN' syntax, where 'SRC' is the source file path and 'ALN' is the line number.
+'ARG' specifies the arguments of this probe point. You can use the name of local variable, or kprobe-tracer argument format (e.g. $retval, %ax, etc).
+
+SEE ALSO
+--------
+linkperf:perf-trace[1], linkperf:perf-record[1]
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 0ff23de9e453..fc46c0b40f6e 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -26,11 +26,19 @@ OPTIONS
-e::
--event=::
- Select the PMU event. Selection can be a symbolic event name
- (use 'perf list' to list all events) or a raw PMU
- event (eventsel+umask) in the form of rNNN where NNN is a
- hexadecimal event descriptor.
+ Select the PMU event. Selection can be:
+ - a symbolic event name (use 'perf list' to list all events)
+
+ - a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a
+ hexadecimal event descriptor.
+
+ - a hardware breakpoint event in the form of '\mem:addr[:access]'
+ where addr is the address in memory you want to break in.
+ Access is the memory access type (read, write, execute) it can
+ be passed as follows: '\mem:addr[:[r][w][x]]'.
+ If you want to profile read-write accesses in 0x1000, just set
+ 'mem:0x1000:rw'.
-a::
System-wide collection.
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 59f0b846cd71..9dccb180b7af 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -24,11 +24,11 @@ OPTIONS
--dsos=::
Only consider symbols in these dsos. CSV that understands
file://filename entries.
--n
---show-nr-samples
+-n::
+--show-nr-samples::
Show the number of samples for each symbol
--T
---threads
+-T::
+--threads::
Show per-thread event counters
-C::
--comms=::
diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt
index a7910099d6fd..4b1788355eca 100644
--- a/tools/perf/Documentation/perf-timechart.txt
+++ b/tools/perf/Documentation/perf-timechart.txt
@@ -31,9 +31,12 @@ OPTIONS
-w::
--width=::
Select the width of the SVG file (default: 1000)
--p::
+-P::
--power-only::
Only output the CPU power section of the diagram
+-p::
+--process::
+ Select the processes to display, by name or PID
SEE ALSO
diff --git a/tools/perf/Documentation/perf-trace-perl.txt b/tools/perf/Documentation/perf-trace-perl.txt
new file mode 100644
index 000000000000..c5f55f439091
--- /dev/null
+++ b/tools/perf/Documentation/perf-trace-perl.txt
@@ -0,0 +1,219 @@
+perf-trace-perl(1)
+==================
+
+NAME
+----
+perf-trace-perl - Process trace data with a Perl script
+
+SYNOPSIS
+--------
+[verse]
+'perf trace' [-s [lang]:script[.ext] ]
+
+DESCRIPTION
+-----------
+
+This perf trace option is used to process perf trace data using perf's
+built-in Perl interpreter. It reads and processes the input file and
+displays the results of the trace analysis implemented in the given
+Perl script, if any.
+
+STARTER SCRIPTS
+---------------
+
+You can avoid reading the rest of this document by running 'perf trace
+-g perl' in the same directory as an existing perf.data trace file.
+That will generate a starter script containing a handler for each of
+the event types in the trace file; it simply prints every available
+field for each event in the trace file.
+
+You can also look at the existing scripts in
+~/libexec/perf-core/scripts/perl for typical examples showing how to
+do basic things like aggregate event data, print results, etc. Also,
+the check-perf-trace.pl script, while not interesting for its results,
+attempts to exercise all of the main scripting features.
+
+EVENT HANDLERS
+--------------
+
+When perf trace is invoked using a trace script, a user-defined
+'handler function' is called for each event in the trace. If there's
+no handler function defined for a given event type, the event is
+ignored (or passed to a 'trace_handled' function, see below) and the
+next event is processed.
+
+Most of the event's field values are passed as arguments to the
+handler function; some of the less common ones aren't - those are
+available as calls back into the perf executable (see below).
+
+As an example, the following perf record command can be used to record
+all sched_wakeup events in the system:
+
+ # perf record -c 1 -f -a -M -R -e sched:sched_wakeup
+
+Traces meant to be processed using a script should be recorded with
+the above options: -c 1 says to sample every event, -a to enable
+system-wide collection, -M to multiplex the output, and -R to collect
+raw samples.
+
+The format file for the sched_wakep event defines the following fields
+(see /sys/kernel/debug/tracing/events/sched/sched_wakeup/format):
+
+----
+ format:
+ field:unsigned short common_type;
+ field:unsigned char common_flags;
+ field:unsigned char common_preempt_count;
+ field:int common_pid;
+ field:int common_lock_depth;
+
+ field:char comm[TASK_COMM_LEN];
+ field:pid_t pid;
+ field:int prio;
+ field:int success;
+ field:int target_cpu;
+----
+
+The handler function for this event would be defined as:
+
+----
+sub sched::sched_wakeup
+{
+ my ($event_name, $context, $common_cpu, $common_secs,
+ $common_nsecs, $common_pid, $common_comm,
+ $comm, $pid, $prio, $success, $target_cpu) = @_;
+}
+----
+
+The handler function takes the form subsystem::event_name.
+
+The $common_* arguments in the handler's argument list are the set of
+arguments passed to all event handlers; some of the fields correspond
+to the common_* fields in the format file, but some are synthesized,
+and some of the common_* fields aren't common enough to to be passed
+to every event as arguments but are available as library functions.
+
+Here's a brief description of each of the invariant event args:
+
+ $event_name the name of the event as text
+ $context an opaque 'cookie' used in calls back into perf
+ $common_cpu the cpu the event occurred on
+ $common_secs the secs portion of the event timestamp
+ $common_nsecs the nsecs portion of the event timestamp
+ $common_pid the pid of the current task
+ $common_comm the name of the current process
+
+All of the remaining fields in the event's format file have
+counterparts as handler function arguments of the same name, as can be
+seen in the example above.
+
+The above provides the basics needed to directly access every field of
+every event in a trace, which covers 90% of what you need to know to
+write a useful trace script. The sections below cover the rest.
+
+SCRIPT LAYOUT
+-------------
+
+Every perf trace Perl script should start by setting up a Perl module
+search path and 'use'ing a few support modules (see module
+descriptions below):
+
+----
+ use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
+ use lib "./Perf-Trace-Util/lib";
+ use Perf::Trace::Core;
+ use Perf::Trace::Context;
+ use Perf::Trace::Util;
+----
+
+The rest of the script can contain handler functions and support
+functions in any order.
+
+Aside from the event handler functions discussed above, every script
+can implement a set of optional functions:
+
+*trace_begin*, if defined, is called before any event is processed and
+gives scripts a chance to do setup tasks:
+
+----
+ sub trace_begin
+ {
+ }
+----
+
+*trace_end*, if defined, is called after all events have been
+ processed and gives scripts a chance to do end-of-script tasks, such
+ as display results:
+
+----
+sub trace_end
+{
+}
+----
+
+*trace_unhandled*, if defined, is called after for any event that
+ doesn't have a handler explicitly defined for it. The standard set
+ of common arguments are passed into it:
+
+----
+sub trace_unhandled
+{
+ my ($event_name, $context, $common_cpu, $common_secs,
+ $common_nsecs, $common_pid, $common_comm) = @_;
+}
+----
+
+The remaining sections provide descriptions of each of the available
+built-in perf trace Perl modules and their associated functions.
+
+AVAILABLE MODULES AND FUNCTIONS
+-------------------------------
+
+The following sections describe the functions and variables available
+via the various Perf::Trace::* Perl modules. To use the functions and
+variables from the given module, add the corresponding 'use
+Perf::Trace::XXX' line to your perf trace script.
+
+Perf::Trace::Core Module
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+These functions provide some essential functions to user scripts.
+
+The *flag_str* and *symbol_str* functions provide human-readable
+strings for flag and symbolic fields. These correspond to the strings
+and values parsed from the 'print fmt' fields of the event format
+files:
+
+ flag_str($event_name, $field_name, $field_value) - returns the string represention corresponding to $field_value for the flag field $field_name of event $event_name
+ symbol_str($event_name, $field_name, $field_value) - returns the string represention corresponding to $field_value for the symbolic field $field_name of event $event_name
+
+Perf::Trace::Context Module
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some of the 'common' fields in the event format file aren't all that
+common, but need to be made accessible to user scripts nonetheless.
+
+Perf::Trace::Context defines a set of functions that can be used to
+access this data in the context of the current event. Each of these
+functions expects a $context variable, which is the same as the
+$context variable passed into every event handler as the second
+argument.
+
+ common_pc($context) - returns common_preempt count for the current event
+ common_flags($context) - returns common_flags for the current event
+ common_lock_depth($context) - returns common_lock_depth for the current event
+
+Perf::Trace::Util Module
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Various utility functions for use with perf trace:
+
+ nsecs($secs, $nsecs) - returns total nsecs given secs/nsecs pair
+ nsecs_secs($nsecs) - returns whole secs portion given nsecs
+ nsecs_nsecs($nsecs) - returns nsecs remainder given nsecs
+ nsecs_str($nsecs) - returns printable string in the form secs.nsecs
+ avg($total, $n) - returns average given a sum and a total number of values
+
+SEE ALSO
+--------
+linkperf:perf-trace[1]
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 41ed75398ca9..07065efa60e0 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -20,6 +20,15 @@ OPTIONS
--dump-raw-trace=::
Display verbose dump of the trace data.
+-s::
+--script=::
+ Process trace data with the given script ([lang]:script[.ext]).
+
+-g::
+--gen-script=::
+ Generate perf-trace.[ext] starter script for given language,
+ using current perf.data.
+
SEE ALSO
--------
-linkperf:perf-record[1]
+linkperf:perf-record[1], linkperf:perf-trace-perl[1]
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 5881943f0c34..23ec66098bdc 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -2,6 +2,7 @@
all::
# Define V=1 to have a more verbose compile.
+# Define V=2 to have an even more verbose compile.
#
# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()
# or vsnprintf() return -1 instead of number of characters which would
@@ -145,6 +146,10 @@ all::
# Define NO_EXTERNAL_GREP if you don't want "perf grep" to ever call
# your external grep (e.g., if your system lacks grep, if its grep is
# broken, or spawning external process is slower than built-in grep perf has).
+#
+# Define LDFLAGS=-static to build a static binary.
+#
+# Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
@$(SHELL_PATH) util/PERF-VERSION-GEN
@@ -157,21 +162,13 @@ uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
-# If we're on a 64-bit kernel, use -m64
-ifndef NO_64BIT
- ifneq ($(patsubst %64,%,$(uname_M)),$(uname_M))
- M64 := -m64
- endif
-endif
-
# CFLAGS and LDFLAGS are for the users to override from the command line.
#
# Include saner warnings here, which can catch bugs:
#
-EXTRA_WARNINGS := -Wcast-align
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat
+EXTRA_WARNINGS := -Wformat
EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-security
EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-y2k
EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wshadow
@@ -194,8 +191,15 @@ EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wold-style-definition
EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-prototypes
EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wdeclaration-after-statement
-CFLAGS = $(M64) -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -fstack-protector-all -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS)
-LDFLAGS = -lpthread -lrt -lelf -lm
+ifeq ("$(origin DEBUG)", "command line")
+ PERF_DEBUG = $(DEBUG)
+endif
+ifndef PERF_DEBUG
+ CFLAGS_OPTIMIZE = -O6
+endif
+
+CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
+EXTLIBS = -lpthread -lrt -lelf -lm
ALL_CFLAGS = $(CFLAGS)
ALL_LDFLAGS = $(LDFLAGS)
STRIP ?= strip
@@ -246,6 +250,9 @@ PTHREAD_LIBS = -lpthread
# explicitly what architecture to check for. Fix this up for yours..
SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
+ifeq ($(shell sh -c "echo 'int foo(void) {char X[2]; return 3;}' | $(CC) -x c -c -Werror -fstack-protector-all - -o /dev/null "$(QUIET_STDERR)" && echo y"), y)
+ CFLAGS := $(CFLAGS) -fstack-protector-all
+endif
### --- END CONFIGURATION SECTION ---
@@ -321,8 +328,28 @@ LIB_FILE=libperf.a
LIB_H += ../../include/linux/perf_event.h
LIB_H += ../../include/linux/rbtree.h
LIB_H += ../../include/linux/list.h
+LIB_H += ../../include/linux/stringify.h
+LIB_H += util/include/linux/bitmap.h
+LIB_H += util/include/linux/bitops.h
+LIB_H += util/include/linux/compiler.h
+LIB_H += util/include/linux/ctype.h
+LIB_H += util/include/linux/kernel.h
LIB_H += util/include/linux/list.h
+LIB_H += util/include/linux/module.h
+LIB_H += util/include/linux/poison.h
+LIB_H += util/include/linux/prefetch.h
+LIB_H += util/include/linux/rbtree.h
+LIB_H += util/include/linux/string.h
+LIB_H += util/include/linux/types.h
+LIB_H += util/include/asm/asm-offsets.h
+LIB_H += util/include/asm/bitops.h
+LIB_H += util/include/asm/byteorder.h
+LIB_H += util/include/asm/swab.h
+LIB_H += util/include/asm/system.h
+LIB_H += util/include/asm/uaccess.h
LIB_H += perf.h
+LIB_H += util/debugfs.h
+LIB_H += util/event.h
LIB_H += util/types.h
LIB_H += util/levenshtein.h
LIB_H += util/parse-options.h
@@ -336,15 +363,22 @@ LIB_H += util/strlist.h
LIB_H += util/run-command.h
LIB_H += util/sigchain.h
LIB_H += util/symbol.h
-LIB_H += util/module.h
LIB_H += util/color.h
LIB_H += util/values.h
+LIB_H += util/sort.h
+LIB_H += util/hist.h
+LIB_H += util/thread.h
+LIB_H += util/data_map.h
+LIB_H += util/probe-finder.h
+LIB_H += util/probe-event.h
LIB_OBJS += util/abspath.o
LIB_OBJS += util/alias.o
LIB_OBJS += util/config.o
LIB_OBJS += util/ctype.o
+LIB_OBJS += util/debugfs.o
LIB_OBJS += util/environment.o
+LIB_OBJS += util/event.o
LIB_OBJS += util/exec_cmd.o
LIB_OBJS += util/help.o
LIB_OBJS += util/levenshtein.o
@@ -352,6 +386,9 @@ LIB_OBJS += util/parse-options.o
LIB_OBJS += util/parse-events.o
LIB_OBJS += util/path.o
LIB_OBJS += util/rbtree.o
+LIB_OBJS += util/bitmap.o
+LIB_OBJS += util/hweight.o
+LIB_OBJS += util/find_next_bit.o
LIB_OBJS += util/run-command.o
LIB_OBJS += util/quote.o
LIB_OBJS += util/strbuf.o
@@ -361,7 +398,6 @@ LIB_OBJS += util/usage.o
LIB_OBJS += util/wrapper.o
LIB_OBJS += util/sigchain.o
LIB_OBJS += util/symbol.o
-LIB_OBJS += util/module.o
LIB_OBJS += util/color.o
LIB_OBJS += util/pager.o
LIB_OBJS += util/header.o
@@ -373,11 +409,25 @@ LIB_OBJS += util/thread.o
LIB_OBJS += util/trace-event-parse.o
LIB_OBJS += util/trace-event-read.o
LIB_OBJS += util/trace-event-info.o
+LIB_OBJS += util/trace-event-perl.o
LIB_OBJS += util/svghelper.o
+LIB_OBJS += util/sort.o
+LIB_OBJS += util/hist.o
+LIB_OBJS += util/data_map.o
+LIB_OBJS += util/probe-event.o
BUILTIN_OBJS += builtin-annotate.o
+
+BUILTIN_OBJS += builtin-bench.o
+
+# Benchmark modules
+BUILTIN_OBJS += bench/sched-messaging.o
+BUILTIN_OBJS += bench/sched-pipe.o
+BUILTIN_OBJS += bench/mem-memcpy.o
+
BUILTIN_OBJS += builtin-help.o
BUILTIN_OBJS += builtin-sched.o
+BUILTIN_OBJS += builtin-buildid-list.o
BUILTIN_OBJS += builtin-list.o
BUILTIN_OBJS += builtin-record.o
BUILTIN_OBJS += builtin-report.o
@@ -385,9 +435,16 @@ BUILTIN_OBJS += builtin-stat.o
BUILTIN_OBJS += builtin-timechart.o
BUILTIN_OBJS += builtin-top.o
BUILTIN_OBJS += builtin-trace.o
+BUILTIN_OBJS += builtin-probe.o
+BUILTIN_OBJS += builtin-kmem.o
PERFLIBS = $(LIB_FILE)
+ifeq ($(V), 2)
+ QUIET_STDERR = ">/dev/null"
+else
+ QUIET_STDERR = ">/dev/null 2>&1"
+endif
#
# Platform specific tweaks
#
@@ -415,32 +472,58 @@ ifeq ($(uname_S),Darwin)
PTHREAD_LIBS =
endif
-ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
- msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel);
+ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ifneq ($(shell sh -c "(echo '\#include <gnu/libc-version.h>'; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
+endif
+
+ ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ BASIC_CFLAGS += -DLIBELF_NO_MMAP
+ endif
+else
+ msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
+endif
+
+ifneq ($(shell sh -c "(echo '\#include <libdwarf/dwarf.h>'; echo '\#include <libdwarf/libdwarf.h>'; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; Dwarf_Ranges *rng; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); dwarf_get_ranges(dbg, 0, &rng, 0, 0, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -ldwarf -lelf -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ msg := $(warning No libdwarf.h found or old libdwarf.h found, disables dwarf support. Please install libdwarf-dev/libdwarf-devel >= 20081231);
+ BASIC_CFLAGS += -DNO_LIBDWARF
+else
+ EXTLIBS += -lelf -ldwarf
+ LIB_OBJS += util/probe-finder.o
+endif
+
+PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null`
+PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
+
+ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; echo 'int main(void) { perl_alloc(); return 0; }') | $(CC) -x c - $(PERL_EMBED_CCOPTS) -o /dev/null $(PERL_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
+ BASIC_CFLAGS += -DNO_LIBPERL
+else
+ ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
+ LIB_OBJS += scripts/perl/Perf-Trace-Util/Context.o
endif
ifdef NO_DEMANGLE
BASIC_CFLAGS += -DNO_DEMANGLE
else
- has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd > /dev/null 2>&1 && echo y")
+ has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) -lbfd "$(QUIET_STDERR)" && echo y")
ifeq ($(has_bfd),y)
EXTLIBS += -lbfd
else
- has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty > /dev/null 2>&1 && echo y")
+ has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty "$(QUIET_STDERR)" && echo y")
ifeq ($(has_bfd_iberty),y)
EXTLIBS += -lbfd -liberty
else
- has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty -lz > /dev/null 2>&1 && echo y")
+ has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty -lz "$(QUIET_STDERR)" && echo y")
ifeq ($(has_bfd_iberty_z),y)
EXTLIBS += -lbfd -liberty -lz
else
- has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -liberty > /dev/null 2>&1 && echo y")
+ has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) -liberty "$(QUIET_STDERR)" && echo y")
ifeq ($(has_cplus_demangle),y)
EXTLIBS += -liberty
BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
else
- msg := $(warning No bfd.h/libbfd found, install binutils-dev[el] to gain symbol demangling)
+ msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
BASIC_CFLAGS += -DNO_DEMANGLE
endif
endif
@@ -777,6 +860,25 @@ util/config.o: util/config.c PERF-CFLAGS
util/rbtree.o: ../../lib/rbtree.c PERF-CFLAGS
$(QUIET_CC)$(CC) -o util/rbtree.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+# some perf warning policies can't fit to lib/bitmap.c, eg: it warns about variable shadowing
+# from <string.h> that comes from kernel headers wrapping.
+KBITMAP_FLAGS=`echo $(ALL_CFLAGS) | sed s/-Wshadow// | sed s/-Wswitch-default// | sed s/-Wextra//`
+
+util/bitmap.o: ../../lib/bitmap.c PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o util/bitmap.o -c $(KBITMAP_FLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+
+util/hweight.o: ../../lib/hweight.c PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o util/hweight.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+
+util/find_next_bit.o: ../../lib/find_next_bit.c PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o util/find_next_bit.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+
+util/trace-event-perl.o: util/trace-event-perl.c PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o util/trace-event-perl.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+
+scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o scripts/perl/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+
perf-%$X: %.o $(PERFLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
@@ -884,6 +986,13 @@ export perfexec_instdir
install: all
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) perf$X '$(DESTDIR_SQ)$(bindir_SQ)'
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
+ $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
+ $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'
+ $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
+ $(INSTALL) scripts/perl/Perf-Trace-Util/Makefile.PL -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util'
+ $(INSTALL) scripts/perl/Perf-Trace-Util/README -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util'
ifdef BUILT_INS
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
$(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
@@ -969,7 +1078,7 @@ distclean: clean
# $(RM) configure
clean:
- $(RM) *.o */*.o $(LIB_FILE)
+ $(RM) *.o */*.o */*/*.o */*/*/*.o $(LIB_FILE)
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X
$(RM) $(TEST_PROGRAMS)
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
new file mode 100644
index 000000000000..f7781c6267c0
--- /dev/null
+++ b/tools/perf/bench/bench.h
@@ -0,0 +1,17 @@
+#ifndef BENCH_H
+#define BENCH_H
+
+extern int bench_sched_messaging(int argc, const char **argv, const char *prefix);
+extern int bench_sched_pipe(int argc, const char **argv, const char *prefix);
+extern int bench_mem_memcpy(int argc, const char **argv, const char *prefix __used);
+
+#define BENCH_FORMAT_DEFAULT_STR "default"
+#define BENCH_FORMAT_DEFAULT 0
+#define BENCH_FORMAT_SIMPLE_STR "simple"
+#define BENCH_FORMAT_SIMPLE 1
+
+#define BENCH_FORMAT_UNKNOWN -1
+
+extern int bench_format;
+
+#endif
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
new file mode 100644
index 000000000000..89773178e894
--- /dev/null
+++ b/tools/perf/bench/mem-memcpy.c
@@ -0,0 +1,193 @@
+/*
+ * mem-memcpy.c
+ *
+ * memcpy: Simple memory copy in various ways
+ *
+ * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
+ */
+#include <ctype.h>
+
+#include "../perf.h"
+#include "../util/util.h"
+#include "../util/parse-options.h"
+#include "../util/string.h"
+#include "../util/header.h"
+#include "bench.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#define K 1024
+
+static const char *length_str = "1MB";
+static const char *routine = "default";
+static int use_clock = 0;
+static int clock_fd;
+
+static const struct option options[] = {
+ OPT_STRING('l', "length", &length_str, "1MB",
+ "Specify length of memory to copy. "
+ "available unit: B, MB, GB (upper and lower)"),
+ OPT_STRING('r', "routine", &routine, "default",
+ "Specify routine to copy"),
+ OPT_BOOLEAN('c', "clock", &use_clock,
+ "Use CPU clock for measuring"),
+ OPT_END()
+};
+
+struct routine {
+ const char *name;
+ const char *desc;
+ void * (*fn)(void *dst, const void *src, size_t len);
+};
+
+struct routine routines[] = {
+ { "default",
+ "Default memcpy() provided by glibc",
+ memcpy },
+ { NULL,
+ NULL,
+ NULL }
+};
+
+static const char * const bench_mem_memcpy_usage[] = {
+ "perf bench mem memcpy <options>",
+ NULL
+};
+
+static struct perf_event_attr clock_attr = {
+ .type = PERF_TYPE_HARDWARE,
+ .config = PERF_COUNT_HW_CPU_CYCLES
+};
+
+static void init_clock(void)
+{
+ clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0);
+
+ if (clock_fd < 0 && errno == ENOSYS)
+ die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
+ else
+ BUG_ON(clock_fd < 0);
+}
+
+static u64 get_clock(void)
+{
+ int ret;
+ u64 clk;
+
+ ret = read(clock_fd, &clk, sizeof(u64));
+ BUG_ON(ret != sizeof(u64));
+
+ return clk;
+}
+
+static double timeval2double(struct timeval *ts)
+{
+ return (double)ts->tv_sec +
+ (double)ts->tv_usec / (double)1000000;
+}
+
+int bench_mem_memcpy(int argc, const char **argv,
+ const char *prefix __used)
+{
+ int i;
+ void *dst, *src;
+ size_t length;
+ double bps = 0.0;
+ struct timeval tv_start, tv_end, tv_diff;
+ u64 clock_start, clock_end, clock_diff;
+
+ clock_start = clock_end = clock_diff = 0ULL;
+ argc = parse_options(argc, argv, options,
+ bench_mem_memcpy_usage, 0);
+
+ tv_diff.tv_sec = 0;
+ tv_diff.tv_usec = 0;
+ length = (size_t)perf_atoll((char *)length_str);
+
+ if ((s64)length <= 0) {
+ fprintf(stderr, "Invalid length:%s\n", length_str);
+ return 1;
+ }
+
+ for (i = 0; routines[i].name; i++) {
+ if (!strcmp(routines[i].name, routine))
+ break;
+ }
+ if (!routines[i].name) {
+ printf("Unknown routine:%s\n", routine);
+ printf("Available routines...\n");
+ for (i = 0; routines[i].name; i++) {
+ printf("\t%s ... %s\n",
+ routines[i].name, routines[i].desc);
+ }
+ return 1;
+ }
+
+ dst = zalloc(length);
+ if (!dst)
+ die("memory allocation failed - maybe length is too large?\n");
+
+ src = zalloc(length);
+ if (!src)
+ die("memory allocation failed - maybe length is too large?\n");
+
+ if (bench_format == BENCH_FORMAT_DEFAULT) {
+ printf("# Copying %s Bytes from %p to %p ...\n\n",
+ length_str, src, dst);
+ }
+
+ if (use_clock) {
+ init_clock();
+ clock_start = get_clock();
+ } else {
+ BUG_ON(gettimeofday(&tv_start, NULL));
+ }
+
+ routines[i].fn(dst, src, length);
+
+ if (use_clock) {
+ clock_end = get_clock();
+ clock_diff = clock_end - clock_start;
+ } else {
+ BUG_ON(gettimeofday(&tv_end, NULL));
+ timersub(&tv_end, &tv_start, &tv_diff);
+ bps = (double)((double)length / timeval2double(&tv_diff));
+ }
+
+ switch (bench_format) {
+ case BENCH_FORMAT_DEFAULT:
+ if (use_clock) {
+ printf(" %14lf Clock/Byte\n",
+ (double)clock_diff / (double)length);
+ } else {
+ if (bps < K)
+ printf(" %14lf B/Sec\n", bps);
+ else if (bps < K * K)
+ printf(" %14lfd KB/Sec\n", bps / 1024);
+ else if (bps < K * K * K)
+ printf(" %14lf MB/Sec\n", bps / 1024 / 1024);
+ else {
+ printf(" %14lf GB/Sec\n",
+ bps / 1024 / 1024 / 1024);
+ }
+ }
+ break;
+ case BENCH_FORMAT_SIMPLE:
+ if (use_clock) {
+ printf("%14lf\n",
+ (double)clock_diff / (double)length);
+ } else
+ printf("%lf\n", bps);
+ break;
+ default:
+ /* reaching this means there's some disaster: */
+ die("unknown format: %d\n", bench_format);
+ break;
+ }
+
+ return 0;
+}
diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c
new file mode 100644
index 000000000000..605a2a959aa8
--- /dev/null
+++ b/tools/perf/bench/sched-messaging.c
@@ -0,0 +1,336 @@
+/*
+ *
+ * builtin-bench-messaging.c
+ *
+ * messaging: Benchmark for scheduler and IPC mechanisms
+ *
+ * Based on hackbench by Rusty Russell <rusty@rustcorp.com.au>
+ * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
+ *
+ */
+
+#include "../perf.h"
+#include "../util/util.h"
+#include "../util/parse-options.h"
+#include "../builtin.h"
+#include "bench.h"
+
+/* Test groups of 20 processes spraying to 20 receivers */
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <limits.h>
+
+#define DATASIZE 100
+
+static int use_pipes = 0;
+static unsigned int loops = 100;
+static unsigned int thread_mode = 0;
+static unsigned int num_groups = 10;
+
+struct sender_context {
+ unsigned int num_fds;
+ int ready_out;
+ int wakefd;
+ int out_fds[0];
+};
+
+struct receiver_context {
+ unsigned int num_packets;
+ int in_fds[2];
+ int ready_out;
+ int wakefd;
+};
+
+static void barf(const char *msg)
+{
+ fprintf(stderr, "%s (error: %s)\n", msg, strerror(errno));
+ exit(1);
+}
+
+static void fdpair(int fds[2])
+{
+ if (use_pipes) {
+ if (pipe(fds) == 0)
+ return;
+ } else {
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0)
+ return;
+ }
+
+ barf(use_pipes ? "pipe()" : "socketpair()");
+}
+
+/* Block until we're ready to go */
+static void ready(int ready_out, int wakefd)
+{
+ char dummy;
+ struct pollfd pollfd = { .fd = wakefd, .events = POLLIN };
+
+ /* Tell them we're ready. */
+ if (write(ready_out, &dummy, 1) != 1)
+ barf("CLIENT: ready write");
+
+ /* Wait for "GO" signal */
+ if (poll(&pollfd, 1, -1) != 1)
+ barf("poll");
+}
+
+/* Sender sprays loops messages down each file descriptor */
+static void *sender(struct sender_context *ctx)
+{
+ char data[DATASIZE];
+ unsigned int i, j;
+
+ ready(ctx->ready_out, ctx->wakefd);
+
+ /* Now pump to every receiver. */
+ for (i = 0; i < loops; i++) {
+ for (j = 0; j < ctx->num_fds; j++) {
+ int ret, done = 0;
+
+again:
+ ret = write(ctx->out_fds[j], data + done,
+ sizeof(data)-done);
+ if (ret < 0)
+ barf("SENDER: write");
+ done += ret;
+ if (done < DATASIZE)
+ goto again;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* One receiver per fd */
+static void *receiver(struct receiver_context* ctx)
+{
+ unsigned int i;
+
+ if (!thread_mode)
+ close(ctx->in_fds[1]);
+
+ /* Wait for start... */
+ ready(ctx->ready_out, ctx->wakefd);
+
+ /* Receive them all */
+ for (i = 0; i < ctx->num_packets; i++) {
+ char data[DATASIZE];
+ int ret, done = 0;
+
+again:
+ ret = read(ctx->in_fds[0], data + done, DATASIZE - done);
+ if (ret < 0)
+ barf("SERVER: read");
+ done += ret;
+ if (done < DATASIZE)
+ goto again;
+ }
+
+ return NULL;
+}
+
+static pthread_t create_worker(void *ctx, void *(*func)(void *))
+{
+ pthread_attr_t attr;
+ pthread_t childid;
+ int err;
+
+ if (!thread_mode) {
+ /* process mode */
+ /* Fork the receiver. */
+ switch (fork()) {
+ case -1:
+ barf("fork()");
+ break;
+ case 0:
+ (*func) (ctx);
+ exit(0);
+ break;
+ default:
+ break;
+ }
+
+ return (pthread_t)0;
+ }
+
+ if (pthread_attr_init(&attr) != 0)
+ barf("pthread_attr_init:");
+
+#ifndef __ia64__
+ if (pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) != 0)
+ barf("pthread_attr_setstacksize");
+#endif
+
+ err = pthread_create(&childid, &attr, func, ctx);
+ if (err != 0) {
+ fprintf(stderr, "pthread_create failed: %s (%d)\n",
+ strerror(err), err);
+ exit(-1);
+ }
+ return childid;
+}
+
+static void reap_worker(pthread_t id)
+{
+ int proc_status;
+ void *thread_status;
+
+ if (!thread_mode) {
+ /* process mode */
+ wait(&proc_status);
+ if (!WIFEXITED(proc_status))
+ exit(1);
+ } else {
+ pthread_join(id, &thread_status);
+ }
+}
+
+/* One group of senders and receivers */
+static unsigned int group(pthread_t *pth,
+ unsigned int num_fds,
+ int ready_out,
+ int wakefd)
+{
+ unsigned int i;
+ struct sender_context *snd_ctx = malloc(sizeof(struct sender_context)
+ + num_fds * sizeof(int));
+
+ if (!snd_ctx)
+ barf("malloc()");
+
+ for (i = 0; i < num_fds; i++) {
+ int fds[2];
+ struct receiver_context *ctx = malloc(sizeof(*ctx));
+
+ if (!ctx)
+ barf("malloc()");
+
+
+ /* Create the pipe between client and server */
+ fdpair(fds);
+
+ ctx->num_packets = num_fds * loops;
+ ctx->in_fds[0] = fds[0];
+ ctx->in_fds[1] = fds[1];
+ ctx->ready_out = ready_out;
+ ctx->wakefd = wakefd;
+
+ pth[i] = create_worker(ctx, (void *)receiver);
+
+ snd_ctx->out_fds[i] = fds[1];
+ if (!thread_mode)
+ close(fds[0]);
+ }
+
+ /* Now we have all the fds, fork the senders */
+ for (i = 0; i < num_fds; i++) {
+ snd_ctx->ready_out = ready_out;
+ snd_ctx->wakefd = wakefd;
+ snd_ctx->num_fds = num_fds;
+
+ pth[num_fds+i] = create_worker(snd_ctx, (void *)sender);
+ }
+
+ /* Close the fds we have left */
+ if (!thread_mode)
+ for (i = 0; i < num_fds; i++)
+ close(snd_ctx->out_fds[i]);
+
+ /* Return number of children to reap */
+ return num_fds * 2;
+}
+
+static const struct option options[] = {
+ OPT_BOOLEAN('p', "pipe", &use_pipes,
+ "Use pipe() instead of socketpair()"),
+ OPT_BOOLEAN('t', "thread", &thread_mode,
+ "Be multi thread instead of multi process"),
+ OPT_INTEGER('g', "group", &num_groups,
+ "Specify number of groups"),
+ OPT_INTEGER('l', "loop", &loops,
+ "Specify number of loops"),
+ OPT_END()
+};
+
+static const char * const bench_sched_message_usage[] = {
+ "perf bench sched messaging <options>",
+ NULL
+};
+
+int bench_sched_messaging(int argc, const char **argv,
+ const char *prefix __used)
+{
+ unsigned int i, total_children;
+ struct timeval start, stop, diff;
+ unsigned int num_fds = 20;
+ int readyfds[2], wakefds[2];
+ char dummy;
+ pthread_t *pth_tab;
+
+ argc = parse_options(argc, argv, options,
+ bench_sched_message_usage, 0);
+
+ pth_tab = malloc(num_fds * 2 * num_groups * sizeof(pthread_t));
+ if (!pth_tab)
+ barf("main:malloc()");
+
+ fdpair(readyfds);
+ fdpair(wakefds);
+
+ total_children = 0;
+ for (i = 0; i < num_groups; i++)
+ total_children += group(pth_tab+total_children, num_fds,
+ readyfds[1], wakefds[0]);
+
+ /* Wait for everyone to be ready */
+ for (i = 0; i < total_children; i++)
+ if (read(readyfds[0], &dummy, 1) != 1)
+ barf("Reading for readyfds");
+
+ gettimeofday(&start, NULL);
+
+ /* Kick them off */
+ if (write(wakefds[1], &dummy, 1) != 1)
+ barf("Writing to start them");
+
+ /* Reap them all */
+ for (i = 0; i < total_children; i++)
+ reap_worker(pth_tab[i]);
+
+ gettimeofday(&stop, NULL);
+
+ timersub(&stop, &start, &diff);
+
+ switch (bench_format) {
+ case BENCH_FORMAT_DEFAULT:
+ printf("# %d sender and receiver %s per group\n",
+ num_fds, thread_mode ? "threads" : "processes");
+ printf("# %d groups == %d %s run\n\n",
+ num_groups, num_groups * 2 * num_fds,
+ thread_mode ? "threads" : "processes");
+ printf(" %14s: %lu.%03lu [sec]\n", "Total time",
+ diff.tv_sec, diff.tv_usec/1000);
+ break;
+ case BENCH_FORMAT_SIMPLE:
+ printf("%lu.%03lu\n", diff.tv_sec, diff.tv_usec/1000);
+ break;
+ default:
+ /* reaching here is something disaster */
+ fprintf(stderr, "Unknown format:%d\n", bench_format);
+ exit(1);
+ break;
+ }
+
+ return 0;
+}
diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c
new file mode 100644
index 000000000000..238185f97977
--- /dev/null
+++ b/tools/perf/bench/sched-pipe.c
@@ -0,0 +1,124 @@
+/*
+ *
+ * builtin-bench-pipe.c
+ *
+ * pipe: Benchmark for pipe()
+ *
+ * Based on pipe-test-1m.c by Ingo Molnar <mingo@redhat.com>
+ * http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c
+ * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
+ *
+ */
+
+#include "../perf.h"
+#include "../util/util.h"
+#include "../util/parse-options.h"
+#include "../builtin.h"
+#include "bench.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <linux/unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#define LOOPS_DEFAULT 1000000
+static int loops = LOOPS_DEFAULT;
+
+static const struct option options[] = {
+ OPT_INTEGER('l', "loop", &loops,
+ "Specify number of loops"),
+ OPT_END()
+};
+
+static const char * const bench_sched_pipe_usage[] = {
+ "perf bench sched pipe <options>",
+ NULL
+};
+
+int bench_sched_pipe(int argc, const char **argv,
+ const char *prefix __used)
+{
+ int pipe_1[2], pipe_2[2];
+ int m = 0, i;
+ struct timeval start, stop, diff;
+ unsigned long long result_usec = 0;
+
+ /*
+ * why does "ret" exist?
+ * discarding returned value of read(), write()
+ * causes error in building environment for perf
+ */
+ int ret, wait_stat;
+ pid_t pid, retpid;
+
+ argc = parse_options(argc, argv, options,
+ bench_sched_pipe_usage, 0);
+
+ assert(!pipe(pipe_1));
+ assert(!pipe(pipe_2));
+
+ pid = fork();
+ assert(pid >= 0);
+
+ gettimeofday(&start, NULL);
+
+ if (!pid) {
+ for (i = 0; i < loops; i++) {
+ ret = read(pipe_1[0], &m, sizeof(int));
+ ret = write(pipe_2[1], &m, sizeof(int));
+ }
+ } else {
+ for (i = 0; i < loops; i++) {
+ ret = write(pipe_1[1], &m, sizeof(int));
+ ret = read(pipe_2[0], &m, sizeof(int));
+ }
+ }
+
+ gettimeofday(&stop, NULL);
+ timersub(&stop, &start, &diff);
+
+ if (pid) {
+ retpid = waitpid(pid, &wait_stat, 0);
+ assert((retpid == pid) && WIFEXITED(wait_stat));
+ return 0;
+ }
+
+ switch (bench_format) {
+ case BENCH_FORMAT_DEFAULT:
+ printf("# Extecuted %d pipe operations between two tasks\n\n",
+ loops);
+
+ result_usec = diff.tv_sec * 1000000;
+ result_usec += diff.tv_usec;
+
+ printf(" %14s: %lu.%03lu [sec]\n\n", "Total time",
+ diff.tv_sec, diff.tv_usec/1000);
+
+ printf(" %14lf usecs/op\n",
+ (double)result_usec / (double)loops);
+ printf(" %14d ops/sec\n",
+ (int)((double)loops /
+ ((double)result_usec / (double)1000000)));
+ break;
+
+ case BENCH_FORMAT_SIMPLE:
+ printf("%lu.%03lu\n",
+ diff.tv_sec, diff.tv_usec / 1000);
+ break;
+
+ default:
+ /* reaching here is something disaster */
+ fprintf(stderr, "Unknown format:%d\n", bench_format);
+ exit(1);
+ break;
+ }
+
+ return 0;
+}
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 1ec741615814..0bf2e8f9af57 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -19,29 +19,26 @@
#include "perf.h"
#include "util/debug.h"
+#include "util/event.h"
#include "util/parse-options.h"
#include "util/parse-events.h"
#include "util/thread.h"
+#include "util/sort.h"
+#include "util/hist.h"
+#include "util/data_map.h"
static char const *input_name = "perf.data";
-static char default_sort_order[] = "comm,symbol";
-static char *sort_order = default_sort_order;
-
static int force;
-static int input;
-static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
static int full_paths;
static int print_line;
-static unsigned long page_size;
-static unsigned long mmap_window = 32;
-
-static struct rb_root threads;
-static struct thread *last_match;
-
+struct sym_hist {
+ u64 sum;
+ u64 ip[0];
+};
struct sym_ext {
struct rb_node node;
@@ -49,247 +46,38 @@ struct sym_ext {
char *path;
};
-/*
- * histogram, sorted on item, collects counts
- */
-
-static struct rb_root hist;
-
-struct hist_entry {
- struct rb_node rb_node;
-
- struct thread *thread;
- struct map *map;
- struct dso *dso;
- struct symbol *sym;
- u64 ip;
- char level;
-
- uint32_t count;
-};
-
-/*
- * configurable sorting bits
- */
-
-struct sort_entry {
- struct list_head list;
-
- const char *header;
-
- int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
- int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
- size_t (*print)(FILE *fp, struct hist_entry *);
-};
-
-/* --sort pid */
-
-static int64_t
-sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- return right->thread->pid - left->thread->pid;
-}
-
-static size_t
-sort__thread_print(FILE *fp, struct hist_entry *self)
-{
- return fprintf(fp, "%16s:%5d", self->thread->comm ?: "", self->thread->pid);
-}
-
-static struct sort_entry sort_thread = {
- .header = " Command: Pid",
- .cmp = sort__thread_cmp,
- .print = sort__thread_print,
-};
-
-/* --sort comm */
-
-static int64_t
-sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- return right->thread->pid - left->thread->pid;
-}
-
-static int64_t
-sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
-{
- char *comm_l = left->thread->comm;
- char *comm_r = right->thread->comm;
-
- if (!comm_l || !comm_r) {
- if (!comm_l && !comm_r)
- return 0;
- else if (!comm_l)
- return -1;
- else
- return 1;
- }
-
- return strcmp(comm_l, comm_r);
-}
-
-static size_t
-sort__comm_print(FILE *fp, struct hist_entry *self)
-{
- return fprintf(fp, "%16s", self->thread->comm);
-}
-
-static struct sort_entry sort_comm = {
- .header = " Command",
- .cmp = sort__comm_cmp,
- .collapse = sort__comm_collapse,
- .print = sort__comm_print,
-};
-
-/* --sort dso */
-
-static int64_t
-sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- struct dso *dso_l = left->dso;
- struct dso *dso_r = right->dso;
-
- if (!dso_l || !dso_r) {
- if (!dso_l && !dso_r)
- return 0;
- else if (!dso_l)
- return -1;
- else
- return 1;
- }
-
- return strcmp(dso_l->name, dso_r->name);
-}
-
-static size_t
-sort__dso_print(FILE *fp, struct hist_entry *self)
-{
- if (self->dso)
- return fprintf(fp, "%-25s", self->dso->name);
-
- return fprintf(fp, "%016llx ", (u64)self->ip);
-}
-
-static struct sort_entry sort_dso = {
- .header = "Shared Object ",
- .cmp = sort__dso_cmp,
- .print = sort__dso_print,
-};
-
-/* --sort symbol */
-
-static int64_t
-sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- u64 ip_l, ip_r;
-
- if (left->sym == right->sym)
- return 0;
-
- ip_l = left->sym ? left->sym->start : left->ip;
- ip_r = right->sym ? right->sym->start : right->ip;
-
- return (int64_t)(ip_r - ip_l);
-}
-
-static size_t
-sort__sym_print(FILE *fp, struct hist_entry *self)
-{
- size_t ret = 0;
-
- if (verbose)
- ret += fprintf(fp, "%#018llx ", (u64)self->ip);
-
- if (self->sym) {
- ret += fprintf(fp, "[%c] %s",
- self->dso == kernel_dso ? 'k' : '.', self->sym->name);
- } else {
- ret += fprintf(fp, "%#016llx", (u64)self->ip);
- }
-
- return ret;
-}
-
-static struct sort_entry sort_sym = {
- .header = "Symbol",
- .cmp = sort__sym_cmp,
- .print = sort__sym_print,
-};
-
-static int sort__need_collapse = 0;
-
-struct sort_dimension {
- const char *name;
- struct sort_entry *entry;
- int taken;
+struct sym_priv {
+ struct sym_hist *hist;
+ struct sym_ext *ext;
};
-static struct sort_dimension sort_dimensions[] = {
- { .name = "pid", .entry = &sort_thread, },
- { .name = "comm", .entry = &sort_comm, },
- { .name = "dso", .entry = &sort_dso, },
- { .name = "symbol", .entry = &sort_sym, },
+static struct symbol_conf symbol_conf = {
+ .priv_size = sizeof(struct sym_priv),
+ .try_vmlinux_path = true,
};
-static LIST_HEAD(hist_entry__sort_list);
+static const char *sym_hist_filter;
-static int sort_dimension__add(char *tok)
+static int symbol_filter(struct map *map __used, struct symbol *sym)
{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
- struct sort_dimension *sd = &sort_dimensions[i];
-
- if (sd->taken)
- continue;
-
- if (strncasecmp(tok, sd->name, strlen(tok)))
- continue;
-
- if (sd->entry->collapse)
- sort__need_collapse = 1;
-
- list_add_tail(&sd->entry->list, &hist_entry__sort_list);
- sd->taken = 1;
+ if (sym_hist_filter == NULL ||
+ strcmp(sym->name, sym_hist_filter) == 0) {
+ struct sym_priv *priv = symbol__priv(sym);
+ const int size = (sizeof(*priv->hist) +
+ (sym->end - sym->start) * sizeof(u64));
+ priv->hist = malloc(size);
+ if (priv->hist)
+ memset(priv->hist, 0, size);
return 0;
}
-
- return -ESRCH;
-}
-
-static int64_t
-hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
-{
- struct sort_entry *se;
- int64_t cmp = 0;
-
- list_for_each_entry(se, &hist_entry__sort_list, list) {
- cmp = se->cmp(left, right);
- if (cmp)
- break;
- }
-
- return cmp;
-}
-
-static int64_t
-hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
-{
- struct sort_entry *se;
- int64_t cmp = 0;
-
- list_for_each_entry(se, &hist_entry__sort_list, list) {
- int64_t (*f)(struct hist_entry *, struct hist_entry *);
-
- f = se->collapse ?: se->cmp;
-
- cmp = f(left, right);
- if (cmp)
- break;
- }
-
- return cmp;
+ /*
+ * FIXME: We should really filter it out, as we don't want to go thru symbols
+ * we're not interested, and if a DSO ends up with no symbols, delete it too,
+ * but right now the kernel loading routines in symbol.c bail out if no symbols
+ * are found, fix it later.
+ */
+ return 0;
}
/*
@@ -299,380 +87,81 @@ static void hist_hit(struct hist_entry *he, u64 ip)
{
unsigned int sym_size, offset;
struct symbol *sym = he->sym;
+ struct sym_priv *priv;
+ struct sym_hist *h;
he->count++;
- if (!sym || !sym->hist)
+ if (!sym || !he->map)
+ return;
+
+ priv = symbol__priv(sym);
+ if (!priv->hist)
return;
sym_size = sym->end - sym->start;
offset = ip - sym->start;
+ if (verbose)
+ fprintf(stderr, "%s: ip=%Lx\n", __func__,
+ he->map->unmap_ip(he->map, ip));
+
if (offset >= sym_size)
return;
- sym->hist_sum++;
- sym->hist[offset]++;
+ h = priv->hist;
+ h->sum++;
+ h->ip[offset]++;
if (verbose >= 3)
printf("%p %s: count++ [ip: %p, %08Lx] => %Ld\n",
(void *)(unsigned long)he->sym->start,
he->sym->name,
(void *)(unsigned long)ip, ip - he->sym->start,
- sym->hist[offset]);
+ h->ip[offset]);
}
-static int
-hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
- struct symbol *sym, u64 ip, char level)
+static int hist_entry__add(struct addr_location *al, u64 count)
{
- struct rb_node **p = &hist.rb_node;
- struct rb_node *parent = NULL;
- struct hist_entry *he;
- struct hist_entry entry = {
- .thread = thread,
- .map = map,
- .dso = dso,
- .sym = sym,
- .ip = ip,
- .level = level,
- .count = 1,
- };
- int cmp;
-
- while (*p != NULL) {
- parent = *p;
- he = rb_entry(parent, struct hist_entry, rb_node);
-
- cmp = hist_entry__cmp(&entry, he);
-
- if (!cmp) {
- hist_hit(he, ip);
-
- return 0;
- }
-
- if (cmp < 0)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- he = malloc(sizeof(*he));
- if (!he)
+ bool hit;
+ struct hist_entry *he = __hist_entry__add(al, NULL, count, &hit);
+ if (he == NULL)
return -ENOMEM;
- *he = entry;
- rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, &hist);
-
+ hist_hit(he, al->addr);
return 0;
}
-static void hist_entry__free(struct hist_entry *he)
-{
- free(he);
-}
-
-/*
- * collapse the histogram
- */
-
-static struct rb_root collapse_hists;
-
-static void collapse__insert_entry(struct hist_entry *he)
-{
- struct rb_node **p = &collapse_hists.rb_node;
- struct rb_node *parent = NULL;
- struct hist_entry *iter;
- int64_t cmp;
-
- while (*p != NULL) {
- parent = *p;
- iter = rb_entry(parent, struct hist_entry, rb_node);
-
- cmp = hist_entry__collapse(iter, he);
-
- if (!cmp) {
- iter->count += he->count;
- hist_entry__free(he);
- return;
- }
-
- if (cmp < 0)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, &collapse_hists);
-}
-
-static void collapse__resort(void)
-{
- struct rb_node *next;
- struct hist_entry *n;
-
- if (!sort__need_collapse)
- return;
-
- next = rb_first(&hist);
- while (next) {
- n = rb_entry(next, struct hist_entry, rb_node);
- next = rb_next(&n->rb_node);
-
- rb_erase(&n->rb_node, &hist);
- collapse__insert_entry(n);
- }
-}
-
-/*
- * reverse the map, sort on count.
- */
-
-static struct rb_root output_hists;
-
-static void output__insert_entry(struct hist_entry *he)
+static int process_sample_event(event_t *event)
{
- struct rb_node **p = &output_hists.rb_node;
- struct rb_node *parent = NULL;
- struct hist_entry *iter;
+ struct addr_location al;
- while (*p != NULL) {
- parent = *p;
- iter = rb_entry(parent, struct hist_entry, rb_node);
+ dump_printf("(IP, %d): %d: %p\n", event->header.misc,
+ event->ip.pid, (void *)(long)event->ip.ip);
- if (he->count > iter->count)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, &output_hists);
-}
-
-static void output__resort(void)
-{
- struct rb_node *next;
- struct hist_entry *n;
- struct rb_root *tree = &hist;
-
- if (sort__need_collapse)
- tree = &collapse_hists;
-
- next = rb_first(tree);
-
- while (next) {
- n = rb_entry(next, struct hist_entry, rb_node);
- next = rb_next(&n->rb_node);
-
- rb_erase(&n->rb_node, tree);
- output__insert_entry(n);
- }
-}
-
-static unsigned long total = 0,
- total_mmap = 0,
- total_comm = 0,
- total_fork = 0,
- total_unknown = 0;
-
-static int
-process_sample_event(event_t *event, unsigned long offset, unsigned long head)
-{
- char level;
- int show = 0;
- struct dso *dso = NULL;
- struct thread *thread;
- u64 ip = event->ip.ip;
- struct map *map = NULL;
-
- thread = threads__findnew(event->ip.pid, &threads, &last_match);
-
- dump_printf("%p [%p]: PERF_EVENT (IP, %d): %d: %p\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->header.misc,
- event->ip.pid,
- (void *)(long)ip);
-
- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
-
- if (thread == NULL) {
+ if (event__preprocess_sample(event, &al, symbol_filter) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
}
- if (event->header.misc & PERF_RECORD_MISC_KERNEL) {
- show = SHOW_KERNEL;
- level = 'k';
-
- dso = kernel_dso;
-
- dump_printf(" ...... dso: %s\n", dso->name);
-
- } else if (event->header.misc & PERF_RECORD_MISC_USER) {
-
- show = SHOW_USER;
- level = '.';
-
- map = thread__find_map(thread, ip);
- if (map != NULL) {
- ip = map->map_ip(map, ip);
- dso = map->dso;
- } else {
- /*
- * If this is outside of all known maps,
- * and is a negative address, try to look it
- * up in the kernel dso, as it might be a
- * vsyscall (which executes in user-mode):
- */
- if ((long long)ip < 0)
- dso = kernel_dso;
- }
- dump_printf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
-
- } else {
- show = SHOW_HV;
- level = 'H';
- dump_printf(" ...... dso: [hypervisor]\n");
- }
-
- if (show & show_mask) {
- struct symbol *sym = NULL;
-
- if (dso)
- sym = dso->find_symbol(dso, ip);
-
- if (hist_entry__add(thread, map, dso, sym, ip, level)) {
- fprintf(stderr,
- "problem incrementing symbol count, skipping event\n");
- return -1;
- }
- }
- total++;
-
- return 0;
-}
-
-static int
-process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
-{
- struct thread *thread;
- struct map *map = map__new(&event->mmap, NULL, 0);
-
- thread = threads__findnew(event->mmap.pid, &threads, &last_match);
-
- dump_printf("%p [%p]: PERF_RECORD_MMAP %d: [%p(%p) @ %p]: %s\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->mmap.pid,
- (void *)(long)event->mmap.start,
- (void *)(long)event->mmap.len,
- (void *)(long)event->mmap.pgoff,
- event->mmap.filename);
-
- if (thread == NULL || map == NULL) {
- dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
- return 0;
- }
-
- thread__insert_map(thread, map);
- total_mmap++;
-
- return 0;
-}
-
-static int
-process_comm_event(event_t *event, unsigned long offset, unsigned long head)
-{
- struct thread *thread;
-
- thread = threads__findnew(event->comm.pid, &threads, &last_match);
- dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->comm.comm, event->comm.pid);
-
- if (thread == NULL ||
- thread__set_comm(thread, event->comm.comm)) {
- dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
- return -1;
- }
- total_comm++;
-
- return 0;
-}
-
-static int
-process_fork_event(event_t *event, unsigned long offset, unsigned long head)
-{
- struct thread *thread;
- struct thread *parent;
-
- thread = threads__findnew(event->fork.pid, &threads, &last_match);
- parent = threads__findnew(event->fork.ppid, &threads, &last_match);
- dump_printf("%p [%p]: PERF_RECORD_FORK: %d:%d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->fork.pid, event->fork.ppid);
-
- /*
- * A thread clone will have the same PID for both
- * parent and child.
- */
- if (thread == parent)
- return 0;
-
- if (!thread || !parent || thread__fork(thread, parent)) {
- dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
- return -1;
- }
- total_fork++;
-
- return 0;
-}
-
-static int
-process_event(event_t *event, unsigned long offset, unsigned long head)
-{
- switch (event->header.type) {
- case PERF_RECORD_SAMPLE:
- return process_sample_event(event, offset, head);
-
- case PERF_RECORD_MMAP:
- return process_mmap_event(event, offset, head);
-
- case PERF_RECORD_COMM:
- return process_comm_event(event, offset, head);
-
- case PERF_RECORD_FORK:
- return process_fork_event(event, offset, head);
- /*
- * We dont process them right now but they are fine:
- */
-
- case PERF_RECORD_THROTTLE:
- case PERF_RECORD_UNTHROTTLE:
- return 0;
-
- default:
+ if (hist_entry__add(&al, 1)) {
+ fprintf(stderr, "problem incrementing symbol count, "
+ "skipping event\n");
return -1;
}
return 0;
}
-static int
-parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
+static int parse_line(FILE *file, struct hist_entry *he, u64 len)
{
+ struct symbol *sym = he->sym;
char *line = NULL, *tmp, *tmp2;
static const char *prev_line;
static const char *prev_color;
unsigned int offset;
size_t line_len;
+ u64 start;
s64 line_ip;
int ret;
char *c;
@@ -709,22 +198,26 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
line_ip = -1;
}
+ start = he->map->unmap_ip(he->map, sym->start);
+
if (line_ip != -1) {
const char *path = NULL;
unsigned int hits = 0;
double percent = 0.0;
const char *color;
- struct sym_ext *sym_ext = sym->priv;
+ struct sym_priv *priv = symbol__priv(sym);
+ struct sym_ext *sym_ext = priv->ext;
+ struct sym_hist *h = priv->hist;
offset = line_ip - start;
if (offset < len)
- hits = sym->hist[offset];
+ hits = h->ip[offset];
if (offset < len && sym_ext) {
path = sym_ext[offset].path;
percent = sym_ext[offset].percent;
- } else if (sym->hist_sum)
- percent = 100.0 * hits / sym->hist_sum;
+ } else if (h->sum)
+ percent = 100.0 * hits / h->sum;
color = get_percent_color(percent);
@@ -777,9 +270,10 @@ static void insert_source_line(struct sym_ext *sym_ext)
rb_insert_color(&sym_ext->node, &root_sym_ext);
}
-static void free_source_line(struct symbol *sym, int len)
+static void free_source_line(struct hist_entry *he, int len)
{
- struct sym_ext *sym_ext = sym->priv;
+ struct sym_priv *priv = symbol__priv(he->sym);
+ struct sym_ext *sym_ext = priv->ext;
int i;
if (!sym_ext)
@@ -789,26 +283,30 @@ static void free_source_line(struct symbol *sym, int len)
free(sym_ext[i].path);
free(sym_ext);
- sym->priv = NULL;
+ priv->ext = NULL;
root_sym_ext = RB_ROOT;
}
/* Get the filename:line for the colored entries */
static void
-get_source_line(struct symbol *sym, u64 start, int len, const char *filename)
+get_source_line(struct hist_entry *he, int len, const char *filename)
{
+ struct symbol *sym = he->sym;
+ u64 start;
int i;
char cmd[PATH_MAX * 2];
struct sym_ext *sym_ext;
+ struct sym_priv *priv = symbol__priv(sym);
+ struct sym_hist *h = priv->hist;
- if (!sym->hist_sum)
+ if (!h->sum)
return;
- sym->priv = calloc(len, sizeof(struct sym_ext));
- if (!sym->priv)
+ sym_ext = priv->ext = calloc(len, sizeof(struct sym_ext));
+ if (!priv->ext)
return;
- sym_ext = sym->priv;
+ start = he->map->unmap_ip(he->map, sym->start);
for (i = 0; i < len; i++) {
char *path = NULL;
@@ -816,7 +314,7 @@ get_source_line(struct symbol *sym, u64 start, int len, const char *filename)
u64 offset;
FILE *fp;
- sym_ext[i].percent = 100.0 * sym->hist[i] / sym->hist_sum;
+ sym_ext[i].percent = 100.0 * h->ip[i] / h->sum;
if (sym_ext[i].percent <= 0.5)
continue;
@@ -870,33 +368,34 @@ static void print_summary(const char *filename)
}
}
-static void annotate_sym(struct dso *dso, struct symbol *sym)
+static void annotate_sym(struct hist_entry *he)
{
- const char *filename = dso->name, *d_filename;
- u64 start, end, len;
+ struct map *map = he->map;
+ struct dso *dso = map->dso;
+ struct symbol *sym = he->sym;
+ const char *filename = dso->long_name, *d_filename;
+ u64 len;
char command[PATH_MAX*2];
FILE *file;
if (!filename)
return;
- if (sym->module)
- filename = sym->module->path;
- else if (dso == kernel_dso)
- filename = vmlinux_name;
-
- start = sym->obj_start;
- if (!start)
- start = sym->start;
+
+ if (verbose)
+ fprintf(stderr, "%s: filename=%s, sym=%s, start=%Lx, end=%Lx\n",
+ __func__, filename, sym->name,
+ map->unmap_ip(map, sym->start),
+ map->unmap_ip(map, sym->end));
+
if (full_paths)
d_filename = filename;
else
d_filename = basename(filename);
- end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
if (print_line) {
- get_source_line(sym, start, len, filename);
+ get_source_line(he, len, filename);
print_summary(filename);
}
@@ -905,10 +404,12 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
printf("------------------------------------------------\n");
if (verbose >= 2)
- printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
+ printf("annotating [%p] %30s : [%p] %30s\n",
+ dso, dso->long_name, sym, sym->name);
sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
- (u64)start, (u64)end, filename, filename);
+ map->unmap_ip(map, sym->start), map->unmap_ip(map, sym->end),
+ filename, filename);
if (verbose >= 3)
printf("doing: %s\n", command);
@@ -918,159 +419,78 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
return;
while (!feof(file)) {
- if (parse_line(file, sym, start, len) < 0)
+ if (parse_line(file, he, len) < 0)
break;
}
pclose(file);
if (print_line)
- free_source_line(sym, len);
+ free_source_line(he, len);
}
static void find_annotations(void)
{
struct rb_node *nd;
- struct dso *dso;
- int count = 0;
-
- list_for_each_entry(dso, &dsos, node) {
-
- for (nd = rb_first(&dso->syms); nd; nd = rb_next(nd)) {
- struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
-
- if (sym->hist) {
- annotate_sym(dso, sym);
- count++;
- }
- }
- }
-
- if (!count)
- printf(" Error: symbol '%s' not present amongst the samples.\n", sym_hist_filter);
-}
-
-static int __cmd_annotate(void)
-{
- int ret, rc = EXIT_FAILURE;
- unsigned long offset = 0;
- unsigned long head = 0;
- struct stat input_stat;
- event_t *event;
- uint32_t size;
- char *buf;
-
- register_idle_thread(&threads, &last_match);
-
- input = open(input_name, O_RDONLY);
- if (input < 0) {
- perror("failed to open file");
- exit(-1);
- }
-
- ret = fstat(input, &input_stat);
- if (ret < 0) {
- perror("failed to stat file");
- exit(-1);
- }
-
- if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
- fprintf(stderr, "file: %s not owned by current user or root\n", input_name);
- exit(-1);
- }
-
- if (!input_stat.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- exit(0);
- }
-
- if (load_kernel() < 0) {
- perror("failed to load kernel symbols");
- return EXIT_FAILURE;
- }
-
-remap:
- buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
- MAP_SHARED, input, offset);
- if (buf == MAP_FAILED) {
- perror("failed to mmap file");
- exit(-1);
- }
-
-more:
- event = (event_t *)(buf + head);
- size = event->header.size;
- if (!size)
- size = 8;
+ for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) {
+ struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
+ struct sym_priv *priv;
- if (head + event->header.size >= page_size * mmap_window) {
- unsigned long shift = page_size * (head / page_size);
- int munmap_ret;
-
- munmap_ret = munmap(buf, page_size * mmap_window);
- assert(munmap_ret == 0);
-
- offset += shift;
- head -= shift;
- goto remap;
- }
-
- size = event->header.size;
-
- dump_printf("%p [%p]: event: %d\n",
- (void *)(offset + head),
- (void *)(long)event->header.size,
- event->header.type);
-
- if (!size || process_event(event, offset, head) < 0) {
-
- dump_printf("%p [%p]: skipping unknown header type: %d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->header.type);
+ if (he->sym == NULL)
+ continue;
- total_unknown++;
+ priv = symbol__priv(he->sym);
+ if (priv->hist == NULL)
+ continue;
+ annotate_sym(he);
/*
- * assume we lost track of the stream, check alignment, and
- * increment a single u64 in the hope to catch on again 'soon'.
+ * Since we have a hist_entry per IP for the same symbol, free
+ * he->sym->hist to signal we already processed this symbol.
*/
-
- if (unlikely(head & 7))
- head &= ~7ULL;
-
- size = 8;
+ free(priv->hist);
+ priv->hist = NULL;
}
+}
- head += size;
+static struct perf_file_handler file_handler = {
+ .process_sample_event = process_sample_event,
+ .process_mmap_event = event__process_mmap,
+ .process_comm_event = event__process_comm,
+ .process_fork_event = event__process_task,
+};
- if (offset + head < (unsigned long)input_stat.st_size)
- goto more;
+static int __cmd_annotate(void)
+{
+ struct perf_header *header;
+ struct thread *idle;
+ int ret;
- rc = EXIT_SUCCESS;
- close(input);
+ idle = register_idle_thread();
+ register_perf_file_handler(&file_handler);
- dump_printf(" IP events: %10ld\n", total);
- dump_printf(" mmap events: %10ld\n", total_mmap);
- dump_printf(" comm events: %10ld\n", total_comm);
- dump_printf(" fork events: %10ld\n", total_fork);
- dump_printf(" unknown events: %10ld\n", total_unknown);
+ ret = mmap_dispatch_perf_file(&header, input_name, 0, 0,
+ &event__cwdlen, &event__cwd);
+ if (ret)
+ return ret;
- if (dump_trace)
+ if (dump_trace) {
+ event__print_totals();
return 0;
+ }
- if (verbose >= 3)
- threads__fprintf(stdout, &threads);
+ if (verbose > 3)
+ threads__fprintf(stdout);
- if (verbose >= 2)
+ if (verbose > 2)
dsos__fprintf(stdout);
collapse__resort();
- output__resort();
+ output__resort(event__total[0]);
find_annotations();
- return rc;
+ return ret;
}
static const char * const annotate_usage[] = {
@@ -1088,8 +508,9 @@ static const struct option options[] = {
"be more verbose (show symbol address, etc)"),
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
- OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"),
- OPT_BOOLEAN('m', "modules", &modules,
+ OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
+ "file", "vmlinux pathname"),
+ OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
"load module symbols - WARNING: use only with -k and LIVE kernel"),
OPT_BOOLEAN('l', "print-line", &print_line,
"print matching source lines (may be slow)"),
@@ -1115,9 +536,8 @@ static void setup_sorting(void)
int cmd_annotate(int argc, const char **argv, const char *prefix __used)
{
- symbol__init();
-
- page_size = getpagesize();
+ if (symbol__init(&symbol_conf) < 0)
+ return -1;
argc = parse_options(argc, argv, options, annotate_usage, 0);
@@ -1134,10 +554,13 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
sym_hist_filter = argv[0];
}
- if (!sym_hist_filter)
- usage_with_options(annotate_usage, options);
-
setup_pager();
+ if (field_sep && *field_sep == '.') {
+ fputs("'.' is the only non valid --field-separator argument\n",
+ stderr);
+ exit(129);
+ }
+
return __cmd_annotate();
}
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
new file mode 100644
index 000000000000..e043eb83092a
--- /dev/null
+++ b/tools/perf/builtin-bench.c
@@ -0,0 +1,196 @@
+/*
+ *
+ * builtin-bench.c
+ *
+ * General benchmarking subsystem provided by perf
+ *
+ * Copyright (C) 2009, Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
+ *
+ */
+
+/*
+ *
+ * Available subsystem list:
+ * sched ... scheduler and IPC mechanism
+ * mem ... memory access performance
+ *
+ */
+
+#include "perf.h"
+#include "util/util.h"
+#include "util/parse-options.h"
+#include "builtin.h"
+#include "bench/bench.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct bench_suite {
+ const char *name;
+ const char *summary;
+ int (*fn)(int, const char **, const char *);
+};
+
+static struct bench_suite sched_suites[] = {
+ { "messaging",
+ "Benchmark for scheduler and IPC mechanisms",
+ bench_sched_messaging },
+ { "pipe",
+ "Flood of communication over pipe() between two processes",
+ bench_sched_pipe },
+ { NULL,
+ NULL,
+ NULL }
+};
+
+static struct bench_suite mem_suites[] = {
+ { "memcpy",
+ "Simple memory copy in various ways",
+ bench_mem_memcpy },
+ { NULL,
+ NULL,
+ NULL }
+};
+
+struct bench_subsys {
+ const char *name;
+ const char *summary;
+ struct bench_suite *suites;
+};
+
+static struct bench_subsys subsystems[] = {
+ { "sched",
+ "scheduler and IPC mechanism",
+ sched_suites },
+ { "mem",
+ "memory access performance",
+ mem_suites },
+ { NULL,
+ NULL,
+ NULL }
+};
+
+static void dump_suites(int subsys_index)
+{
+ int i;
+
+ printf("List of available suites for %s...\n\n",
+ subsystems[subsys_index].name);
+
+ for (i = 0; subsystems[subsys_index].suites[i].name; i++)
+ printf("\t%s: %s\n",
+ subsystems[subsys_index].suites[i].name,
+ subsystems[subsys_index].suites[i].summary);
+
+ printf("\n");
+ return;
+}
+
+static char *bench_format_str;
+int bench_format = BENCH_FORMAT_DEFAULT;
+
+static const struct option bench_options[] = {
+ OPT_STRING('f', "format", &bench_format_str, "default",
+ "Specify format style"),
+ OPT_END()
+};
+
+static const char * const bench_usage[] = {
+ "perf bench [<common options>] <subsystem> <suite> [<options>]",
+ NULL
+};
+
+static void print_usage(void)
+{
+ int i;
+
+ printf("Usage: \n");
+ for (i = 0; bench_usage[i]; i++)
+ printf("\t%s\n", bench_usage[i]);
+ printf("\n");
+
+ printf("List of available subsystems...\n\n");
+
+ for (i = 0; subsystems[i].name; i++)
+ printf("\t%s: %s\n",
+ subsystems[i].name, subsystems[i].summary);
+ printf("\n");
+}
+
+static int bench_str2int(char *str)
+{
+ if (!str)
+ return BENCH_FORMAT_DEFAULT;
+
+ if (!strcmp(str, BENCH_FORMAT_DEFAULT_STR))
+ return BENCH_FORMAT_DEFAULT;
+ else if (!strcmp(str, BENCH_FORMAT_SIMPLE_STR))
+ return BENCH_FORMAT_SIMPLE;
+
+ return BENCH_FORMAT_UNKNOWN;
+}
+
+int cmd_bench(int argc, const char **argv, const char *prefix __used)
+{
+ int i, j, status = 0;
+
+ if (argc < 2) {
+ /* No subsystem specified. */
+ print_usage();
+ goto end;
+ }
+
+ argc = parse_options(argc, argv, bench_options, bench_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+
+ bench_format = bench_str2int(bench_format_str);
+ if (bench_format == BENCH_FORMAT_UNKNOWN) {
+ printf("Unknown format descriptor:%s\n", bench_format_str);
+ goto end;
+ }
+
+ if (argc < 1) {
+ print_usage();
+ goto end;
+ }
+
+ for (i = 0; subsystems[i].name; i++) {
+ if (strcmp(subsystems[i].name, argv[0]))
+ continue;
+
+ if (argc < 2) {
+ /* No suite specified. */
+ dump_suites(i);
+ goto end;
+ }
+
+ for (j = 0; subsystems[i].suites[j].name; j++) {
+ if (strcmp(subsystems[i].suites[j].name, argv[1]))
+ continue;
+
+ if (bench_format == BENCH_FORMAT_DEFAULT)
+ printf("# Running %s/%s benchmark...\n",
+ subsystems[i].name,
+ subsystems[i].suites[j].name);
+ status = subsystems[i].suites[j].fn(argc - 1,
+ argv + 1, prefix);
+ goto end;
+ }
+
+ if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
+ dump_suites(i);
+ goto end;
+ }
+
+ printf("Unknown suite:%s for %s\n", argv[1], argv[0]);
+ status = 1;
+ goto end;
+ }
+
+ printf("Unknown subsystem:%s\n", argv[0]);
+ status = 1;
+
+end:
+ return status;
+}
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
new file mode 100644
index 000000000000..7dee9d19ab7a
--- /dev/null
+++ b/tools/perf/builtin-buildid-list.c
@@ -0,0 +1,116 @@
+/*
+ * builtin-buildid-list.c
+ *
+ * Builtin buildid-list command: list buildids in perf.data
+ *
+ * Copyright (C) 2009, Red Hat Inc.
+ * Copyright (C) 2009, Arnaldo Carvalho de Melo <acme@redhat.com>
+ */
+#include "builtin.h"
+#include "perf.h"
+#include "util/cache.h"
+#include "util/data_map.h"
+#include "util/debug.h"
+#include "util/header.h"
+#include "util/parse-options.h"
+#include "util/symbol.h"
+
+static char const *input_name = "perf.data";
+static int force;
+
+static const char *const buildid_list_usage[] = {
+ "perf report [<options>]",
+ NULL
+};
+
+static const struct option options[] = {
+ OPT_STRING('i', "input", &input_name, "file",
+ "input file name"),
+ OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
+ OPT_BOOLEAN('v', "verbose", &verbose,
+ "be more verbose"),
+ OPT_END()
+};
+
+static int perf_file_section__process_buildids(struct perf_file_section *self,
+ int feat, int fd)
+{
+ if (feat != HEADER_BUILD_ID)
+ return 0;
+
+ if (lseek(fd, self->offset, SEEK_SET) < 0) {
+ pr_warning("Failed to lseek to %Ld offset for buildids!\n",
+ self->offset);
+ return -1;
+ }
+
+ if (perf_header__read_build_ids(fd, self->offset, self->size)) {
+ pr_warning("Failed to read buildids!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __cmd_buildid_list(void)
+{
+ int err = -1;
+ struct perf_header *header;
+ struct perf_file_header f_header;
+ struct stat input_stat;
+ int input = open(input_name, O_RDONLY);
+
+ if (input < 0) {
+ pr_err("failed to open file: %s", input_name);
+ if (!strcmp(input_name, "perf.data"))
+ pr_err(" (try 'perf record' first)");
+ pr_err("\n");
+ goto out;
+ }
+
+ err = fstat(input, &input_stat);
+ if (err < 0) {
+ perror("failed to stat file");
+ goto out_close;
+ }
+
+ if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
+ pr_err("file %s not owned by current user or root\n",
+ input_name);
+ goto out_close;
+ }
+
+ if (!input_stat.st_size) {
+ pr_info("zero-sized file, nothing to do!\n");
+ goto out_close;
+ }
+
+ err = -1;
+ header = perf_header__new();
+ if (header == NULL)
+ goto out_close;
+
+ if (perf_file_header__read(&f_header, header, input) < 0) {
+ pr_warning("incompatible file format");
+ goto out_close;
+ }
+
+ err = perf_header__process_sections(header, input,
+ perf_file_section__process_buildids);
+
+ if (err < 0)
+ goto out_close;
+
+ dsos__fprintf_buildid(stdout);
+out_close:
+ close(input);
+out:
+ return err;
+}
+
+int cmd_buildid_list(int argc, const char **argv, const char *prefix __used)
+{
+ argc = parse_options(argc, argv, options, buildid_list_usage, 0);
+ setup_pager();
+ return __cmd_buildid_list();
+}
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 4fb8734a796e..9f810b17c25c 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -61,8 +61,7 @@ static const char *get_man_viewer_info(const char *name)
{
struct man_viewer_info_list *viewer;
- for (viewer = man_viewer_info_list; viewer; viewer = viewer->next)
- {
+ for (viewer = man_viewer_info_list; viewer; viewer = viewer->next) {
if (!strcasecmp(name, viewer->name))
return viewer->info;
}
@@ -115,7 +114,7 @@ static int check_emacsclient_version(void)
return 0;
}
-static void exec_woman_emacs(const char* path, const char *page)
+static void exec_woman_emacs(const char *path, const char *page)
{
if (!check_emacsclient_version()) {
/* This works only with emacsclient version >= 22. */
@@ -129,7 +128,7 @@ static void exec_woman_emacs(const char* path, const char *page)
}
}
-static void exec_man_konqueror(const char* path, const char *page)
+static void exec_man_konqueror(const char *path, const char *page)
{
const char *display = getenv("DISPLAY");
if (display && *display) {
@@ -157,7 +156,7 @@ static void exec_man_konqueror(const char* path, const char *page)
}
}
-static void exec_man_man(const char* path, const char *page)
+static void exec_man_man(const char *path, const char *page)
{
if (!path)
path = "man";
@@ -180,7 +179,7 @@ static void add_man_viewer(const char *name)
while (*p)
p = &((*p)->next);
- *p = calloc(1, (sizeof(**p) + len + 1));
+ *p = zalloc(sizeof(**p) + len + 1);
strncpy((*p)->name, name, len);
}
@@ -195,7 +194,7 @@ static void do_add_man_viewer_info(const char *name,
size_t len,
const char *value)
{
- struct man_viewer_info_list *new = calloc(1, sizeof(*new) + len + 1);
+ struct man_viewer_info_list *new = zalloc(sizeof(*new) + len + 1);
strncpy(new->name, name, len);
new->info = strdup(value);
@@ -364,9 +363,8 @@ static void show_man_page(const char *perf_cmd)
setup_man_path();
for (viewer = man_viewer_list; viewer; viewer = viewer->next)
- {
exec_viewer(viewer->name, page); /* will return when unable */
- }
+
if (fallback)
exec_viewer(fallback, page);
exec_viewer("man", page);
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
new file mode 100644
index 000000000000..047fef74bd52
--- /dev/null
+++ b/tools/perf/builtin-kmem.c
@@ -0,0 +1,807 @@
+#include "builtin.h"
+#include "perf.h"
+
+#include "util/util.h"
+#include "util/cache.h"
+#include "util/symbol.h"
+#include "util/thread.h"
+#include "util/header.h"
+
+#include "util/parse-options.h"
+#include "util/trace-event.h"
+
+#include "util/debug.h"
+#include "util/data_map.h"
+
+#include <linux/rbtree.h>
+
+struct alloc_stat;
+typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *);
+
+static char const *input_name = "perf.data";
+
+static struct perf_header *header;
+static u64 sample_type;
+
+static int alloc_flag;
+static int caller_flag;
+
+static int alloc_lines = -1;
+static int caller_lines = -1;
+
+static bool raw_ip;
+
+static char default_sort_order[] = "frag,hit,bytes";
+
+static int *cpunode_map;
+static int max_cpu_num;
+
+struct alloc_stat {
+ u64 call_site;
+ u64 ptr;
+ u64 bytes_req;
+ u64 bytes_alloc;
+ u32 hit;
+ u32 pingpong;
+
+ short alloc_cpu;
+
+ struct rb_node node;
+};
+
+static struct rb_root root_alloc_stat;
+static struct rb_root root_alloc_sorted;
+static struct rb_root root_caller_stat;
+static struct rb_root root_caller_sorted;
+
+static unsigned long total_requested, total_allocated;
+static unsigned long nr_allocs, nr_cross_allocs;
+
+struct raw_event_sample {
+ u32 size;
+ char data[0];
+};
+
+#define PATH_SYS_NODE "/sys/devices/system/node"
+
+static void init_cpunode_map(void)
+{
+ FILE *fp;
+ int i;
+
+ fp = fopen("/sys/devices/system/cpu/kernel_max", "r");
+ if (!fp) {
+ max_cpu_num = 4096;
+ return;
+ }
+
+ if (fscanf(fp, "%d", &max_cpu_num) < 1)
+ die("Failed to read 'kernel_max' from sysfs");
+ max_cpu_num++;
+
+ cpunode_map = calloc(max_cpu_num, sizeof(int));
+ if (!cpunode_map)
+ die("calloc");
+ for (i = 0; i < max_cpu_num; i++)
+ cpunode_map[i] = -1;
+ fclose(fp);
+}
+
+static void setup_cpunode_map(void)
+{
+ struct dirent *dent1, *dent2;
+ DIR *dir1, *dir2;
+ unsigned int cpu, mem;
+ char buf[PATH_MAX];
+
+ init_cpunode_map();
+
+ dir1 = opendir(PATH_SYS_NODE);
+ if (!dir1)
+ return;
+
+ while (true) {
+ dent1 = readdir(dir1);
+ if (!dent1)
+ break;
+
+ if (sscanf(dent1->d_name, "node%u", &mem) < 1)
+ continue;
+
+ snprintf(buf, PATH_MAX, "%s/%s", PATH_SYS_NODE, dent1->d_name);
+ dir2 = opendir(buf);
+ if (!dir2)
+ continue;
+ while (true) {
+ dent2 = readdir(dir2);
+ if (!dent2)
+ break;
+ if (sscanf(dent2->d_name, "cpu%u", &cpu) < 1)
+ continue;
+ cpunode_map[cpu] = mem;
+ }
+ }
+}
+
+static void insert_alloc_stat(unsigned long call_site, unsigned long ptr,
+ int bytes_req, int bytes_alloc, int cpu)
+{
+ struct rb_node **node = &root_alloc_stat.rb_node;
+ struct rb_node *parent = NULL;
+ struct alloc_stat *data = NULL;
+
+ while (*node) {
+ parent = *node;
+ data = rb_entry(*node, struct alloc_stat, node);
+
+ if (ptr > data->ptr)
+ node = &(*node)->rb_right;
+ else if (ptr < data->ptr)
+ node = &(*node)->rb_left;
+ else
+ break;
+ }
+
+ if (data && data->ptr == ptr) {
+ data->hit++;
+ data->bytes_req += bytes_req;
+ data->bytes_alloc += bytes_req;
+ } else {
+ data = malloc(sizeof(*data));
+ if (!data)
+ die("malloc");
+ data->ptr = ptr;
+ data->pingpong = 0;
+ data->hit = 1;
+ data->bytes_req = bytes_req;
+ data->bytes_alloc = bytes_alloc;
+
+ rb_link_node(&data->node, parent, node);
+ rb_insert_color(&data->node, &root_alloc_stat);
+ }
+ data->call_site = call_site;
+ data->alloc_cpu = cpu;
+}
+
+static void insert_caller_stat(unsigned long call_site,
+ int bytes_req, int bytes_alloc)
+{
+ struct rb_node **node = &root_caller_stat.rb_node;
+ struct rb_node *parent = NULL;
+ struct alloc_stat *data = NULL;
+
+ while (*node) {
+ parent = *node;
+ data = rb_entry(*node, struct alloc_stat, node);
+
+ if (call_site > data->call_site)
+ node = &(*node)->rb_right;
+ else if (call_site < data->call_site)
+ node = &(*node)->rb_left;
+ else
+ break;
+ }
+
+ if (data && data->call_site == call_site) {
+ data->hit++;
+ data->bytes_req += bytes_req;
+ data->bytes_alloc += bytes_req;
+ } else {
+ data = malloc(sizeof(*data));
+ if (!data)
+ die("malloc");
+ data->call_site = call_site;
+ data->pingpong = 0;
+ data->hit = 1;
+ data->bytes_req = bytes_req;
+ data->bytes_alloc = bytes_alloc;
+
+ rb_link_node(&data->node, parent, node);
+ rb_insert_color(&data->node, &root_caller_stat);
+ }
+}
+
+static void process_alloc_event(struct raw_event_sample *raw,
+ struct event *event,
+ int cpu,
+ u64 timestamp __used,
+ struct thread *thread __used,
+ int node)
+{
+ unsigned long call_site;
+ unsigned long ptr;
+ int bytes_req;
+ int bytes_alloc;
+ int node1, node2;
+
+ ptr = raw_field_value(event, "ptr", raw->data);
+ call_site = raw_field_value(event, "call_site", raw->data);
+ bytes_req = raw_field_value(event, "bytes_req", raw->data);
+ bytes_alloc = raw_field_value(event, "bytes_alloc", raw->data);
+
+ insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, cpu);
+ insert_caller_stat(call_site, bytes_req, bytes_alloc);
+
+ total_requested += bytes_req;
+ total_allocated += bytes_alloc;
+
+ if (node) {
+ node1 = cpunode_map[cpu];
+ node2 = raw_field_value(event, "node", raw->data);
+ if (node1 != node2)
+ nr_cross_allocs++;
+ }
+ nr_allocs++;
+}
+
+static int ptr_cmp(struct alloc_stat *, struct alloc_stat *);
+static int callsite_cmp(struct alloc_stat *, struct alloc_stat *);
+
+static struct alloc_stat *search_alloc_stat(unsigned long ptr,
+ unsigned long call_site,
+ struct rb_root *root,
+ sort_fn_t sort_fn)
+{
+ struct rb_node *node = root->rb_node;
+ struct alloc_stat key = { .ptr = ptr, .call_site = call_site };
+
+ while (node) {
+ struct alloc_stat *data;
+ int cmp;
+
+ data = rb_entry(node, struct alloc_stat, node);
+
+ cmp = sort_fn(&key, data);
+ if (cmp < 0)
+ node = node->rb_left;
+ else if (cmp > 0)
+ node = node->rb_right;
+ else
+ return data;
+ }
+ return NULL;
+}
+
+static void process_free_event(struct raw_event_sample *raw,
+ struct event *event,
+ int cpu,
+ u64 timestamp __used,
+ struct thread *thread __used)
+{
+ unsigned long ptr;
+ struct alloc_stat *s_alloc, *s_caller;
+
+ ptr = raw_field_value(event, "ptr", raw->data);
+
+ s_alloc = search_alloc_stat(ptr, 0, &root_alloc_stat, ptr_cmp);
+ if (!s_alloc)
+ return;
+
+ if (cpu != s_alloc->alloc_cpu) {
+ s_alloc->pingpong++;
+
+ s_caller = search_alloc_stat(0, s_alloc->call_site,
+ &root_caller_stat, callsite_cmp);
+ assert(s_caller);
+ s_caller->pingpong++;
+ }
+ s_alloc->alloc_cpu = -1;
+}
+
+static void
+process_raw_event(event_t *raw_event __used, void *more_data,
+ int cpu, u64 timestamp, struct thread *thread)
+{
+ struct raw_event_sample *raw = more_data;
+ struct event *event;
+ int type;
+
+ type = trace_parse_common_type(raw->data);
+ event = trace_find_event(type);
+
+ if (!strcmp(event->name, "kmalloc") ||
+ !strcmp(event->name, "kmem_cache_alloc")) {
+ process_alloc_event(raw, event, cpu, timestamp, thread, 0);
+ return;
+ }
+
+ if (!strcmp(event->name, "kmalloc_node") ||
+ !strcmp(event->name, "kmem_cache_alloc_node")) {
+ process_alloc_event(raw, event, cpu, timestamp, thread, 1);
+ return;
+ }
+
+ if (!strcmp(event->name, "kfree") ||
+ !strcmp(event->name, "kmem_cache_free")) {
+ process_free_event(raw, event, cpu, timestamp, thread);
+ return;
+ }
+}
+
+static int process_sample_event(event_t *event)
+{
+ u64 ip = event->ip.ip;
+ u64 timestamp = -1;
+ u32 cpu = -1;
+ u64 period = 1;
+ void *more_data = event->ip.__more_data;
+ struct thread *thread = threads__findnew(event->ip.pid);
+
+ if (sample_type & PERF_SAMPLE_TIME) {
+ timestamp = *(u64 *)more_data;
+ more_data += sizeof(u64);
+ }
+
+ if (sample_type & PERF_SAMPLE_CPU) {
+ cpu = *(u32 *)more_data;
+ more_data += sizeof(u32);
+ more_data += sizeof(u32); /* reserved */
+ }
+
+ if (sample_type & PERF_SAMPLE_PERIOD) {
+ period = *(u64 *)more_data;
+ more_data += sizeof(u64);
+ }
+
+ dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
+ event->header.misc,
+ event->ip.pid, event->ip.tid,
+ (void *)(long)ip,
+ (long long)period);
+
+ if (thread == NULL) {
+ pr_debug("problem processing %d event, skipping it.\n",
+ event->header.type);
+ return -1;
+ }
+
+ dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
+
+ process_raw_event(event, more_data, cpu, timestamp, thread);
+
+ return 0;
+}
+
+static int sample_type_check(u64 type)
+{
+ sample_type = type;
+
+ if (!(sample_type & PERF_SAMPLE_RAW)) {
+ fprintf(stderr,
+ "No trace sample to read. Did you call perf record "
+ "without -R?");
+ return -1;
+ }
+
+ return 0;
+}
+
+static struct perf_file_handler file_handler = {
+ .process_sample_event = process_sample_event,
+ .process_comm_event = event__process_comm,
+ .sample_type_check = sample_type_check,
+};
+
+static int read_events(void)
+{
+ register_idle_thread();
+ register_perf_file_handler(&file_handler);
+
+ return mmap_dispatch_perf_file(&header, input_name, 0, 0,
+ &event__cwdlen, &event__cwd);
+}
+
+static double fragmentation(unsigned long n_req, unsigned long n_alloc)
+{
+ if (n_alloc == 0)
+ return 0.0;
+ else
+ return 100.0 - (100.0 * n_req / n_alloc);
+}
+
+static void __print_result(struct rb_root *root, int n_lines, int is_caller)
+{
+ struct rb_node *next;
+
+ printf("%.102s\n", graph_dotted_line);
+ printf(" %-34s |", is_caller ? "Callsite": "Alloc Ptr");
+ printf(" Total_alloc/Per | Total_req/Per | Hit | Ping-pong | Frag\n");
+ printf("%.102s\n", graph_dotted_line);
+
+ next = rb_first(root);
+
+ while (next && n_lines--) {
+ struct alloc_stat *data = rb_entry(next, struct alloc_stat,
+ node);
+ struct symbol *sym = NULL;
+ char buf[BUFSIZ];
+ u64 addr;
+
+ if (is_caller) {
+ addr = data->call_site;
+ if (!raw_ip)
+ sym = thread__find_function(kthread, addr, NULL);
+ } else
+ addr = data->ptr;
+
+ if (sym != NULL)
+ snprintf(buf, sizeof(buf), "%s+%Lx", sym->name,
+ addr - sym->start);
+ else
+ snprintf(buf, sizeof(buf), "%#Lx", addr);
+ printf(" %-34s |", buf);
+
+ printf(" %9llu/%-5lu | %9llu/%-5lu | %6lu | %8lu | %6.3f%%\n",
+ (unsigned long long)data->bytes_alloc,
+ (unsigned long)data->bytes_alloc / data->hit,
+ (unsigned long long)data->bytes_req,
+ (unsigned long)data->bytes_req / data->hit,
+ (unsigned long)data->hit,
+ (unsigned long)data->pingpong,
+ fragmentation(data->bytes_req, data->bytes_alloc));
+
+ next = rb_next(next);
+ }
+
+ if (n_lines == -1)
+ printf(" ... | ... | ... | ... | ... | ... \n");
+
+ printf("%.102s\n", graph_dotted_line);
+}
+
+static void print_summary(void)
+{
+ printf("\nSUMMARY\n=======\n");
+ printf("Total bytes requested: %lu\n", total_requested);
+ printf("Total bytes allocated: %lu\n", total_allocated);
+ printf("Total bytes wasted on internal fragmentation: %lu\n",
+ total_allocated - total_requested);
+ printf("Internal fragmentation: %f%%\n",
+ fragmentation(total_requested, total_allocated));
+ printf("Cross CPU allocations: %lu/%lu\n", nr_cross_allocs, nr_allocs);
+}
+
+static void print_result(void)
+{
+ if (caller_flag)
+ __print_result(&root_caller_sorted, caller_lines, 1);
+ if (alloc_flag)
+ __print_result(&root_alloc_sorted, alloc_lines, 0);
+ print_summary();
+}
+
+struct sort_dimension {
+ const char name[20];
+ sort_fn_t cmp;
+ struct list_head list;
+};
+
+static LIST_HEAD(caller_sort);
+static LIST_HEAD(alloc_sort);
+
+static void sort_insert(struct rb_root *root, struct alloc_stat *data,
+ struct list_head *sort_list)
+{
+ struct rb_node **new = &(root->rb_node);
+ struct rb_node *parent = NULL;
+ struct sort_dimension *sort;
+
+ while (*new) {
+ struct alloc_stat *this;
+ int cmp = 0;
+
+ this = rb_entry(*new, struct alloc_stat, node);
+ parent = *new;
+
+ list_for_each_entry(sort, sort_list, list) {
+ cmp = sort->cmp(data, this);
+ if (cmp)
+ break;
+ }
+
+ if (cmp > 0)
+ new = &((*new)->rb_left);
+ else
+ new = &((*new)->rb_right);
+ }
+
+ rb_link_node(&data->node, parent, new);
+ rb_insert_color(&data->node, root);
+}
+
+static void __sort_result(struct rb_root *root, struct rb_root *root_sorted,
+ struct list_head *sort_list)
+{
+ struct rb_node *node;
+ struct alloc_stat *data;
+
+ for (;;) {
+ node = rb_first(root);
+ if (!node)
+ break;
+
+ rb_erase(node, root);
+ data = rb_entry(node, struct alloc_stat, node);
+ sort_insert(root_sorted, data, sort_list);
+ }
+}
+
+static void sort_result(void)
+{
+ __sort_result(&root_alloc_stat, &root_alloc_sorted, &alloc_sort);
+ __sort_result(&root_caller_stat, &root_caller_sorted, &caller_sort);
+}
+
+static int __cmd_kmem(void)
+{
+ setup_pager();
+ read_events();
+ sort_result();
+ print_result();
+
+ return 0;
+}
+
+static const char * const kmem_usage[] = {
+ "perf kmem [<options>] {record}",
+ NULL
+};
+
+static int ptr_cmp(struct alloc_stat *l, struct alloc_stat *r)
+{
+ if (l->ptr < r->ptr)
+ return -1;
+ else if (l->ptr > r->ptr)
+ return 1;
+ return 0;
+}
+
+static struct sort_dimension ptr_sort_dimension = {
+ .name = "ptr",
+ .cmp = ptr_cmp,
+};
+
+static int callsite_cmp(struct alloc_stat *l, struct alloc_stat *r)
+{
+ if (l->call_site < r->call_site)
+ return -1;
+ else if (l->call_site > r->call_site)
+ return 1;
+ return 0;
+}
+
+static struct sort_dimension callsite_sort_dimension = {
+ .name = "callsite",
+ .cmp = callsite_cmp,
+};
+
+static int hit_cmp(struct alloc_stat *l, struct alloc_stat *r)
+{
+ if (l->hit < r->hit)
+ return -1;
+ else if (l->hit > r->hit)
+ return 1;
+ return 0;
+}
+
+static struct sort_dimension hit_sort_dimension = {
+ .name = "hit",
+ .cmp = hit_cmp,
+};
+
+static int bytes_cmp(struct alloc_stat *l, struct alloc_stat *r)
+{
+ if (l->bytes_alloc < r->bytes_alloc)
+ return -1;
+ else if (l->bytes_alloc > r->bytes_alloc)
+ return 1;
+ return 0;
+}
+
+static struct sort_dimension bytes_sort_dimension = {
+ .name = "bytes",
+ .cmp = bytes_cmp,
+};
+
+static int frag_cmp(struct alloc_stat *l, struct alloc_stat *r)
+{
+ double x, y;
+
+ x = fragmentation(l->bytes_req, l->bytes_alloc);
+ y = fragmentation(r->bytes_req, r->bytes_alloc);
+
+ if (x < y)
+ return -1;
+ else if (x > y)
+ return 1;
+ return 0;
+}
+
+static struct sort_dimension frag_sort_dimension = {
+ .name = "frag",
+ .cmp = frag_cmp,
+};
+
+static int pingpong_cmp(struct alloc_stat *l, struct alloc_stat *r)
+{
+ if (l->pingpong < r->pingpong)
+ return -1;
+ else if (l->pingpong > r->pingpong)
+ return 1;
+ return 0;
+}
+
+static struct sort_dimension pingpong_sort_dimension = {
+ .name = "pingpong",
+ .cmp = pingpong_cmp,
+};
+
+static struct sort_dimension *avail_sorts[] = {
+ &ptr_sort_dimension,
+ &callsite_sort_dimension,
+ &hit_sort_dimension,
+ &bytes_sort_dimension,
+ &frag_sort_dimension,
+ &pingpong_sort_dimension,
+};
+
+#define NUM_AVAIL_SORTS \
+ (int)(sizeof(avail_sorts) / sizeof(struct sort_dimension *))
+
+static int sort_dimension__add(const char *tok, struct list_head *list)
+{
+ struct sort_dimension *sort;
+ int i;
+
+ for (i = 0; i < NUM_AVAIL_SORTS; i++) {
+ if (!strcmp(avail_sorts[i]->name, tok)) {
+ sort = malloc(sizeof(*sort));
+ if (!sort)
+ die("malloc");
+ memcpy(sort, avail_sorts[i], sizeof(*sort));
+ list_add_tail(&sort->list, list);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static int setup_sorting(struct list_head *sort_list, const char *arg)
+{
+ char *tok;
+ char *str = strdup(arg);
+
+ if (!str)
+ die("strdup");
+
+ while (true) {
+ tok = strsep(&str, ",");
+ if (!tok)
+ break;
+ if (sort_dimension__add(tok, sort_list) < 0) {
+ error("Unknown --sort key: '%s'", tok);
+ return -1;
+ }
+ }
+
+ free(str);
+ return 0;
+}
+
+static int parse_sort_opt(const struct option *opt __used,
+ const char *arg, int unset __used)
+{
+ if (!arg)
+ return -1;
+
+ if (caller_flag > alloc_flag)
+ return setup_sorting(&caller_sort, arg);
+ else
+ return setup_sorting(&alloc_sort, arg);
+
+ return 0;
+}
+
+static int parse_stat_opt(const struct option *opt __used,
+ const char *arg, int unset __used)
+{
+ if (!arg)
+ return -1;
+
+ if (strcmp(arg, "alloc") == 0)
+ alloc_flag = (caller_flag + 1);
+ else if (strcmp(arg, "caller") == 0)
+ caller_flag = (alloc_flag + 1);
+ else
+ return -1;
+ return 0;
+}
+
+static int parse_line_opt(const struct option *opt __used,
+ const char *arg, int unset __used)
+{
+ int lines;
+
+ if (!arg)
+ return -1;
+
+ lines = strtoul(arg, NULL, 10);
+
+ if (caller_flag > alloc_flag)
+ caller_lines = lines;
+ else
+ alloc_lines = lines;
+
+ return 0;
+}
+
+static const struct option kmem_options[] = {
+ OPT_STRING('i', "input", &input_name, "file",
+ "input file name"),
+ OPT_CALLBACK(0, "stat", NULL, "<alloc>|<caller>",
+ "stat selector, Pass 'alloc' or 'caller'.",
+ parse_stat_opt),
+ OPT_CALLBACK('s', "sort", NULL, "key[,key2...]",
+ "sort by keys: ptr, call_site, bytes, hit, pingpong, frag",
+ parse_sort_opt),
+ OPT_CALLBACK('l', "line", NULL, "num",
+ "show n lins",
+ parse_line_opt),
+ OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"),
+ OPT_END()
+};
+
+static const char *record_args[] = {
+ "record",
+ "-a",
+ "-R",
+ "-M",
+ "-f",
+ "-c", "1",
+ "-e", "kmem:kmalloc",
+ "-e", "kmem:kmalloc_node",
+ "-e", "kmem:kfree",
+ "-e", "kmem:kmem_cache_alloc",
+ "-e", "kmem:kmem_cache_alloc_node",
+ "-e", "kmem:kmem_cache_free",
+};
+
+static int __cmd_record(int argc, const char **argv)
+{
+ unsigned int rec_argc, i, j;
+ const char **rec_argv;
+
+ rec_argc = ARRAY_SIZE(record_args) + argc - 1;
+ rec_argv = calloc(rec_argc + 1, sizeof(char *));
+
+ for (i = 0; i < ARRAY_SIZE(record_args); i++)
+ rec_argv[i] = strdup(record_args[i]);
+
+ for (j = 1; j < (unsigned int)argc; j++, i++)
+ rec_argv[i] = argv[j];
+
+ return cmd_record(i, rec_argv, NULL);
+}
+
+int cmd_kmem(int argc, const char **argv, const char *prefix __used)
+{
+ symbol__init(0);
+
+ argc = parse_options(argc, argv, kmem_options, kmem_usage, 0);
+
+ if (argc && !strncmp(argv[0], "rec", 3))
+ return __cmd_record(argc, argv);
+ else if (argc)
+ usage_with_options(kmem_usage, kmem_options);
+
+ if (list_empty(&caller_sort))
+ setup_sorting(&caller_sort, default_sort_order);
+ if (list_empty(&alloc_sort))
+ setup_sorting(&alloc_sort, default_sort_order);
+
+ setup_cpunode_map();
+
+ return __cmd_kmem();
+}
+
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
new file mode 100644
index 000000000000..a58e11b7ea80
--- /dev/null
+++ b/tools/perf/builtin-probe.c
@@ -0,0 +1,242 @@
+/*
+ * builtin-probe.c
+ *
+ * Builtin probe command: Set up probe events by C expression
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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.
+ *
+ */
+#define _GNU_SOURCE
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#undef _GNU_SOURCE
+#include "perf.h"
+#include "builtin.h"
+#include "util/util.h"
+#include "util/event.h"
+#include "util/debug.h"
+#include "util/parse-options.h"
+#include "util/parse-events.h" /* For debugfs_path */
+#include "util/probe-finder.h"
+#include "util/probe-event.h"
+
+/* Default vmlinux search paths */
+#define NR_SEARCH_PATH 3
+const char *default_search_path[NR_SEARCH_PATH] = {
+"/lib/modules/%s/build/vmlinux", /* Custom build kernel */
+"/usr/lib/debug/lib/modules/%s/vmlinux", /* Red Hat debuginfo */
+"/boot/vmlinux-debug-%s", /* Ubuntu */
+};
+
+#define MAX_PATH_LEN 256
+#define MAX_PROBES 128
+
+/* Session management structure */
+static struct {
+ char *vmlinux;
+ char *release;
+ int need_dwarf;
+ int nr_probe;
+ struct probe_point probes[MAX_PROBES];
+} session;
+
+static bool listing;
+
+/* Parse an event definition. Note that any error must die. */
+static void parse_probe_event(const char *str)
+{
+ struct probe_point *pp = &session.probes[session.nr_probe];
+
+ pr_debug("probe-definition(%d): %s\n", session.nr_probe, str);
+ if (++session.nr_probe == MAX_PROBES)
+ die("Too many probes (> %d) are specified.", MAX_PROBES);
+
+ /* Parse perf-probe event into probe_point */
+ session.need_dwarf = parse_perf_probe_event(str, pp);
+
+ pr_debug("%d arguments\n", pp->nr_args);
+}
+
+static int opt_add_probe_event(const struct option *opt __used,
+ const char *str, int unset __used)
+{
+ if (str)
+ parse_probe_event(str);
+ return 0;
+}
+
+#ifndef NO_LIBDWARF
+static int open_default_vmlinux(void)
+{
+ struct utsname uts;
+ char fname[MAX_PATH_LEN];
+ int fd, ret, i;
+
+ ret = uname(&uts);
+ if (ret) {
+ pr_debug("uname() failed.\n");
+ return -errno;
+ }
+ session.release = uts.release;
+ for (i = 0; i < NR_SEARCH_PATH; i++) {
+ ret = snprintf(fname, MAX_PATH_LEN,
+ default_search_path[i], session.release);
+ if (ret >= MAX_PATH_LEN || ret < 0) {
+ pr_debug("Filename(%d,%s) is too long.\n", i,
+ uts.release);
+ errno = E2BIG;
+ return -E2BIG;
+ }
+ pr_debug("try to open %s\n", fname);
+ fd = open(fname, O_RDONLY);
+ if (fd >= 0)
+ break;
+ }
+ return fd;
+}
+#endif
+
+static const char * const probe_usage[] = {
+ "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
+ "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
+ "perf probe --list",
+ NULL
+};
+
+static const struct option options[] = {
+ OPT_BOOLEAN('v', "verbose", &verbose,
+ "be more verbose (show parsed arguments, etc)"),
+#ifndef NO_LIBDWARF
+ OPT_STRING('k', "vmlinux", &session.vmlinux, "file",
+ "vmlinux/module pathname"),
+#endif
+ OPT_BOOLEAN('l', "list", &listing, "list up current probes"),
+ OPT_CALLBACK('a', "add", NULL,
+#ifdef NO_LIBDWARF
+ "FUNC[+OFFS|%return] [ARG ...]",
+#else
+ "FUNC[+OFFS|%return|:RLN][@SRC]|SRC:ALN [ARG ...]",
+#endif
+ "probe point definition, where\n"
+ "\t\tGRP:\tGroup name (optional)\n"
+ "\t\tNAME:\tEvent name\n"
+ "\t\tFUNC:\tFunction name\n"
+ "\t\tOFFS:\tOffset from function entry (in byte)\n"
+ "\t\t%return:\tPut the probe at function return\n"
+#ifdef NO_LIBDWARF
+ "\t\tARG:\tProbe argument (only \n"
+#else
+ "\t\tSRC:\tSource code path\n"
+ "\t\tRLN:\tRelative line number from function entry.\n"
+ "\t\tALN:\tAbsolute line number in file.\n"
+ "\t\tARG:\tProbe argument (local variable name or\n"
+#endif
+ "\t\t\tkprobe-tracer argument format.)\n",
+ opt_add_probe_event),
+ OPT_END()
+};
+
+int cmd_probe(int argc, const char **argv, const char *prefix __used)
+{
+ int i, j, ret;
+#ifndef NO_LIBDWARF
+ int fd;
+#endif
+ struct probe_point *pp;
+
+ argc = parse_options(argc, argv, options, probe_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+ for (i = 0; i < argc; i++)
+ parse_probe_event(argv[i]);
+
+ if ((session.nr_probe == 0 && !listing) ||
+ (session.nr_probe != 0 && listing))
+ usage_with_options(probe_usage, options);
+
+ if (listing) {
+ show_perf_probe_events();
+ return 0;
+ }
+
+ if (session.need_dwarf)
+#ifdef NO_LIBDWARF
+ die("Debuginfo-analysis is not supported");
+#else /* !NO_LIBDWARF */
+ pr_debug("Some probes require debuginfo.\n");
+
+ if (session.vmlinux)
+ fd = open(session.vmlinux, O_RDONLY);
+ else
+ fd = open_default_vmlinux();
+ if (fd < 0) {
+ if (session.need_dwarf)
+ die("Could not open vmlinux/module file.");
+
+ pr_warning("Could not open vmlinux/module file."
+ " Try to use symbols.\n");
+ goto end_dwarf;
+ }
+
+ /* Searching probe points */
+ for (j = 0; j < session.nr_probe; j++) {
+ pp = &session.probes[j];
+ if (pp->found)
+ continue;
+
+ lseek(fd, SEEK_SET, 0);
+ ret = find_probepoint(fd, pp);
+ if (ret < 0) {
+ if (session.need_dwarf)
+ die("Could not analyze debuginfo.");
+
+ pr_warning("An error occurred in debuginfo analysis. Try to use symbols.\n");
+ break;
+ }
+ if (ret == 0) /* No error but failed to find probe point. */
+ die("No probe point found.");
+ }
+ close(fd);
+
+end_dwarf:
+#endif /* !NO_LIBDWARF */
+
+ /* Synthesize probes without dwarf */
+ for (j = 0; j < session.nr_probe; j++) {
+ pp = &session.probes[j];
+ if (pp->found) /* This probe is already found. */
+ continue;
+
+ ret = synthesize_trace_kprobe_event(pp);
+ if (ret == -E2BIG)
+ die("probe point definition becomes too long.");
+ else if (ret < 0)
+ die("Failed to synthesize a probe point.");
+ }
+
+ /* Settng up probe points */
+ add_trace_kprobe_events(session.probes, session.nr_probe);
+ return 0;
+}
+
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 3eeef339c787..0e519c667e3a 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -17,55 +17,52 @@
#include "util/header.h"
#include "util/event.h"
#include "util/debug.h"
-#include "util/trace-event.h"
+#include "util/symbol.h"
#include <unistd.h>
#include <sched.h>
-#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
-#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
-
static int fd[MAX_NR_CPUS][MAX_COUNTERS];
-static long default_interval = 100000;
+static long default_interval = 0;
-static int nr_cpus = 0;
+static int nr_cpus = 0;
static unsigned int page_size;
-static unsigned int mmap_pages = 128;
-static int freq = 0;
+static unsigned int mmap_pages = 128;
+static int freq = 1000;
static int output;
static const char *output_name = "perf.data";
-static int group = 0;
-static unsigned int realtime_prio = 0;
-static int raw_samples = 0;
-static int system_wide = 0;
-static int profile_cpu = -1;
-static pid_t target_pid = -1;
-static pid_t child_pid = -1;
-static int inherit = 1;
-static int force = 0;
-static int append_file = 0;
-static int call_graph = 0;
-static int inherit_stat = 0;
-static int no_samples = 0;
-static int sample_address = 0;
-static int multiplex = 0;
-static int multiplex_fd = -1;
-
-static long samples;
+static int group = 0;
+static unsigned int realtime_prio = 0;
+static int raw_samples = 0;
+static int system_wide = 0;
+static int profile_cpu = -1;
+static pid_t target_pid = -1;
+static pid_t child_pid = -1;
+static int inherit = 1;
+static int force = 0;
+static int append_file = 0;
+static int call_graph = 0;
+static int inherit_stat = 0;
+static int no_samples = 0;
+static int sample_address = 0;
+static int multiplex = 0;
+static int multiplex_fd = -1;
+
+static long samples = 0;
static struct timeval last_read;
static struct timeval this_read;
-static u64 bytes_written;
+static u64 bytes_written = 0;
static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
-static int nr_poll;
-static int nr_cpu;
+static int nr_poll = 0;
+static int nr_cpu = 0;
-static int file_new = 1;
+static int file_new = 1;
-struct perf_header *header;
+struct perf_header *header = NULL;
struct mmap_data {
int counter;
@@ -113,6 +110,24 @@ static void write_output(void *buf, size_t size)
}
}
+static void write_event(event_t *buf, size_t size)
+{
+ /*
+ * Add it to the list of DSOs, so that when we finish this
+ * record session we can pick the available build-ids.
+ */
+ if (buf->header.type == PERF_RECORD_MMAP)
+ dsos__findnew(buf->mmap.filename);
+
+ write_output(buf, size);
+}
+
+static int process_synthesized_event(event_t *event)
+{
+ write_event(event, event->header.size);
+ return 0;
+}
+
static void mmap_read(struct mmap_data *md)
{
unsigned int head = mmap_read_head(md);
@@ -161,14 +176,14 @@ static void mmap_read(struct mmap_data *md)
size = md->mask + 1 - (old & md->mask);
old += size;
- write_output(buf, size);
+ write_event(buf, size);
}
buf = &data[old & md->mask];
size = head - old;
old += size;
- write_output(buf, size);
+ write_event(buf, size);
md->prev = old;
mmap_write_tail(md, old);
@@ -195,168 +210,6 @@ static void sig_atexit(void)
kill(getpid(), signr);
}
-static pid_t pid_synthesize_comm_event(pid_t pid, int full)
-{
- struct comm_event comm_ev;
- char filename[PATH_MAX];
- char bf[BUFSIZ];
- FILE *fp;
- size_t size = 0;
- DIR *tasks;
- struct dirent dirent, *next;
- pid_t tgid = 0;
-
- snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- /*
- * We raced with a task exiting - just return:
- */
- if (verbose)
- fprintf(stderr, "couldn't open %s\n", filename);
- return 0;
- }
-
- memset(&comm_ev, 0, sizeof(comm_ev));
- while (!comm_ev.comm[0] || !comm_ev.pid) {
- if (fgets(bf, sizeof(bf), fp) == NULL)
- goto out_failure;
-
- if (memcmp(bf, "Name:", 5) == 0) {
- char *name = bf + 5;
- while (*name && isspace(*name))
- ++name;
- size = strlen(name) - 1;
- memcpy(comm_ev.comm, name, size++);
- } else if (memcmp(bf, "Tgid:", 5) == 0) {
- char *tgids = bf + 5;
- while (*tgids && isspace(*tgids))
- ++tgids;
- tgid = comm_ev.pid = atoi(tgids);
- }
- }
-
- comm_ev.header.type = PERF_RECORD_COMM;
- size = ALIGN(size, sizeof(u64));
- comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size);
-
- if (!full) {
- comm_ev.tid = pid;
-
- write_output(&comm_ev, comm_ev.header.size);
- goto out_fclose;
- }
-
- snprintf(filename, sizeof(filename), "/proc/%d/task", pid);
-
- tasks = opendir(filename);
- while (!readdir_r(tasks, &dirent, &next) && next) {
- char *end;
- pid = strtol(dirent.d_name, &end, 10);
- if (*end)
- continue;
-
- comm_ev.tid = pid;
-
- write_output(&comm_ev, comm_ev.header.size);
- }
- closedir(tasks);
-
-out_fclose:
- fclose(fp);
- return tgid;
-
-out_failure:
- fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n",
- filename);
- exit(EXIT_FAILURE);
-}
-
-static void pid_synthesize_mmap_samples(pid_t pid, pid_t tgid)
-{
- char filename[PATH_MAX];
- FILE *fp;
-
- snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- /*
- * We raced with a task exiting - just return:
- */
- if (verbose)
- fprintf(stderr, "couldn't open %s\n", filename);
- return;
- }
- while (1) {
- char bf[BUFSIZ], *pbf = bf;
- struct mmap_event mmap_ev = {
- .header = { .type = PERF_RECORD_MMAP },
- };
- int n;
- size_t size;
- if (fgets(bf, sizeof(bf), fp) == NULL)
- break;
-
- /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */
- n = hex2u64(pbf, &mmap_ev.start);
- if (n < 0)
- continue;
- pbf += n + 1;
- n = hex2u64(pbf, &mmap_ev.len);
- if (n < 0)
- continue;
- pbf += n + 3;
- if (*pbf == 'x') { /* vm_exec */
- char *execname = strchr(bf, '/');
-
- /* Catch VDSO */
- if (execname == NULL)
- execname = strstr(bf, "[vdso]");
-
- if (execname == NULL)
- continue;
-
- size = strlen(execname);
- execname[size - 1] = '\0'; /* Remove \n */
- memcpy(mmap_ev.filename, execname, size);
- size = ALIGN(size, sizeof(u64));
- mmap_ev.len -= mmap_ev.start;
- mmap_ev.header.size = (sizeof(mmap_ev) -
- (sizeof(mmap_ev.filename) - size));
- mmap_ev.pid = tgid;
- mmap_ev.tid = pid;
-
- write_output(&mmap_ev, mmap_ev.header.size);
- }
- }
-
- fclose(fp);
-}
-
-static void synthesize_all(void)
-{
- DIR *proc;
- struct dirent dirent, *next;
-
- proc = opendir("/proc");
-
- while (!readdir_r(proc, &dirent, &next) && next) {
- char *end;
- pid_t pid, tgid;
-
- pid = strtol(dirent.d_name, &end, 10);
- if (*end) /* only interested in proper numerical dirents */
- continue;
-
- tgid = pid_synthesize_comm_event(pid, 1);
- pid_synthesize_mmap_samples(pid, tgid);
- }
-
- closedir(proc);
-}
-
static int group_fd;
static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr)
@@ -367,7 +220,11 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n
h_attr = header->attr[nr];
} else {
h_attr = perf_header_attr__new(a);
- perf_header__add_attr(header, h_attr);
+ if (h_attr != NULL)
+ if (perf_header__add_attr(header, h_attr) < 0) {
+ perf_header_attr__delete(h_attr);
+ h_attr = NULL;
+ }
}
return h_attr;
@@ -375,9 +232,11 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n
static void create_counter(int counter, int cpu, pid_t pid)
{
+ char *filter = filters[counter];
struct perf_event_attr *attr = attrs + counter;
struct perf_header_attr *h_attr;
int track = !counter; /* only the first counter needs these */
+ int ret;
struct {
u64 count;
u64 time_enabled;
@@ -426,7 +285,7 @@ try_again:
if (fd[nr_cpu][counter] < 0) {
int err = errno;
- if (err == EPERM)
+ if (err == EPERM || err == EACCES)
die("Permission error - are you root?\n");
else if (err == ENODEV && profile_cpu != -1)
die("No such device - did you specify an out-of-range profile CPU?\n");
@@ -448,11 +307,19 @@ try_again:
printf("\n");
error("perfcounter syscall returned with %d (%s)\n",
fd[nr_cpu][counter], strerror(err));
+
+#if defined(__i386__) || defined(__x86_64__)
+ if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
+ die("No hardware sampling interrupt available. No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.\n");
+#endif
+
die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
exit(-1);
}
h_attr = get_header_attr(attr, counter);
+ if (h_attr == NULL)
+ die("nomem\n");
if (!file_new) {
if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
@@ -466,7 +333,10 @@ try_again:
exit(-1);
}
- perf_header_attr__add_id(h_attr, read_data.id);
+ if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
+ pr_warning("Not enough memory to add id\n");
+ exit(-1);
+ }
assert(fd[nr_cpu][counter] >= 0);
fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK);
@@ -480,7 +350,6 @@ try_again:
multiplex_fd = fd[nr_cpu][counter];
if (multiplex && fd[nr_cpu][counter] != multiplex_fd) {
- int ret;
ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
assert(ret != -1);
@@ -500,6 +369,16 @@ try_again:
}
}
+ if (filter != NULL) {
+ ret = ioctl(fd[nr_cpu][counter],
+ PERF_EVENT_IOC_SET_FILTER, filter);
+ if (ret) {
+ error("failed to set filter with %d (%s)\n", errno,
+ strerror(errno));
+ exit(-1);
+ }
+ }
+
ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE);
}
@@ -518,7 +397,7 @@ static void atexit_header(void)
{
header->data_size += bytes_written;
- perf_header__write(header, output);
+ perf_header__write(header, output, true);
}
static int __cmd_record(int argc, const char **argv)
@@ -527,7 +406,7 @@ static int __cmd_record(int argc, const char **argv)
struct stat st;
pid_t pid = 0;
int flags;
- int ret;
+ int err;
unsigned long waking = 0;
page_size = sysconf(_SC_PAGE_SIZE);
@@ -561,22 +440,29 @@ static int __cmd_record(int argc, const char **argv)
exit(-1);
}
- if (!file_new)
- header = perf_header__read(output);
- else
- header = perf_header__new();
+ header = perf_header__new();
+ if (header == NULL) {
+ pr_err("Not enough memory for reading perf file header\n");
+ return -1;
+ }
+ if (!file_new) {
+ err = perf_header__read(header, output);
+ if (err < 0)
+ return err;
+ }
if (raw_samples) {
- read_tracing_data(attrs, nr_counters);
+ perf_header__set_feat(header, HEADER_TRACE_INFO);
} else {
for (i = 0; i < nr_counters; i++) {
if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
- read_tracing_data(attrs, nr_counters);
+ perf_header__set_feat(header, HEADER_TRACE_INFO);
break;
}
}
}
+
atexit(atexit_header);
if (!system_wide) {
@@ -594,25 +480,36 @@ static int __cmd_record(int argc, const char **argv)
}
}
- if (file_new)
- perf_header__write(header, output);
+ if (file_new) {
+ err = perf_header__write(header, output, false);
+ if (err < 0)
+ return err;
+ }
- if (!system_wide) {
- pid_t tgid = pid_synthesize_comm_event(pid, 0);
- pid_synthesize_mmap_samples(pid, tgid);
- } else
- synthesize_all();
+ if (!system_wide)
+ event__synthesize_thread(pid, process_synthesized_event);
+ else
+ event__synthesize_threads(process_synthesized_event);
if (target_pid == -1 && argc) {
pid = fork();
if (pid < 0)
- perror("failed to fork");
+ die("failed to fork");
if (!pid) {
if (execvp(argv[0], (char **)argv)) {
perror(argv[0]);
exit(-1);
}
+ } else {
+ /*
+ * Wait a bit for the execv'ed child to appear
+ * and be updated in /proc
+ * FIXME: Do you know a less heuristical solution?
+ */
+ usleep(1000);
+ event__synthesize_thread(pid,
+ process_synthesized_event);
}
child_pid = pid;
@@ -623,7 +520,7 @@ static int __cmd_record(int argc, const char **argv)
param.sched_priority = realtime_prio;
if (sched_setscheduler(0, SCHED_FIFO, &param)) {
- printf("Could not set realtime priority.\n");
+ pr_err("Could not set realtime priority.\n");
exit(-1);
}
}
@@ -641,7 +538,7 @@ static int __cmd_record(int argc, const char **argv)
if (hits == samples) {
if (done)
break;
- ret = poll(event_array, nr_poll, -1);
+ err = poll(event_array, nr_poll, -1);
waking++;
}
@@ -677,6 +574,8 @@ static const struct option options[] = {
OPT_CALLBACK('e', "event", NULL, "event",
"event selector. use 'perf list' to list available events",
parse_events),
+ OPT_CALLBACK(0, "filter", NULL, "filter",
+ "event filter", parse_filter),
OPT_INTEGER('p', "pid", &target_pid,
"record events on existing pid"),
OPT_INTEGER('r', "realtime", &realtime_prio,
@@ -720,6 +619,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
{
int counter;
+ symbol__init(0);
+
argc = parse_options(argc, argv, options, record_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
if (!argc && target_pid == -1 && !system_wide)
@@ -731,6 +632,18 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
attrs[0].config = PERF_COUNT_HW_CPU_CYCLES;
}
+ /*
+ * User specified count overrides default frequency.
+ */
+ if (default_interval)
+ freq = 0;
+ else if (freq) {
+ default_interval = freq;
+ } else {
+ fprintf(stderr, "frequency and count are zero, aborting\n");
+ exit(EXIT_FAILURE);
+ }
+
for (counter = 0; counter < nr_counters; counter++) {
if (attrs[counter].sample_period)
continue;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 19669c20088e..383c4ab4f9af 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -26,20 +26,18 @@
#include "util/parse-options.h"
#include "util/parse-events.h"
+#include "util/data_map.h"
#include "util/thread.h"
+#include "util/sort.h"
+#include "util/hist.h"
static char const *input_name = "perf.data";
-static char default_sort_order[] = "comm,dso,symbol";
-static char *sort_order = default_sort_order;
static char *dso_list_str, *comm_list_str, *sym_list_str,
*col_width_list_str;
static struct strlist *dso_list, *comm_list, *sym_list;
-static char *field_sep;
static int force;
-static int input;
-static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
static int full_paths;
static int show_nr_samples;
@@ -50,374 +48,38 @@ static struct perf_read_values show_threads_values;
static char default_pretty_printing_style[] = "normal";
static char *pretty_printing_style = default_pretty_printing_style;
-static unsigned long page_size;
-static unsigned long mmap_window = 32;
-
-static char default_parent_pattern[] = "^sys_|^do_page_fault";
-static char *parent_pattern = default_parent_pattern;
-static regex_t parent_regex;
-
static int exclude_other = 1;
static char callchain_default_opt[] = "fractal,0.5";
-static int callchain;
-
-static char __cwd[PATH_MAX];
-static char *cwd = __cwd;
-static int cwdlen;
-
-static struct rb_root threads;
-static struct thread *last_match;
-
static struct perf_header *header;
-static
-struct callchain_param callchain_param = {
- .mode = CHAIN_GRAPH_REL,
- .min_percent = 0.5
-};
-
static u64 sample_type;
-static int repsep_fprintf(FILE *fp, const char *fmt, ...)
-{
- int n;
- va_list ap;
-
- va_start(ap, fmt);
- if (!field_sep)
- n = vfprintf(fp, fmt, ap);
- else {
- char *bf = NULL;
- n = vasprintf(&bf, fmt, ap);
- if (n > 0) {
- char *sep = bf;
-
- while (1) {
- sep = strchr(sep, *field_sep);
- if (sep == NULL)
- break;
- *sep = '.';
- }
- }
- fputs(bf, fp);
- free(bf);
- }
- va_end(ap);
- return n;
-}
-
-static unsigned int dsos__col_width,
- comms__col_width,
- threads__col_width;
+struct symbol_conf symbol_conf;
-/*
- * histogram, sorted on item, collects counts
- */
-
-static struct rb_root hist;
-
-struct hist_entry {
- struct rb_node rb_node;
-
- struct thread *thread;
- struct map *map;
- struct dso *dso;
- struct symbol *sym;
- struct symbol *parent;
- u64 ip;
- char level;
- struct callchain_node callchain;
- struct rb_root sorted_chain;
-
- u64 count;
-};
-
-/*
- * configurable sorting bits
- */
-
-struct sort_entry {
- struct list_head list;
-
- const char *header;
-
- int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
- int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
- size_t (*print)(FILE *fp, struct hist_entry *, unsigned int width);
- unsigned int *width;
- bool elide;
-};
-
-static int64_t cmp_null(void *l, void *r)
-{
- if (!l && !r)
- return 0;
- else if (!l)
- return -1;
- else
- return 1;
-}
-
-/* --sort pid */
-
-static int64_t
-sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- return right->thread->pid - left->thread->pid;
-}
static size_t
-sort__thread_print(FILE *fp, struct hist_entry *self, unsigned int width)
+callchain__fprintf_left_margin(FILE *fp, int left_margin)
{
- return repsep_fprintf(fp, "%*s:%5d", width - 6,
- self->thread->comm ?: "", self->thread->pid);
-}
-
-static struct sort_entry sort_thread = {
- .header = "Command: Pid",
- .cmp = sort__thread_cmp,
- .print = sort__thread_print,
- .width = &threads__col_width,
-};
-
-/* --sort comm */
-
-static int64_t
-sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- return right->thread->pid - left->thread->pid;
-}
-
-static int64_t
-sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
-{
- char *comm_l = left->thread->comm;
- char *comm_r = right->thread->comm;
-
- if (!comm_l || !comm_r)
- return cmp_null(comm_l, comm_r);
-
- return strcmp(comm_l, comm_r);
-}
-
-static size_t
-sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
-{
- return repsep_fprintf(fp, "%*s", width, self->thread->comm);
-}
-
-static struct sort_entry sort_comm = {
- .header = "Command",
- .cmp = sort__comm_cmp,
- .collapse = sort__comm_collapse,
- .print = sort__comm_print,
- .width = &comms__col_width,
-};
-
-/* --sort dso */
-
-static int64_t
-sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- struct dso *dso_l = left->dso;
- struct dso *dso_r = right->dso;
-
- if (!dso_l || !dso_r)
- return cmp_null(dso_l, dso_r);
-
- return strcmp(dso_l->name, dso_r->name);
-}
-
-static size_t
-sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width)
-{
- if (self->dso)
- return repsep_fprintf(fp, "%-*s", width, self->dso->name);
-
- return repsep_fprintf(fp, "%*llx", width, (u64)self->ip);
-}
-
-static struct sort_entry sort_dso = {
- .header = "Shared Object",
- .cmp = sort__dso_cmp,
- .print = sort__dso_print,
- .width = &dsos__col_width,
-};
-
-/* --sort symbol */
-
-static int64_t
-sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- u64 ip_l, ip_r;
-
- if (left->sym == right->sym)
- return 0;
-
- ip_l = left->sym ? left->sym->start : left->ip;
- ip_r = right->sym ? right->sym->start : right->ip;
-
- return (int64_t)(ip_r - ip_l);
-}
-
-static size_t
-sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used)
-{
- size_t ret = 0;
+ int i;
+ int ret;
- if (verbose)
- ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip,
- dso__symtab_origin(self->dso));
+ ret = fprintf(fp, " ");
- ret += repsep_fprintf(fp, "[%c] ", self->level);
- if (self->sym) {
- ret += repsep_fprintf(fp, "%s", self->sym->name);
-
- if (self->sym->module)
- ret += repsep_fprintf(fp, "\t[%s]",
- self->sym->module->name);
- } else {
- ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip);
- }
+ for (i = 0; i < left_margin; i++)
+ ret += fprintf(fp, " ");
return ret;
}
-static struct sort_entry sort_sym = {
- .header = "Symbol",
- .cmp = sort__sym_cmp,
- .print = sort__sym_print,
-};
-
-/* --sort parent */
-
-static int64_t
-sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- struct symbol *sym_l = left->parent;
- struct symbol *sym_r = right->parent;
-
- if (!sym_l || !sym_r)
- return cmp_null(sym_l, sym_r);
-
- return strcmp(sym_l->name, sym_r->name);
-}
-
-static size_t
-sort__parent_print(FILE *fp, struct hist_entry *self, unsigned int width)
-{
- return repsep_fprintf(fp, "%-*s", width,
- self->parent ? self->parent->name : "[other]");
-}
-
-static unsigned int parent_symbol__col_width;
-
-static struct sort_entry sort_parent = {
- .header = "Parent symbol",
- .cmp = sort__parent_cmp,
- .print = sort__parent_print,
- .width = &parent_symbol__col_width,
-};
-
-static int sort__need_collapse = 0;
-static int sort__has_parent = 0;
-
-struct sort_dimension {
- const char *name;
- struct sort_entry *entry;
- int taken;
-};
-
-static struct sort_dimension sort_dimensions[] = {
- { .name = "pid", .entry = &sort_thread, },
- { .name = "comm", .entry = &sort_comm, },
- { .name = "dso", .entry = &sort_dso, },
- { .name = "symbol", .entry = &sort_sym, },
- { .name = "parent", .entry = &sort_parent, },
-};
-
-static LIST_HEAD(hist_entry__sort_list);
-
-static int sort_dimension__add(const char *tok)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
- struct sort_dimension *sd = &sort_dimensions[i];
-
- if (sd->taken)
- continue;
-
- if (strncasecmp(tok, sd->name, strlen(tok)))
- continue;
-
- if (sd->entry->collapse)
- sort__need_collapse = 1;
-
- if (sd->entry == &sort_parent) {
- int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
- if (ret) {
- char err[BUFSIZ];
-
- regerror(ret, &parent_regex, err, sizeof(err));
- fprintf(stderr, "Invalid regex: %s\n%s",
- parent_pattern, err);
- exit(-1);
- }
- sort__has_parent = 1;
- }
-
- list_add_tail(&sd->entry->list, &hist_entry__sort_list);
- sd->taken = 1;
-
- return 0;
- }
-
- return -ESRCH;
-}
-
-static int64_t
-hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
-{
- struct sort_entry *se;
- int64_t cmp = 0;
-
- list_for_each_entry(se, &hist_entry__sort_list, list) {
- cmp = se->cmp(left, right);
- if (cmp)
- break;
- }
-
- return cmp;
-}
-
-static int64_t
-hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
-{
- struct sort_entry *se;
- int64_t cmp = 0;
-
- list_for_each_entry(se, &hist_entry__sort_list, list) {
- int64_t (*f)(struct hist_entry *, struct hist_entry *);
-
- f = se->collapse ?: se->cmp;
-
- cmp = f(left, right);
- if (cmp)
- break;
- }
-
- return cmp;
-}
-
-static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask)
+static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
+ int left_margin)
{
int i;
size_t ret = 0;
- ret += fprintf(fp, "%s", " ");
+ ret += callchain__fprintf_left_margin(fp, left_margin);
for (i = 0; i < depth; i++)
if (depth_mask & (1 << i))
@@ -432,12 +94,12 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask)
static size_t
ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth,
int depth_mask, int count, u64 total_samples,
- int hits)
+ int hits, int left_margin)
{
int i;
size_t ret = 0;
- ret += fprintf(fp, "%s", " ");
+ ret += callchain__fprintf_left_margin(fp, left_margin);
for (i = 0; i < depth; i++) {
if (depth_mask & (1 << i))
ret += fprintf(fp, "|");
@@ -475,8 +137,9 @@ static void init_rem_hits(void)
}
static size_t
-callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
- u64 total_samples, int depth, int depth_mask)
+__callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
+ u64 total_samples, int depth, int depth_mask,
+ int left_margin)
{
struct rb_node *node, *next;
struct callchain_node *child;
@@ -517,7 +180,8 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
* But we keep the older depth mask for the line seperator
* to keep the level link until we reach the last child
*/
- ret += ipchain__fprintf_graph_line(fp, depth, depth_mask);
+ ret += ipchain__fprintf_graph_line(fp, depth, depth_mask,
+ left_margin);
i = 0;
list_for_each_entry(chain, &child->val, list) {
if (chain->ip >= PERF_CONTEXT_MAX)
@@ -525,11 +189,13 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
ret += ipchain__fprintf_graph(fp, chain, depth,
new_depth_mask, i++,
new_total,
- cumul);
+ cumul,
+ left_margin);
}
- ret += callchain__fprintf_graph(fp, child, new_total,
- depth + 1,
- new_depth_mask | (1 << depth));
+ ret += __callchain__fprintf_graph(fp, child, new_total,
+ depth + 1,
+ new_depth_mask | (1 << depth),
+ left_margin);
node = next;
}
@@ -543,9 +209,48 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
ret += ipchain__fprintf_graph(fp, &rem_hits, depth,
new_depth_mask, 0, new_total,
- remaining);
+ remaining, left_margin);
+ }
+
+ return ret;
+}
+
+
+static size_t
+callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
+ u64 total_samples, int left_margin)
+{
+ struct callchain_list *chain;
+ bool printed = false;
+ int i = 0;
+ int ret = 0;
+
+ list_for_each_entry(chain, &self->val, list) {
+ if (chain->ip >= PERF_CONTEXT_MAX)
+ continue;
+
+ if (!i++ && sort__first_dimension == SORT_SYM)
+ continue;
+
+ if (!printed) {
+ ret += callchain__fprintf_left_margin(fp, left_margin);
+ ret += fprintf(fp, "|\n");
+ ret += callchain__fprintf_left_margin(fp, left_margin);
+ ret += fprintf(fp, "---");
+
+ left_margin += 3;
+ printed = true;
+ } else
+ ret += callchain__fprintf_left_margin(fp, left_margin);
+
+ if (chain->sym)
+ ret += fprintf(fp, " %s\n", chain->sym->name);
+ else
+ ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
}
+ ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin);
+
return ret;
}
@@ -577,7 +282,7 @@ callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
static size_t
hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
- u64 total_samples)
+ u64 total_samples, int left_margin)
{
struct rb_node *rb_node;
struct callchain_node *chain;
@@ -597,8 +302,8 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
break;
case CHAIN_GRAPH_ABS: /* Falldown */
case CHAIN_GRAPH_REL:
- ret += callchain__fprintf_graph(fp, chain,
- total_samples, 1, 1);
+ ret += callchain__fprintf_graph(fp, chain, total_samples,
+ left_margin);
case CHAIN_NONE:
default:
break;
@@ -610,7 +315,6 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
return ret;
}
-
static size_t
hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
{
@@ -644,8 +348,19 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
ret += fprintf(fp, "\n");
- if (callchain)
- hist_entry_callchain__fprintf(fp, self, total_samples);
+ if (callchain) {
+ int left_margin = 0;
+
+ if (sort__first_dimension == SORT_COMM) {
+ se = list_first_entry(&hist_entry__sort_list, typeof(*se),
+ list);
+ left_margin = se->width ? *se->width : 0;
+ left_margin -= thread__comm_len(self->thread);
+ }
+
+ hist_entry_callchain__fprintf(fp, self, total_samples,
+ left_margin);
+ }
return ret;
}
@@ -693,63 +408,6 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm)
return 0;
}
-
-static struct symbol *
-resolve_symbol(struct thread *thread, struct map **mapp,
- struct dso **dsop, u64 *ipp)
-{
- struct dso *dso = dsop ? *dsop : NULL;
- struct map *map = mapp ? *mapp : NULL;
- u64 ip = *ipp;
-
- if (!thread)
- return NULL;
-
- if (dso)
- goto got_dso;
-
- if (map)
- goto got_map;
-
- map = thread__find_map(thread, ip);
- if (map != NULL) {
- /*
- * We have to do this here as we may have a dso
- * with no symbol hit that has a name longer than
- * the ones with symbols sampled.
- */
- if (!sort_dso.elide && !map->dso->slen_calculated)
- dso__calc_col_width(map->dso);
-
- if (mapp)
- *mapp = map;
-got_map:
- ip = map->map_ip(map, ip);
-
- dso = map->dso;
- } else {
- /*
- * If this is outside of all known maps,
- * and is a negative address, try to look it
- * up in the kernel dso, as it might be a
- * vsyscall (which executes in user-mode):
- */
- if ((long long)ip < 0)
- dso = kernel_dso;
- }
- dump_printf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
- dump_printf(" ...... map: %Lx -> %Lx\n", *ipp, ip);
- *ipp = ip;
-
- if (dsop)
- *dsop = dso;
-
- if (!dso)
- return NULL;
-got_dso:
- return dso->find_symbol(dso, ip);
-}
-
static int call__match(struct symbol *sym)
{
if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
@@ -758,11 +416,11 @@ static int call__match(struct symbol *sym)
return 0;
}
-static struct symbol **
-resolve_callchain(struct thread *thread, struct map *map __used,
- struct ip_callchain *chain, struct hist_entry *entry)
+static struct symbol **resolve_callchain(struct thread *thread,
+ struct ip_callchain *chain,
+ struct symbol **parent)
{
- u64 context = PERF_CONTEXT_MAX;
+ u8 cpumode = PERF_RECORD_MISC_USER;
struct symbol **syms = NULL;
unsigned int i;
@@ -776,34 +434,31 @@ resolve_callchain(struct thread *thread, struct map *map __used,
for (i = 0; i < chain->nr; i++) {
u64 ip = chain->ips[i];
- struct dso *dso = NULL;
- struct symbol *sym;
+ struct addr_location al;
if (ip >= PERF_CONTEXT_MAX) {
- context = ip;
+ switch (ip) {
+ case PERF_CONTEXT_HV:
+ cpumode = PERF_RECORD_MISC_HYPERVISOR; break;
+ case PERF_CONTEXT_KERNEL:
+ cpumode = PERF_RECORD_MISC_KERNEL; break;
+ case PERF_CONTEXT_USER:
+ cpumode = PERF_RECORD_MISC_USER; break;
+ default:
+ break;
+ }
continue;
}
- switch (context) {
- case PERF_CONTEXT_HV:
- dso = hypervisor_dso;
- break;
- case PERF_CONTEXT_KERNEL:
- dso = kernel_dso;
- break;
- default:
- break;
- }
-
- sym = resolve_symbol(thread, NULL, &dso, &ip);
-
- if (sym) {
- if (sort__has_parent && call__match(sym) &&
- !entry->parent)
- entry->parent = sym;
+ thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
+ ip, &al, NULL);
+ if (al.sym != NULL) {
+ if (sort__has_parent && !*parent &&
+ call__match(al.sym))
+ *parent = al.sym;
if (!callchain)
break;
- syms[i] = sym;
+ syms[i] = al.sym;
}
}
@@ -814,178 +469,33 @@ resolve_callchain(struct thread *thread, struct map *map __used,
* collect histogram counts
*/
-static int
-hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
- struct symbol *sym, u64 ip, struct ip_callchain *chain,
- char level, u64 count)
+static int hist_entry__add(struct addr_location *al,
+ struct ip_callchain *chain, u64 count)
{
- struct rb_node **p = &hist.rb_node;
- struct rb_node *parent = NULL;
+ struct symbol **syms = NULL, *parent = NULL;
+ bool hit;
struct hist_entry *he;
- struct symbol **syms = NULL;
- struct hist_entry entry = {
- .thread = thread,
- .map = map,
- .dso = dso,
- .sym = sym,
- .ip = ip,
- .level = level,
- .count = count,
- .parent = NULL,
- .sorted_chain = RB_ROOT
- };
- int cmp;
if ((sort__has_parent || callchain) && chain)
- syms = resolve_callchain(thread, map, chain, &entry);
+ syms = resolve_callchain(al->thread, chain, &parent);
- while (*p != NULL) {
- parent = *p;
- he = rb_entry(parent, struct hist_entry, rb_node);
+ he = __hist_entry__add(al, parent, count, &hit);
+ if (he == NULL)
+ return -ENOMEM;
- cmp = hist_entry__cmp(&entry, he);
+ if (hit)
+ he->count += count;
- if (!cmp) {
- he->count += count;
- if (callchain) {
- append_chain(&he->callchain, chain, syms);
- free(syms);
- }
- return 0;
- }
-
- if (cmp < 0)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- he = malloc(sizeof(*he));
- if (!he)
- return -ENOMEM;
- *he = entry;
if (callchain) {
- callchain_init(&he->callchain);
+ if (!hit)
+ callchain_init(&he->callchain);
append_chain(&he->callchain, chain, syms);
free(syms);
}
- rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, &hist);
return 0;
}
-static void hist_entry__free(struct hist_entry *he)
-{
- free(he);
-}
-
-/*
- * collapse the histogram
- */
-
-static struct rb_root collapse_hists;
-
-static void collapse__insert_entry(struct hist_entry *he)
-{
- struct rb_node **p = &collapse_hists.rb_node;
- struct rb_node *parent = NULL;
- struct hist_entry *iter;
- int64_t cmp;
-
- while (*p != NULL) {
- parent = *p;
- iter = rb_entry(parent, struct hist_entry, rb_node);
-
- cmp = hist_entry__collapse(iter, he);
-
- if (!cmp) {
- iter->count += he->count;
- hist_entry__free(he);
- return;
- }
-
- if (cmp < 0)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, &collapse_hists);
-}
-
-static void collapse__resort(void)
-{
- struct rb_node *next;
- struct hist_entry *n;
-
- if (!sort__need_collapse)
- return;
-
- next = rb_first(&hist);
- while (next) {
- n = rb_entry(next, struct hist_entry, rb_node);
- next = rb_next(&n->rb_node);
-
- rb_erase(&n->rb_node, &hist);
- collapse__insert_entry(n);
- }
-}
-
-/*
- * reverse the map, sort on count.
- */
-
-static struct rb_root output_hists;
-
-static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
-{
- struct rb_node **p = &output_hists.rb_node;
- struct rb_node *parent = NULL;
- struct hist_entry *iter;
-
- if (callchain)
- callchain_param.sort(&he->sorted_chain, &he->callchain,
- min_callchain_hits, &callchain_param);
-
- while (*p != NULL) {
- parent = *p;
- iter = rb_entry(parent, struct hist_entry, rb_node);
-
- if (he->count > iter->count)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, &output_hists);
-}
-
-static void output__resort(u64 total_samples)
-{
- struct rb_node *next;
- struct hist_entry *n;
- struct rb_root *tree = &hist;
- u64 min_callchain_hits;
-
- min_callchain_hits = total_samples * (callchain_param.min_percent / 100);
-
- if (sort__need_collapse)
- tree = &collapse_hists;
-
- next = rb_first(tree);
-
- while (next) {
- n = rb_entry(next, struct hist_entry, rb_node);
- next = rb_next(&n->rb_node);
-
- rb_erase(&n->rb_node, tree);
- output__insert_entry(n, min_callchain_hits);
- }
-}
-
static size_t output__fprintf(FILE *fp, u64 total_samples)
{
struct hist_entry *pos;
@@ -1080,13 +590,6 @@ print_entries:
return ret;
}
-static unsigned long total = 0,
- total_mmap = 0,
- total_comm = 0,
- total_fork = 0,
- total_unknown = 0,
- total_lost = 0;
-
static int validate_chain(struct ip_callchain *chain, event_t *event)
{
unsigned int chain_size;
@@ -1100,30 +603,22 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)
return 0;
}
-static int
-process_sample_event(event_t *event, unsigned long offset, unsigned long head)
+static int process_sample_event(event_t *event)
{
- char level;
- int show = 0;
- struct dso *dso = NULL;
- struct thread *thread;
u64 ip = event->ip.ip;
u64 period = 1;
- struct map *map = NULL;
void *more_data = event->ip.__more_data;
struct ip_callchain *chain = NULL;
int cpumode;
-
- thread = threads__findnew(event->ip.pid, &threads, &last_match);
+ struct addr_location al;
+ struct thread *thread = threads__findnew(event->ip.pid);
if (sample_type & PERF_SAMPLE_PERIOD) {
period = *(u64 *)more_data;
more_data += sizeof(u64);
}
- dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
+ dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
event->header.misc,
event->ip.pid, event->ip.tid,
(void *)(long)ip,
@@ -1137,7 +632,8 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
dump_printf("... chain: nr:%Lu\n", chain->nr);
if (validate_chain(chain, event) < 0) {
- eprintf("call-chain problem with event, skipping it.\n");
+ pr_debug("call-chain problem with event, "
+ "skipping it.\n");
return 0;
}
@@ -1147,163 +643,64 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
}
}
- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
-
if (thread == NULL) {
- eprintf("problem processing %d event, skipping it.\n",
+ pr_debug("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
}
+ dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
+
if (comm_list && !strlist__has_entry(comm_list, thread->comm))
return 0;
cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
- if (cpumode == PERF_RECORD_MISC_KERNEL) {
- show = SHOW_KERNEL;
- level = 'k';
-
- dso = kernel_dso;
-
- dump_printf(" ...... dso: %s\n", dso->name);
-
- } else if (cpumode == PERF_RECORD_MISC_USER) {
-
- show = SHOW_USER;
- level = '.';
-
- } else {
- show = SHOW_HV;
- level = 'H';
-
- dso = hypervisor_dso;
-
- dump_printf(" ...... dso: [hypervisor]\n");
- }
-
- if (show & show_mask) {
- struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip);
-
- if (dso_list && (!dso || !dso->name ||
- !strlist__has_entry(dso_list, dso->name)))
- return 0;
-
- if (sym_list && (!sym || !strlist__has_entry(sym_list, sym->name)))
- return 0;
-
- if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) {
- eprintf("problem incrementing symbol count, skipping event\n");
- return -1;
- }
- }
- total += period;
-
- return 0;
-}
+ thread__find_addr_location(thread, cpumode,
+ MAP__FUNCTION, ip, &al, NULL);
+ /*
+ * We have to do this here as we may have a dso with no symbol hit that
+ * has a name longer than the ones with symbols sampled.
+ */
+ if (al.map && !sort_dso.elide && !al.map->dso->slen_calculated)
+ dso__calc_col_width(al.map->dso);
+
+ if (dso_list &&
+ (!al.map || !al.map->dso ||
+ !(strlist__has_entry(dso_list, al.map->dso->short_name) ||
+ (al.map->dso->short_name != al.map->dso->long_name &&
+ strlist__has_entry(dso_list, al.map->dso->long_name)))))
+ return 0;
-static int
-process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
-{
- struct thread *thread;
- struct map *map = map__new(&event->mmap, cwd, cwdlen);
-
- thread = threads__findnew(event->mmap.pid, &threads, &last_match);
-
- dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->mmap.pid,
- event->mmap.tid,
- (void *)(long)event->mmap.start,
- (void *)(long)event->mmap.len,
- (void *)(long)event->mmap.pgoff,
- event->mmap.filename);
-
- if (thread == NULL || map == NULL) {
- dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
+ if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name))
return 0;
+
+ if (hist_entry__add(&al, chain, period)) {
+ pr_debug("problem incrementing symbol count, skipping event\n");
+ return -1;
}
- thread__insert_map(thread, map);
- total_mmap++;
+ event__stats.total += period;
return 0;
}
-static int
-process_comm_event(event_t *event, unsigned long offset, unsigned long head)
+static int process_comm_event(event_t *event)
{
- struct thread *thread;
-
- thread = threads__findnew(event->comm.pid, &threads, &last_match);
+ struct thread *thread = threads__findnew(event->comm.pid);
- dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->comm.comm, event->comm.pid);
+ dump_printf(": %s:%d\n", event->comm.comm, event->comm.pid);
if (thread == NULL ||
thread__set_comm_adjust(thread, event->comm.comm)) {
dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
return -1;
}
- total_comm++;
-
- return 0;
-}
-
-static int
-process_task_event(event_t *event, unsigned long offset, unsigned long head)
-{
- struct thread *thread;
- struct thread *parent;
-
- thread = threads__findnew(event->fork.pid, &threads, &last_match);
- parent = threads__findnew(event->fork.ppid, &threads, &last_match);
-
- dump_printf("%p [%p]: PERF_RECORD_%s: (%d:%d):(%d:%d)\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->header.type == PERF_RECORD_FORK ? "FORK" : "EXIT",
- event->fork.pid, event->fork.tid,
- event->fork.ppid, event->fork.ptid);
-
- /*
- * A thread clone will have the same PID for both
- * parent and child.
- */
- if (thread == parent)
- return 0;
-
- if (event->header.type == PERF_RECORD_EXIT)
- return 0;
-
- if (!thread || !parent || thread__fork(thread, parent)) {
- dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
- return -1;
- }
- total_fork++;
return 0;
}
-static int
-process_lost_event(event_t *event, unsigned long offset, unsigned long head)
-{
- dump_printf("%p [%p]: PERF_RECORD_LOST: id:%Ld: lost:%Ld\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->lost.id,
- event->lost.lost);
-
- total_lost += event->lost.lost;
-
- return 0;
-}
-
-static int
-process_read_event(event_t *event, unsigned long offset, unsigned long head)
+static int process_read_event(event_t *event)
{
struct perf_event_attr *attr;
@@ -1319,238 +716,91 @@ process_read_event(event_t *event, unsigned long offset, unsigned long head)
event->read.value);
}
- dump_printf("%p [%p]: PERF_RECORD_READ: %d %d %s %Lu\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->read.pid,
- event->read.tid,
- attr ? __event_name(attr->type, attr->config)
- : "FAIL",
- event->read.value);
-
- return 0;
-}
-
-static int
-process_event(event_t *event, unsigned long offset, unsigned long head)
-{
- trace_event(event);
-
- switch (event->header.type) {
- case PERF_RECORD_SAMPLE:
- return process_sample_event(event, offset, head);
-
- case PERF_RECORD_MMAP:
- return process_mmap_event(event, offset, head);
-
- case PERF_RECORD_COMM:
- return process_comm_event(event, offset, head);
-
- case PERF_RECORD_FORK:
- case PERF_RECORD_EXIT:
- return process_task_event(event, offset, head);
-
- case PERF_RECORD_LOST:
- return process_lost_event(event, offset, head);
-
- case PERF_RECORD_READ:
- return process_read_event(event, offset, head);
-
- /*
- * We dont process them right now but they are fine:
- */
-
- case PERF_RECORD_THROTTLE:
- case PERF_RECORD_UNTHROTTLE:
- return 0;
-
- default:
- return -1;
- }
+ dump_printf(": %d %d %s %Lu\n", event->read.pid, event->read.tid,
+ attr ? __event_name(attr->type, attr->config) : "FAIL",
+ event->read.value);
return 0;
}
-static int __cmd_report(void)
+static int sample_type_check(u64 type)
{
- int ret, rc = EXIT_FAILURE;
- unsigned long offset = 0;
- unsigned long head, shift;
- struct stat input_stat;
- struct thread *idle;
- event_t *event;
- uint32_t size;
- char *buf;
-
- idle = register_idle_thread(&threads, &last_match);
- thread__comm_adjust(idle);
-
- if (show_threads)
- perf_read_values_init(&show_threads_values);
-
- input = open(input_name, O_RDONLY);
- if (input < 0) {
- fprintf(stderr, " failed to open file: %s", input_name);
- if (!strcmp(input_name, "perf.data"))
- fprintf(stderr, " (try 'perf record' first)");
- fprintf(stderr, "\n");
- exit(-1);
- }
-
- ret = fstat(input, &input_stat);
- if (ret < 0) {
- perror("failed to stat file");
- exit(-1);
- }
-
- if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
- fprintf(stderr, "file: %s not owned by current user or root\n", input_name);
- exit(-1);
- }
-
- if (!input_stat.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- exit(0);
- }
-
- header = perf_header__read(input);
- head = header->data_offset;
-
- sample_type = perf_header__sample_type(header);
+ sample_type = type;
if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
if (sort__has_parent) {
fprintf(stderr, "selected --sort parent, but no"
" callchain data. Did you call"
" perf record without -g?\n");
- exit(-1);
+ return -1;
}
if (callchain) {
fprintf(stderr, "selected -g but no callchain data."
" Did you call perf record without"
" -g?\n");
- exit(-1);
+ return -1;
}
} else if (callchain_param.mode != CHAIN_NONE && !callchain) {
callchain = 1;
if (register_callchain_param(&callchain_param) < 0) {
fprintf(stderr, "Can't register callchain"
" params\n");
- exit(-1);
+ return -1;
}
}
- if (load_kernel() < 0) {
- perror("failed to load kernel symbols");
- return EXIT_FAILURE;
- }
-
- if (!full_paths) {
- if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
- perror("failed to get the current directory");
- return EXIT_FAILURE;
- }
- cwdlen = strlen(cwd);
- } else {
- cwd = NULL;
- cwdlen = 0;
- }
-
- shift = page_size * (head / page_size);
- offset += shift;
- head -= shift;
-
-remap:
- buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
- MAP_SHARED, input, offset);
- if (buf == MAP_FAILED) {
- perror("failed to mmap file");
- exit(-1);
- }
-
-more:
- event = (event_t *)(buf + head);
-
- size = event->header.size;
- if (!size)
- size = 8;
-
- if (head + event->header.size >= page_size * mmap_window) {
- int munmap_ret;
-
- shift = page_size * (head / page_size);
-
- munmap_ret = munmap(buf, page_size * mmap_window);
- assert(munmap_ret == 0);
-
- offset += shift;
- head -= shift;
- goto remap;
- }
-
- size = event->header.size;
-
- dump_printf("\n%p [%p]: event: %d\n",
- (void *)(offset + head),
- (void *)(long)event->header.size,
- event->header.type);
-
- if (!size || process_event(event, offset, head) < 0) {
-
- dump_printf("%p [%p]: skipping unknown header type: %d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->header.type);
-
- total_unknown++;
-
- /*
- * assume we lost track of the stream, check alignment, and
- * increment a single u64 in the hope to catch on again 'soon'.
- */
+ return 0;
+}
- if (unlikely(head & 7))
- head &= ~7ULL;
+static struct perf_file_handler file_handler = {
+ .process_sample_event = process_sample_event,
+ .process_mmap_event = event__process_mmap,
+ .process_comm_event = process_comm_event,
+ .process_exit_event = event__process_task,
+ .process_fork_event = event__process_task,
+ .process_lost_event = event__process_lost,
+ .process_read_event = process_read_event,
+ .sample_type_check = sample_type_check,
+};
- size = 8;
- }
- head += size;
+static int __cmd_report(void)
+{
+ struct thread *idle;
+ int ret;
- if (offset + head >= header->data_offset + header->data_size)
- goto done;
+ idle = register_idle_thread();
+ thread__comm_adjust(idle);
- if (offset + head < (unsigned long)input_stat.st_size)
- goto more;
+ if (show_threads)
+ perf_read_values_init(&show_threads_values);
-done:
- rc = EXIT_SUCCESS;
- close(input);
+ register_perf_file_handler(&file_handler);
- dump_printf(" IP events: %10ld\n", total);
- dump_printf(" mmap events: %10ld\n", total_mmap);
- dump_printf(" comm events: %10ld\n", total_comm);
- dump_printf(" fork events: %10ld\n", total_fork);
- dump_printf(" lost events: %10ld\n", total_lost);
- dump_printf(" unknown events: %10ld\n", total_unknown);
+ ret = mmap_dispatch_perf_file(&header, input_name, force,
+ full_paths, &event__cwdlen, &event__cwd);
+ if (ret)
+ return ret;
- if (dump_trace)
+ if (dump_trace) {
+ event__print_totals();
return 0;
+ }
- if (verbose >= 3)
- threads__fprintf(stdout, &threads);
+ if (verbose > 3)
+ threads__fprintf(stdout);
- if (verbose >= 2)
+ if (verbose > 2)
dsos__fprintf(stdout);
collapse__resort();
- output__resort(total);
- output__fprintf(stdout, total);
+ output__resort(event__stats.total);
+ output__fprintf(stdout, event__stats.total);
if (show_threads)
perf_read_values_destroy(&show_threads_values);
- return rc;
+ return ret;
}
static int
@@ -1606,7 +856,8 @@ setup:
return 0;
}
-static const char * const report_usage[] = {
+//static const char * const report_usage[] = {
+const char * const report_usage[] = {
"perf report [<options>] <command>",
NULL
};
@@ -1618,9 +869,10 @@ static const struct option options[] = {
"be more verbose (show symbol address, etc)"),
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
- OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"),
+ OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
+ "file", "vmlinux pathname"),
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
- OPT_BOOLEAN('m', "modules", &modules,
+ OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
"load module symbols - WARNING: use only with -k and LIVE kernel"),
OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples,
"Show a column with the number of samples"),
@@ -1690,9 +942,8 @@ static void setup_list(struct strlist **list, const char *list_str,
int cmd_report(int argc, const char **argv, const char *prefix __used)
{
- symbol__init();
-
- page_size = getpagesize();
+ if (symbol__init(&symbol_conf) < 0)
+ return -1;
argc = parse_options(argc, argv, options, report_usage, 0);
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index ea9c15c0cdfe..26b782f26ee1 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -11,6 +11,7 @@
#include "util/trace-event.h"
#include "util/debug.h"
+#include "util/data_map.h"
#include <sys/types.h>
#include <sys/prctl.h>
@@ -20,14 +21,6 @@
#include <math.h>
static char const *input_name = "perf.data";
-static int input;
-static unsigned long page_size;
-static unsigned long mmap_window = 32;
-
-static unsigned long total_comm = 0;
-
-static struct rb_root threads;
-static struct thread *last_match;
static struct perf_header *header;
static u64 sample_type;
@@ -35,11 +28,11 @@ static u64 sample_type;
static char default_sort_order[] = "avg, max, switch, runtime";
static char *sort_order = default_sort_order;
+static int profile_cpu = -1;
+
#define PR_SET_NAME 15 /* Set process name */
#define MAX_CPUS 4096
-#define BUG_ON(x) assert(!(x))
-
static u64 run_measurement_overhead;
static u64 sleep_measurement_overhead;
@@ -74,6 +67,7 @@ enum sched_event_type {
SCHED_EVENT_RUN,
SCHED_EVENT_SLEEP,
SCHED_EVENT_WAKEUP,
+ SCHED_EVENT_MIGRATION,
};
struct sched_atom {
@@ -226,7 +220,7 @@ static void calibrate_sleep_measurement_overhead(void)
static struct sched_atom *
get_new_event(struct task_desc *task, u64 timestamp)
{
- struct sched_atom *event = calloc(1, sizeof(*event));
+ struct sched_atom *event = zalloc(sizeof(*event));
unsigned long idx = task->nr_events;
size_t size;
@@ -294,7 +288,7 @@ add_sched_event_wakeup(struct task_desc *task, u64 timestamp,
return;
}
- wakee_event->wait_sem = calloc(1, sizeof(*wakee_event->wait_sem));
+ wakee_event->wait_sem = zalloc(sizeof(*wakee_event->wait_sem));
sem_init(wakee_event->wait_sem, 0, 0);
wakee_event->specific_wait = 1;
event->wait_sem = wakee_event->wait_sem;
@@ -324,7 +318,7 @@ static struct task_desc *register_pid(unsigned long pid, const char *comm)
if (task)
return task;
- task = calloc(1, sizeof(*task));
+ task = zalloc(sizeof(*task));
task->pid = pid;
task->nr = nr_tasks;
strcpy(task->comm, comm);
@@ -398,6 +392,8 @@ process_sched_event(struct task_desc *this_task __used, struct sched_atom *atom)
ret = sem_post(atom->wait_sem);
BUG_ON(ret);
break;
+ case SCHED_EVENT_MIGRATION:
+ break;
default:
BUG_ON(1);
}
@@ -632,29 +628,6 @@ static void test_calibrations(void)
printf("the sleep test took %Ld nsecs\n", T1-T0);
}
-static int
-process_comm_event(event_t *event, unsigned long offset, unsigned long head)
-{
- struct thread *thread;
-
- thread = threads__findnew(event->comm.pid, &threads, &last_match);
-
- dump_printf("%p [%p]: perf_event_comm: %s:%d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->comm.comm, event->comm.pid);
-
- if (thread == NULL ||
- thread__set_comm(thread, event->comm.comm)) {
- dump_printf("problem processing perf_event_comm, skipping event.\n");
- return -1;
- }
- total_comm++;
-
- return 0;
-}
-
-
struct raw_event_sample {
u32 size;
char data[0];
@@ -745,6 +718,22 @@ struct trace_fork_event {
u32 child_pid;
};
+struct trace_migrate_task_event {
+ u32 size;
+
+ u16 common_type;
+ u8 common_flags;
+ u8 common_preempt_count;
+ u32 common_pid;
+ u32 common_tgid;
+
+ char comm[16];
+ u32 pid;
+
+ u32 prio;
+ u32 cpu;
+};
+
struct trace_sched_handler {
void (*switch_event)(struct trace_switch_event *,
struct event *,
@@ -769,6 +758,12 @@ struct trace_sched_handler {
int cpu,
u64 timestamp,
struct thread *thread);
+
+ void (*migrate_task_event)(struct trace_migrate_task_event *,
+ struct event *,
+ int cpu,
+ u64 timestamp,
+ struct thread *thread);
};
@@ -941,9 +936,7 @@ __thread_latency_insert(struct rb_root *root, struct work_atoms *data,
static void thread_atoms_insert(struct thread *thread)
{
- struct work_atoms *atoms;
-
- atoms = calloc(sizeof(*atoms), 1);
+ struct work_atoms *atoms = zalloc(sizeof(*atoms));
if (!atoms)
die("No memory");
@@ -975,9 +968,7 @@ add_sched_out_event(struct work_atoms *atoms,
char run_state,
u64 timestamp)
{
- struct work_atom *atom;
-
- atom = calloc(sizeof(*atom), 1);
+ struct work_atom *atom = zalloc(sizeof(*atom));
if (!atom)
die("Non memory");
@@ -1058,8 +1049,8 @@ latency_switch_event(struct trace_switch_event *switch_event,
die("hm, delta: %Ld < 0 ?\n", delta);
- sched_out = threads__findnew(switch_event->prev_pid, &threads, &last_match);
- sched_in = threads__findnew(switch_event->next_pid, &threads, &last_match);
+ sched_out = threads__findnew(switch_event->prev_pid);
+ sched_in = threads__findnew(switch_event->next_pid);
out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid);
if (!out_events) {
@@ -1092,13 +1083,10 @@ latency_runtime_event(struct trace_runtime_event *runtime_event,
u64 timestamp,
struct thread *this_thread __used)
{
- struct work_atoms *atoms;
- struct thread *thread;
+ struct thread *thread = threads__findnew(runtime_event->pid);
+ struct work_atoms *atoms = thread_atoms_search(&atom_root, thread, &cmp_pid);
BUG_ON(cpu >= MAX_CPUS || cpu < 0);
-
- thread = threads__findnew(runtime_event->pid, &threads, &last_match);
- atoms = thread_atoms_search(&atom_root, thread, &cmp_pid);
if (!atoms) {
thread_atoms_insert(thread);
atoms = thread_atoms_search(&atom_root, thread, &cmp_pid);
@@ -1125,7 +1113,7 @@ latency_wakeup_event(struct trace_wakeup_event *wakeup_event,
if (!wakeup_event->success)
return;
- wakee = threads__findnew(wakeup_event->pid, &threads, &last_match);
+ wakee = threads__findnew(wakeup_event->pid);
atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid);
if (!atoms) {
thread_atoms_insert(wakee);
@@ -1139,7 +1127,12 @@ latency_wakeup_event(struct trace_wakeup_event *wakeup_event,
atom = list_entry(atoms->work_list.prev, struct work_atom, list);
- if (atom->state != THREAD_SLEEPING)
+ /*
+ * You WILL be missing events if you've recorded only
+ * one CPU, or are only looking at only one, so don't
+ * make useless noise.
+ */
+ if (profile_cpu == -1 && atom->state != THREAD_SLEEPING)
nr_state_machine_bugs++;
nr_timestamps++;
@@ -1152,11 +1145,51 @@ latency_wakeup_event(struct trace_wakeup_event *wakeup_event,
atom->wake_up_time = timestamp;
}
+static void
+latency_migrate_task_event(struct trace_migrate_task_event *migrate_task_event,
+ struct event *__event __used,
+ int cpu __used,
+ u64 timestamp,
+ struct thread *thread __used)
+{
+ struct work_atoms *atoms;
+ struct work_atom *atom;
+ struct thread *migrant;
+
+ /*
+ * Only need to worry about migration when profiling one CPU.
+ */
+ if (profile_cpu == -1)
+ return;
+
+ migrant = threads__findnew(migrate_task_event->pid);
+ atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid);
+ if (!atoms) {
+ thread_atoms_insert(migrant);
+ register_pid(migrant->pid, migrant->comm);
+ atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid);
+ if (!atoms)
+ die("migration-event: Internal tree error");
+ add_sched_out_event(atoms, 'R', timestamp);
+ }
+
+ BUG_ON(list_empty(&atoms->work_list));
+
+ atom = list_entry(atoms->work_list.prev, struct work_atom, list);
+ atom->sched_in_time = atom->sched_out_time = atom->wake_up_time = timestamp;
+
+ nr_timestamps++;
+
+ if (atom->sched_out_time > timestamp)
+ nr_unordered_timestamps++;
+}
+
static struct trace_sched_handler lat_ops = {
.wakeup_event = latency_wakeup_event,
.switch_event = latency_switch_event,
.runtime_event = latency_runtime_event,
.fork_event = latency_fork_event,
+ .migrate_task_event = latency_migrate_task_event,
};
static void output_lat_thread(struct work_atoms *work_list)
@@ -1287,7 +1320,7 @@ static struct sort_dimension *available_sorts[] = {
static LIST_HEAD(sort_list);
-static int sort_dimension__add(char *tok, struct list_head *list)
+static int sort_dimension__add(const char *tok, struct list_head *list)
{
int i;
@@ -1385,8 +1418,8 @@ map_switch_event(struct trace_switch_event *switch_event,
die("hm, delta: %Ld < 0 ?\n", delta);
- sched_out = threads__findnew(switch_event->prev_pid, &threads, &last_match);
- sched_in = threads__findnew(switch_event->next_pid, &threads, &last_match);
+ sched_out = threads__findnew(switch_event->prev_pid);
+ sched_in = threads__findnew(switch_event->next_pid);
curr_thread[this_cpu] = sched_in;
@@ -1517,6 +1550,26 @@ process_sched_exit_event(struct event *event,
}
static void
+process_sched_migrate_task_event(struct raw_event_sample *raw,
+ struct event *event,
+ int cpu __used,
+ u64 timestamp __used,
+ struct thread *thread __used)
+{
+ struct trace_migrate_task_event migrate_task_event;
+
+ FILL_COMMON_FIELDS(migrate_task_event, event, raw->data);
+
+ FILL_ARRAY(migrate_task_event, comm, event, raw->data);
+ FILL_FIELD(migrate_task_event, pid, event, raw->data);
+ FILL_FIELD(migrate_task_event, prio, event, raw->data);
+ FILL_FIELD(migrate_task_event, cpu, event, raw->data);
+
+ if (trace_handler->migrate_task_event)
+ trace_handler->migrate_task_event(&migrate_task_event, event, cpu, timestamp, thread);
+}
+
+static void
process_raw_event(event_t *raw_event __used, void *more_data,
int cpu, u64 timestamp, struct thread *thread)
{
@@ -1539,23 +1592,23 @@ process_raw_event(event_t *raw_event __used, void *more_data,
process_sched_fork_event(raw, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_process_exit"))
process_sched_exit_event(event, cpu, timestamp, thread);
+ if (!strcmp(event->name, "sched_migrate_task"))
+ process_sched_migrate_task_event(raw, event, cpu, timestamp, thread);
}
-static int
-process_sample_event(event_t *event, unsigned long offset, unsigned long head)
+static int process_sample_event(event_t *event)
{
- char level;
- int show = 0;
- struct dso *dso = NULL;
struct thread *thread;
u64 ip = event->ip.ip;
u64 timestamp = -1;
u32 cpu = -1;
u64 period = 1;
void *more_data = event->ip.__more_data;
- int cpumode;
- thread = threads__findnew(event->ip.pid, &threads, &last_match);
+ if (!(sample_type & PERF_SAMPLE_RAW))
+ return 0;
+
+ thread = threads__findnew(event->ip.pid);
if (sample_type & PERF_SAMPLE_TIME) {
timestamp = *(u64 *)more_data;
@@ -1573,177 +1626,64 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
more_data += sizeof(u64);
}
- dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
+ dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
event->header.misc,
event->ip.pid, event->ip.tid,
(void *)(long)ip,
(long long)period);
- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
-
if (thread == NULL) {
- eprintf("problem processing %d event, skipping it.\n",
- event->header.type);
+ pr_debug("problem processing %d event, skipping it.\n",
+ event->header.type);
return -1;
}
- cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
-
- if (cpumode == PERF_RECORD_MISC_KERNEL) {
- show = SHOW_KERNEL;
- level = 'k';
-
- dso = kernel_dso;
-
- dump_printf(" ...... dso: %s\n", dso->name);
-
- } else if (cpumode == PERF_RECORD_MISC_USER) {
-
- show = SHOW_USER;
- level = '.';
-
- } else {
- show = SHOW_HV;
- level = 'H';
-
- dso = hypervisor_dso;
+ dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
- dump_printf(" ...... dso: [hypervisor]\n");
- }
+ if (profile_cpu != -1 && profile_cpu != (int) cpu)
+ return 0;
- if (sample_type & PERF_SAMPLE_RAW)
- process_raw_event(event, more_data, cpu, timestamp, thread);
+ process_raw_event(event, more_data, cpu, timestamp, thread);
return 0;
}
-static int
-process_event(event_t *event, unsigned long offset, unsigned long head)
+static int process_lost_event(event_t *event __used)
{
- trace_event(event);
-
- nr_events++;
- switch (event->header.type) {
- case PERF_RECORD_MMAP:
- return 0;
- case PERF_RECORD_LOST:
- nr_lost_chunks++;
- nr_lost_events += event->lost.lost;
- return 0;
-
- case PERF_RECORD_COMM:
- return process_comm_event(event, offset, head);
+ nr_lost_chunks++;
+ nr_lost_events += event->lost.lost;
- case PERF_RECORD_EXIT ... PERF_RECORD_READ:
- return 0;
+ return 0;
+}
- case PERF_RECORD_SAMPLE:
- return process_sample_event(event, offset, head);
+static int sample_type_check(u64 type)
+{
+ sample_type = type;
- case PERF_RECORD_MAX:
- default:
+ if (!(sample_type & PERF_SAMPLE_RAW)) {
+ fprintf(stderr,
+ "No trace sample to read. Did you call perf record "
+ "without -R?");
return -1;
}
return 0;
}
+static struct perf_file_handler file_handler = {
+ .process_sample_event = process_sample_event,
+ .process_comm_event = event__process_comm,
+ .process_lost_event = process_lost_event,
+ .sample_type_check = sample_type_check,
+};
+
static int read_events(void)
{
- int ret, rc = EXIT_FAILURE;
- unsigned long offset = 0;
- unsigned long head = 0;
- struct stat perf_stat;
- event_t *event;
- uint32_t size;
- char *buf;
-
- trace_report();
- register_idle_thread(&threads, &last_match);
-
- input = open(input_name, O_RDONLY);
- if (input < 0) {
- perror("failed to open file");
- exit(-1);
- }
-
- ret = fstat(input, &perf_stat);
- if (ret < 0) {
- perror("failed to stat file");
- exit(-1);
- }
-
- if (!perf_stat.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- exit(0);
- }
- header = perf_header__read(input);
- head = header->data_offset;
- sample_type = perf_header__sample_type(header);
-
- if (!(sample_type & PERF_SAMPLE_RAW))
- die("No trace sample to read. Did you call perf record "
- "without -R?");
-
- if (load_kernel() < 0) {
- perror("failed to load kernel symbols");
- return EXIT_FAILURE;
- }
-
-remap:
- buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
- MAP_SHARED, input, offset);
- if (buf == MAP_FAILED) {
- perror("failed to mmap file");
- exit(-1);
- }
-
-more:
- event = (event_t *)(buf + head);
-
- size = event->header.size;
- if (!size)
- size = 8;
-
- if (head + event->header.size >= page_size * mmap_window) {
- unsigned long shift = page_size * (head / page_size);
- int res;
-
- res = munmap(buf, page_size * mmap_window);
- assert(res == 0);
-
- offset += shift;
- head -= shift;
- goto remap;
- }
-
- size = event->header.size;
-
-
- if (!size || process_event(event, offset, head) < 0) {
-
- /*
- * assume we lost track of the stream, check alignment, and
- * increment a single u64 in the hope to catch on again 'soon'.
- */
-
- if (unlikely(head & 7))
- head &= ~7ULL;
-
- size = 8;
- }
-
- head += size;
-
- if (offset + head < (unsigned long)perf_stat.st_size)
- goto more;
-
- rc = EXIT_SUCCESS;
- close(input);
+ register_idle_thread();
+ register_perf_file_handler(&file_handler);
- return rc;
+ return mmap_dispatch_perf_file(&header, input_name, 0, 0,
+ &event__cwdlen, &event__cwd);
}
static void print_bad_events(void)
@@ -1883,6 +1823,8 @@ static const struct option latency_options[] = {
"sort by key(s): runtime, switch, avg, max"),
OPT_BOOLEAN('v', "verbose", &verbose,
"be more verbose (show symbol address, etc)"),
+ OPT_INTEGER('C', "CPU", &profile_cpu,
+ "CPU to profile on"),
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
OPT_END()
@@ -1917,7 +1859,7 @@ static void setup_sorting(void)
free(str);
- sort_dimension__add((char *)"pid", &cmp_pid);
+ sort_dimension__add("pid", &cmp_pid);
}
static const char *record_args[] = {
@@ -1960,8 +1902,7 @@ static int __cmd_record(int argc, const char **argv)
int cmd_sched(int argc, const char **argv, const char *prefix __used)
{
- symbol__init();
- page_size = getpagesize();
+ symbol__init(0);
argc = parse_options(argc, argv, sched_options, sched_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 3db31e7bf173..c70d72003557 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -50,15 +50,17 @@
static struct perf_event_attr default_attrs[] = {
- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES},
- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
-
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_REFERENCES},
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_MISSES },
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES },
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
+
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_REFERENCES },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_MISSES },
};
@@ -125,6 +127,7 @@ struct stats event_res_stats[MAX_COUNTERS][3];
struct stats runtime_nsecs_stats;
struct stats walltime_nsecs_stats;
struct stats runtime_cycles_stats;
+struct stats runtime_branches_stats;
#define MATCH_EVENT(t, c, counter) \
(attrs[counter].type == PERF_TYPE_##t && \
@@ -235,6 +238,8 @@ static void read_counter(int counter)
update_stats(&runtime_nsecs_stats, count[0]);
if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter))
update_stats(&runtime_cycles_stats, count[0]);
+ if (MATCH_EVENT(HARDWARE, HW_BRANCH_INSTRUCTIONS, counter))
+ update_stats(&runtime_branches_stats, count[0]);
}
static int run_perf_stat(int argc __used, const char **argv)
@@ -352,7 +357,16 @@ static void abs_printout(int counter, double avg)
ratio = avg / total;
fprintf(stderr, " # %10.3f IPC ", ratio);
- } else {
+ } else if (MATCH_EVENT(HARDWARE, HW_BRANCH_MISSES, counter) &&
+ runtime_branches_stats.n != 0) {
+ total = avg_stats(&runtime_branches_stats);
+
+ if (total)
+ ratio = avg * 100 / total;
+
+ fprintf(stderr, " # %10.3f %% ", ratio);
+
+ } else if (runtime_nsecs_stats.n != 0) {
total = avg_stats(&runtime_nsecs_stats);
if (total)
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 702d8fe58fbc..cb58b6605fcc 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -29,14 +29,14 @@
#include "util/header.h"
#include "util/parse-options.h"
#include "util/parse-events.h"
+#include "util/event.h"
+#include "util/data_map.h"
#include "util/svghelper.h"
static char const *input_name = "perf.data";
static char const *output_name = "output.svg";
-static unsigned long page_size;
-static unsigned long mmap_window = 32;
static u64 sample_type;
static unsigned int numcpus;
@@ -49,8 +49,6 @@ static u64 first_time, last_time;
static int power_only;
-static struct perf_header *header;
-
struct per_pid;
struct per_pidcomm;
@@ -153,6 +151,17 @@ static struct wake_event *wake_events;
struct sample_wrapper *all_samples;
+
+struct process_filter;
+struct process_filter {
+ char *name;
+ int pid;
+ struct process_filter *next;
+};
+
+static struct process_filter *process_filter;
+
+
static struct per_pid *find_create_pid(int pid)
{
struct per_pid *cursor = all_data;
@@ -763,21 +772,42 @@ static void draw_wakeups(void)
c = p->all;
while (c) {
if (c->Y && c->start_time <= we->time && c->end_time >= we->time) {
- if (p->pid == we->waker) {
+ if (p->pid == we->waker && !from) {
from = c->Y;
- task_from = c->comm;
+ task_from = strdup(c->comm);
}
- if (p->pid == we->wakee) {
+ if (p->pid == we->wakee && !to) {
to = c->Y;
- task_to = c->comm;
+ task_to = strdup(c->comm);
}
}
c = c->next;
}
+ c = p->all;
+ while (c) {
+ if (p->pid == we->waker && !from) {
+ from = c->Y;
+ task_from = strdup(c->comm);
+ }
+ if (p->pid == we->wakee && !to) {
+ to = c->Y;
+ task_to = strdup(c->comm);
+ }
+ c = c->next;
+ }
}
p = p->next;
}
+ if (!task_from) {
+ task_from = malloc(40);
+ sprintf(task_from, "[%i]", we->waker);
+ }
+ if (!task_to) {
+ task_to = malloc(40);
+ sprintf(task_to, "[%i]", we->wakee);
+ }
+
if (we->waker == -1)
svg_interrupt(we->time, to);
else if (from && to && abs(from - to) == 1)
@@ -785,6 +815,9 @@ static void draw_wakeups(void)
else
svg_partial_wakeline(we->time, from, task_from, to, task_to);
we = we->next;
+
+ free(task_from);
+ free(task_to);
}
}
@@ -858,12 +891,89 @@ static void draw_process_bars(void)
}
}
+static void add_process_filter(const char *string)
+{
+ struct process_filter *filt;
+ int pid;
+
+ pid = strtoull(string, NULL, 10);
+ filt = malloc(sizeof(struct process_filter));
+ if (!filt)
+ return;
+
+ filt->name = strdup(string);
+ filt->pid = pid;
+ filt->next = process_filter;
+
+ process_filter = filt;
+}
+
+static int passes_filter(struct per_pid *p, struct per_pidcomm *c)
+{
+ struct process_filter *filt;
+ if (!process_filter)
+ return 1;
+
+ filt = process_filter;
+ while (filt) {
+ if (filt->pid && p->pid == filt->pid)
+ return 1;
+ if (strcmp(filt->name, c->comm) == 0)
+ return 1;
+ filt = filt->next;
+ }
+ return 0;
+}
+
+static int determine_display_tasks_filtered(void)
+{
+ struct per_pid *p;
+ struct per_pidcomm *c;
+ int count = 0;
+
+ p = all_data;
+ while (p) {
+ p->display = 0;
+ if (p->start_time == 1)
+ p->start_time = first_time;
+
+ /* no exit marker, task kept running to the end */
+ if (p->end_time == 0)
+ p->end_time = last_time;
+
+ c = p->all;
+
+ while (c) {
+ c->display = 0;
+
+ if (c->start_time == 1)
+ c->start_time = first_time;
+
+ if (passes_filter(p, c)) {
+ c->display = 1;
+ p->display = 1;
+ count++;
+ }
+
+ if (c->end_time == 0)
+ c->end_time = last_time;
+
+ c = c->next;
+ }
+ p = p->next;
+ }
+ return count;
+}
+
static int determine_display_tasks(u64 threshold)
{
struct per_pid *p;
struct per_pidcomm *c;
int count = 0;
+ if (process_filter)
+ return determine_display_tasks_filtered();
+
p = all_data;
while (p) {
p->display = 0;
@@ -933,36 +1043,6 @@ static void write_svg_file(const char *filename)
svg_close();
}
-static int
-process_event(event_t *event)
-{
-
- switch (event->header.type) {
-
- case PERF_RECORD_COMM:
- return process_comm_event(event);
- case PERF_RECORD_FORK:
- return process_fork_event(event);
- case PERF_RECORD_EXIT:
- return process_exit_event(event);
- case PERF_RECORD_SAMPLE:
- return queue_sample_event(event);
-
- /*
- * We dont process them right now but they are fine:
- */
- case PERF_RECORD_MMAP:
- case PERF_RECORD_THROTTLE:
- case PERF_RECORD_UNTHROTTLE:
- return 0;
-
- default:
- return -1;
- }
-
- return 0;
-}
-
static void process_samples(void)
{
struct sample_wrapper *cursor;
@@ -978,107 +1058,38 @@ static void process_samples(void)
}
}
-
-static int __cmd_timechart(void)
+static int sample_type_check(u64 type)
{
- int ret, rc = EXIT_FAILURE;
- unsigned long offset = 0;
- unsigned long head, shift;
- struct stat statbuf;
- event_t *event;
- uint32_t size;
- char *buf;
- int input;
-
- input = open(input_name, O_RDONLY);
- if (input < 0) {
- fprintf(stderr, " failed to open file: %s", input_name);
- if (!strcmp(input_name, "perf.data"))
- fprintf(stderr, " (try 'perf record' first)");
- fprintf(stderr, "\n");
- exit(-1);
- }
-
- ret = fstat(input, &statbuf);
- if (ret < 0) {
- perror("failed to stat file");
- exit(-1);
- }
-
- if (!statbuf.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- exit(0);
- }
-
- header = perf_header__read(input);
- head = header->data_offset;
-
- sample_type = perf_header__sample_type(header);
-
- shift = page_size * (head / page_size);
- offset += shift;
- head -= shift;
-
-remap:
- buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
- MAP_SHARED, input, offset);
- if (buf == MAP_FAILED) {
- perror("failed to mmap file");
- exit(-1);
- }
-
-more:
- event = (event_t *)(buf + head);
-
- size = event->header.size;
- if (!size)
- size = 8;
-
- if (head + event->header.size >= page_size * mmap_window) {
- int ret2;
-
- shift = page_size * (head / page_size);
-
- ret2 = munmap(buf, page_size * mmap_window);
- assert(ret2 == 0);
-
- offset += shift;
- head -= shift;
- goto remap;
- }
-
- size = event->header.size;
-
- if (!size || process_event(event) < 0) {
+ sample_type = type;
- printf("%p [%p]: skipping unknown header type: %d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->header.type);
-
- /*
- * assume we lost track of the stream, check alignment, and
- * increment a single u64 in the hope to catch on again 'soon'.
- */
-
- if (unlikely(head & 7))
- head &= ~7ULL;
-
- size = 8;
+ if (!(sample_type & PERF_SAMPLE_RAW)) {
+ fprintf(stderr, "No trace samples found in the file.\n"
+ "Have you used 'perf timechart record' to record it?\n");
+ return -1;
}
- head += size;
+ return 0;
+}
- if (offset + head >= header->data_offset + header->data_size)
- goto done;
+static struct perf_file_handler file_handler = {
+ .process_comm_event = process_comm_event,
+ .process_fork_event = process_fork_event,
+ .process_exit_event = process_exit_event,
+ .process_sample_event = queue_sample_event,
+ .sample_type_check = sample_type_check,
+};
- if (offset + head < (unsigned long)statbuf.st_size)
- goto more;
+static int __cmd_timechart(void)
+{
+ struct perf_header *header;
+ int ret;
-done:
- rc = EXIT_SUCCESS;
- close(input);
+ register_perf_file_handler(&file_handler);
+ ret = mmap_dispatch_perf_file(&header, input_name, 0, 0,
+ &event__cwdlen, &event__cwd);
+ if (ret)
+ return EXIT_FAILURE;
process_samples();
@@ -1088,9 +1099,10 @@ done:
write_svg_file(output_name);
- printf("Written %2.1f seconds of trace to %s.\n", (last_time - first_time) / 1000000000.0, output_name);
+ pr_info("Written %2.1f seconds of trace to %s.\n",
+ (last_time - first_time) / 1000000000.0, output_name);
- return rc;
+ return EXIT_SUCCESS;
}
static const char * const timechart_usage[] = {
@@ -1129,6 +1141,14 @@ static int __cmd_record(int argc, const char **argv)
return cmd_record(i, rec_argv, NULL);
}
+static int
+parse_process(const struct option *opt __used, const char *arg, int __used unset)
+{
+ if (arg)
+ add_process_filter(arg);
+ return 0;
+}
+
static const struct option options[] = {
OPT_STRING('i', "input", &input_name, "file",
"input file name"),
@@ -1136,17 +1156,18 @@ static const struct option options[] = {
"output file name"),
OPT_INTEGER('w', "width", &svg_page_width,
"page width"),
- OPT_BOOLEAN('p', "power-only", &power_only,
+ OPT_BOOLEAN('P', "power-only", &power_only,
"output power data only"),
+ OPT_CALLBACK('p', "process", NULL, "process",
+ "process selector. Pass a pid or process name.",
+ parse_process),
OPT_END()
};
int cmd_timechart(int argc, const char **argv, const char *prefix __used)
{
- symbol__init();
-
- page_size = getpagesize();
+ symbol__init(0);
argc = parse_options(argc, argv, options, timechart_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 37512e936235..e0a374d0e43a 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -22,6 +22,7 @@
#include "util/symbol.h"
#include "util/color.h"
+#include "util/thread.h"
#include "util/util.h"
#include <linux/rbtree.h>
#include "util/parse-options.h"
@@ -54,26 +55,31 @@
static int fd[MAX_NR_CPUS][MAX_COUNTERS];
-static int system_wide = 0;
+static int system_wide = 0;
-static int default_interval = 100000;
+static int default_interval = 0;
-static int count_filter = 5;
-static int print_entries = 15;
+static int count_filter = 5;
+static int print_entries;
-static int target_pid = -1;
-static int inherit = 0;
-static int profile_cpu = -1;
-static int nr_cpus = 0;
-static unsigned int realtime_prio = 0;
-static int group = 0;
+static int target_pid = -1;
+static int inherit = 0;
+static int profile_cpu = -1;
+static int nr_cpus = 0;
+static unsigned int realtime_prio = 0;
+static int group = 0;
static unsigned int page_size;
-static unsigned int mmap_pages = 16;
-static int freq = 0;
+static unsigned int mmap_pages = 16;
+static int freq = 1000; /* 1 KHz */
-static int delay_secs = 2;
-static int zero;
-static int dump_symtab;
+static int delay_secs = 2;
+static int zero = 0;
+static int dump_symtab = 0;
+
+static bool hide_kernel_symbols = false;
+static bool hide_user_symbols = false;
+static struct winsize winsize;
+struct symbol_conf symbol_conf;
/*
* Source
@@ -86,83 +92,126 @@ struct source_line {
struct source_line *next;
};
-static char *sym_filter = NULL;
-struct sym_entry *sym_filter_entry = NULL;
-static int sym_pcnt_filter = 5;
-static int sym_counter = 0;
-static int display_weighted = -1;
+static char *sym_filter = NULL;
+struct sym_entry *sym_filter_entry = NULL;
+static int sym_pcnt_filter = 5;
+static int sym_counter = 0;
+static int display_weighted = -1;
/*
* Symbols
*/
-static u64 min_ip;
-static u64 max_ip = -1ll;
+struct sym_entry_source {
+ struct source_line *source;
+ struct source_line *lines;
+ struct source_line **lines_tail;
+ pthread_mutex_t lock;
+};
struct sym_entry {
struct rb_node rb_node;
struct list_head node;
- unsigned long count[MAX_COUNTERS];
unsigned long snap_count;
double weight;
int skip;
- struct source_line *source;
- struct source_line *lines;
- struct source_line **lines_tail;
- pthread_mutex_t source_lock;
+ u16 name_len;
+ u8 origin;
+ struct map *map;
+ struct sym_entry_source *src;
+ unsigned long count[0];
};
/*
* Source functions
*/
+static inline struct symbol *sym_entry__symbol(struct sym_entry *self)
+{
+ return ((void *)self) + symbol_conf.priv_size;
+}
+
+static void get_term_dimensions(struct winsize *ws)
+{
+ char *s = getenv("LINES");
+
+ if (s != NULL) {
+ ws->ws_row = atoi(s);
+ s = getenv("COLUMNS");
+ if (s != NULL) {
+ ws->ws_col = atoi(s);
+ if (ws->ws_row && ws->ws_col)
+ return;
+ }
+ }
+#ifdef TIOCGWINSZ
+ if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
+ ws->ws_row && ws->ws_col)
+ return;
+#endif
+ ws->ws_row = 25;
+ ws->ws_col = 80;
+}
+
+static void update_print_entries(struct winsize *ws)
+{
+ print_entries = ws->ws_row;
+
+ if (print_entries > 9)
+ print_entries -= 9;
+}
+
+static void sig_winch_handler(int sig __used)
+{
+ get_term_dimensions(&winsize);
+ update_print_entries(&winsize);
+}
+
static void parse_source(struct sym_entry *syme)
{
struct symbol *sym;
- struct module *module;
- struct section *section = NULL;
+ struct sym_entry_source *source;
+ struct map *map;
FILE *file;
char command[PATH_MAX*2];
- const char *path = vmlinux_name;
- u64 start, end, len;
+ const char *path;
+ u64 len;
if (!syme)
return;
- if (syme->lines) {
- pthread_mutex_lock(&syme->source_lock);
- goto out_assign;
+ if (syme->src == NULL) {
+ syme->src = zalloc(sizeof(*source));
+ if (syme->src == NULL)
+ return;
+ pthread_mutex_init(&syme->src->lock, NULL);
}
- sym = (struct symbol *)(syme + 1);
- module = sym->module;
-
- if (module)
- path = module->path;
- if (!path)
- return;
-
- start = sym->obj_start;
- if (!start)
- start = sym->start;
+ source = syme->src;
- if (module) {
- section = module->sections->find_section(module->sections, ".text");
- if (section)
- start -= section->vma;
+ if (source->lines) {
+ pthread_mutex_lock(&source->lock);
+ goto out_assign;
}
- end = start + sym->end - sym->start + 1;
+ sym = sym_entry__symbol(syme);
+ map = syme->map;
+ path = map->dso->long_name;
+
len = sym->end - sym->start;
- sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", start, end, path);
+ sprintf(command,
+ "objdump --start-address=0x%016Lx "
+ "--stop-address=0x%016Lx -dS %s",
+ map->unmap_ip(map, sym->start),
+ map->unmap_ip(map, sym->end), path);
file = popen(command, "r");
if (!file)
return;
- pthread_mutex_lock(&syme->source_lock);
- syme->lines_tail = &syme->lines;
+ pthread_mutex_lock(&source->lock);
+ source->lines_tail = &source->lines;
while (!feof(file)) {
struct source_line *src;
size_t dummy = 0;
@@ -182,24 +231,22 @@ static void parse_source(struct sym_entry *syme)
*c = 0;
src->next = NULL;
- *syme->lines_tail = src;
- syme->lines_tail = &src->next;
+ *source->lines_tail = src;
+ source->lines_tail = &src->next;
if (strlen(src->line)>8 && src->line[8] == ':') {
src->eip = strtoull(src->line, NULL, 16);
- if (section)
- src->eip += section->vma;
+ src->eip = map->unmap_ip(map, src->eip);
}
if (strlen(src->line)>8 && src->line[16] == ':') {
src->eip = strtoull(src->line, NULL, 16);
- if (section)
- src->eip += section->vma;
+ src->eip = map->unmap_ip(map, src->eip);
}
}
pclose(file);
out_assign:
sym_filter_entry = syme;
- pthread_mutex_unlock(&syme->source_lock);
+ pthread_mutex_unlock(&source->lock);
}
static void __zero_source_counters(struct sym_entry *syme)
@@ -207,7 +254,7 @@ static void __zero_source_counters(struct sym_entry *syme)
int i;
struct source_line *line;
- line = syme->lines;
+ line = syme->src->lines;
while (line) {
for (i = 0; i < nr_counters; i++)
line->count[i] = 0;
@@ -222,13 +269,13 @@ static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip)
if (syme != sym_filter_entry)
return;
- if (pthread_mutex_trylock(&syme->source_lock))
+ if (pthread_mutex_trylock(&syme->src->lock))
return;
- if (!syme->source)
+ if (syme->src == NULL || syme->src->source == NULL)
goto out_unlock;
- for (line = syme->lines; line; line = line->next) {
+ for (line = syme->src->lines; line; line = line->next) {
if (line->eip == ip) {
line->count[counter]++;
break;
@@ -237,32 +284,25 @@ static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip)
break;
}
out_unlock:
- pthread_mutex_unlock(&syme->source_lock);
+ pthread_mutex_unlock(&syme->src->lock);
}
static void lookup_sym_source(struct sym_entry *syme)
{
- struct symbol *symbol = (struct symbol *)(syme + 1);
+ struct symbol *symbol = sym_entry__symbol(syme);
struct source_line *line;
char pattern[PATH_MAX];
- char *idx;
sprintf(pattern, "<%s>:", symbol->name);
- if (symbol->module) {
- idx = strstr(pattern, "\t");
- if (idx)
- *idx = 0;
- }
-
- pthread_mutex_lock(&syme->source_lock);
- for (line = syme->lines; line; line = line->next) {
+ pthread_mutex_lock(&syme->src->lock);
+ for (line = syme->src->lines; line; line = line->next) {
if (strstr(line->line, pattern)) {
- syme->source = line;
+ syme->src->source = line;
break;
}
}
- pthread_mutex_unlock(&syme->source_lock);
+ pthread_mutex_unlock(&syme->src->lock);
}
static void show_lines(struct source_line *queue, int count, int total)
@@ -292,24 +332,24 @@ static void show_details(struct sym_entry *syme)
if (!syme)
return;
- if (!syme->source)
+ if (!syme->src->source)
lookup_sym_source(syme);
- if (!syme->source)
+ if (!syme->src->source)
return;
- symbol = (struct symbol *)(syme + 1);
+ symbol = sym_entry__symbol(syme);
printf("Showing %s for %s\n", event_name(sym_counter), symbol->name);
printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter);
- pthread_mutex_lock(&syme->source_lock);
- line = syme->source;
+ pthread_mutex_lock(&syme->src->lock);
+ line = syme->src->source;
while (line) {
total += line->count[sym_counter];
line = line->next;
}
- line = syme->source;
+ line = syme->src->source;
while (line) {
float pcnt = 0.0;
@@ -334,13 +374,13 @@ static void show_details(struct sym_entry *syme)
line->count[sym_counter] = zero ? 0 : line->count[sym_counter] * 7 / 8;
line = line->next;
}
- pthread_mutex_unlock(&syme->source_lock);
+ pthread_mutex_unlock(&syme->src->lock);
if (more)
printf("%d lines not displayed, maybe increase display entries [e]\n", more);
}
/*
- * Symbols will be added here in record_ip and will get out
+ * Symbols will be added here in event__process_sample and will get out
* after decayed.
*/
static LIST_HEAD(active_symbols);
@@ -411,6 +451,8 @@ static void print_sym_table(void)
struct sym_entry *syme, *n;
struct rb_root tmp = RB_ROOT;
struct rb_node *nd;
+ int sym_width = 0, dso_width = 0, max_dso_width;
+ const int win_width = winsize.ws_col - 1;
samples = userspace_samples = 0;
@@ -422,6 +464,14 @@ static void print_sym_table(void)
list_for_each_entry_safe_from(syme, n, &active_symbols, node) {
syme->snap_count = syme->count[snap];
if (syme->snap_count != 0) {
+
+ if ((hide_user_symbols &&
+ syme->origin == PERF_RECORD_MISC_USER) ||
+ (hide_kernel_symbols &&
+ syme->origin == PERF_RECORD_MISC_KERNEL)) {
+ list_remove_active_sym(syme);
+ continue;
+ }
syme->weight = sym_weight(syme);
rb_insert_active_sym(&tmp, syme);
sum_ksamples += syme->snap_count;
@@ -434,8 +484,7 @@ static void print_sym_table(void)
puts(CONSOLE_CLEAR);
- printf(
-"------------------------------------------------------------------------------\n");
+ printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
printf( " PerfTop:%8.0f irqs/sec kernel:%4.1f%% [",
samples_per_sec,
100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec)));
@@ -473,33 +522,57 @@ static void print_sym_table(void)
printf(", %d CPUs)\n", nr_cpus);
}
- printf("------------------------------------------------------------------------------\n\n");
+ printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
if (sym_filter_entry) {
show_details(sym_filter_entry);
return;
}
+ /*
+ * Find the longest symbol name that will be displayed
+ */
+ for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
+ syme = rb_entry(nd, struct sym_entry, rb_node);
+ if (++printed > print_entries ||
+ (int)syme->snap_count < count_filter)
+ continue;
+
+ if (syme->map->dso->long_name_len > dso_width)
+ dso_width = syme->map->dso->long_name_len;
+
+ if (syme->name_len > sym_width)
+ sym_width = syme->name_len;
+ }
+
+ printed = 0;
+
+ max_dso_width = winsize.ws_col - sym_width - 29;
+ if (dso_width > max_dso_width)
+ dso_width = max_dso_width;
+ putchar('\n');
if (nr_counters == 1)
- printf(" samples pcnt");
+ printf(" samples pcnt");
else
- printf(" weight samples pcnt");
+ printf(" weight samples pcnt");
if (verbose)
printf(" RIP ");
- printf(" kernel function\n");
- printf(" %s _______ _____",
+ printf(" %-*.*s DSO\n", sym_width, sym_width, "function");
+ printf(" %s _______ _____",
nr_counters == 1 ? " " : "______");
if (verbose)
- printf(" ________________");
- printf(" _______________\n\n");
+ printf(" ________________");
+ printf(" %-*.*s", sym_width, sym_width, graph_line);
+ printf(" %-*.*s", dso_width, dso_width, graph_line);
+ puts("\n");
for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
struct symbol *sym;
double pcnt;
syme = rb_entry(nd, struct sym_entry, rb_node);
- sym = (struct symbol *)(syme + 1);
+ sym = sym_entry__symbol(syme);
if (++printed > print_entries || (int)syme->snap_count < count_filter)
continue;
@@ -508,17 +581,18 @@ static void print_sym_table(void)
sum_ksamples));
if (nr_counters == 1 || !display_weighted)
- printf("%20.2f - ", syme->weight);
+ printf("%20.2f ", syme->weight);
else
- printf("%9.1f %10ld - ", syme->weight, syme->snap_count);
+ printf("%9.1f %10ld ", syme->weight, syme->snap_count);
percent_color_fprintf(stdout, "%4.1f%%", pcnt);
if (verbose)
- printf(" - %016llx", sym->start);
- printf(" : %s", sym->name);
- if (sym->module)
- printf("\t[%s]", sym->module->name);
- printf("\n");
+ printf(" %016llx", sym->start);
+ printf(" %-*.*s", sym_width, sym_width, sym->name);
+ printf(" %-*.*s\n", dso_width, dso_width,
+ dso_width >= syme->map->dso->long_name_len ?
+ syme->map->dso->long_name :
+ syme->map->dso->short_name);
}
}
@@ -565,10 +639,10 @@ static void prompt_symbol(struct sym_entry **target, const char *msg)
/* zero counters of active symbol */
if (syme) {
- pthread_mutex_lock(&syme->source_lock);
+ pthread_mutex_lock(&syme->src->lock);
__zero_source_counters(syme);
*target = NULL;
- pthread_mutex_unlock(&syme->source_lock);
+ pthread_mutex_unlock(&syme->src->lock);
}
fprintf(stdout, "\n%s: ", msg);
@@ -584,7 +658,7 @@ static void prompt_symbol(struct sym_entry **target, const char *msg)
pthread_mutex_unlock(&active_symbols_lock);
list_for_each_entry_safe_from(syme, n, &active_symbols, node) {
- struct symbol *sym = (struct symbol *)(syme + 1);
+ struct symbol *sym = sym_entry__symbol(syme);
if (!strcmp(buf, sym->name)) {
found = syme;
@@ -608,7 +682,7 @@ static void print_mapped_keys(void)
char *name = NULL;
if (sym_filter_entry) {
- struct symbol *sym = (struct symbol *)(sym_filter_entry+1);
+ struct symbol *sym = sym_entry__symbol(sym_filter_entry);
name = sym->name;
}
@@ -621,7 +695,7 @@ static void print_mapped_keys(void)
fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter);
- if (vmlinux_name) {
+ if (symbol_conf.vmlinux_name) {
fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter);
fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL");
fprintf(stdout, "\t[S] stop annotation.\n");
@@ -630,6 +704,12 @@ static void print_mapped_keys(void)
if (nr_counters > 1)
fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0);
+ fprintf(stdout,
+ "\t[K] hide kernel_symbols symbols. \t(%s)\n",
+ hide_kernel_symbols ? "yes" : "no");
+ fprintf(stdout,
+ "\t[U] hide user symbols. \t(%s)\n",
+ hide_user_symbols ? "yes" : "no");
fprintf(stdout, "\t[z] toggle sample zeroing. \t(%d)\n", zero ? 1 : 0);
fprintf(stdout, "\t[qQ] quit.\n");
}
@@ -643,6 +723,8 @@ static int key_mapped(int c)
case 'z':
case 'q':
case 'Q':
+ case 'K':
+ case 'U':
return 1;
case 'E':
case 'w':
@@ -650,7 +732,7 @@ static int key_mapped(int c)
case 'F':
case 's':
case 'S':
- return vmlinux_name ? 1 : 0;
+ return symbol_conf.vmlinux_name ? 1 : 0;
default:
break;
}
@@ -686,9 +768,16 @@ static void handle_keypress(int c)
switch (c) {
case 'd':
prompt_integer(&delay_secs, "Enter display delay");
+ if (delay_secs < 1)
+ delay_secs = 1;
break;
case 'e':
prompt_integer(&print_entries, "Enter display entries (lines)");
+ if (print_entries == 0) {
+ sig_winch_handler(SIGWINCH);
+ signal(SIGWINCH, sig_winch_handler);
+ } else
+ signal(SIGWINCH, SIG_DFL);
break;
case 'E':
if (nr_counters > 1) {
@@ -713,9 +802,14 @@ static void handle_keypress(int c)
case 'F':
prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)");
break;
+ case 'K':
+ hide_kernel_symbols = !hide_kernel_symbols;
+ break;
case 'q':
case 'Q':
printf("exiting.\n");
+ if (dump_symtab)
+ dsos__fprintf(stderr);
exit(0);
case 's':
prompt_symbol(&sym_filter_entry, "Enter details symbol");
@@ -726,12 +820,15 @@ static void handle_keypress(int c)
else {
struct sym_entry *syme = sym_filter_entry;
- pthread_mutex_lock(&syme->source_lock);
+ pthread_mutex_lock(&syme->src->lock);
sym_filter_entry = NULL;
__zero_source_counters(syme);
- pthread_mutex_unlock(&syme->source_lock);
+ pthread_mutex_unlock(&syme->src->lock);
}
break;
+ case 'U':
+ hide_user_symbols = !hide_user_symbols;
+ break;
case 'w':
display_weighted = ~display_weighted;
break;
@@ -788,7 +885,7 @@ static const char *skip_symbols[] = {
NULL
};
-static int symbol_filter(struct dso *self, struct symbol *sym)
+static int symbol_filter(struct map *map, struct symbol *sym)
{
struct sym_entry *syme;
const char *name = sym->name;
@@ -810,8 +907,9 @@ static int symbol_filter(struct dso *self, struct symbol *sym)
strstr(name, "_text_end"))
return 1;
- syme = dso__sym_priv(self, sym);
- pthread_mutex_init(&syme->source_lock, NULL);
+ syme = symbol__priv(sym);
+ syme->map = map;
+ syme->src = NULL;
if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter))
sym_filter_entry = syme;
@@ -822,75 +920,65 @@ static int symbol_filter(struct dso *self, struct symbol *sym)
}
}
- return 0;
-}
-
-static int parse_symbols(void)
-{
- struct rb_node *node;
- struct symbol *sym;
- int use_modules = vmlinux_name ? 1 : 0;
-
- kernel_dso = dso__new("[kernel]", sizeof(struct sym_entry));
- if (kernel_dso == NULL)
- return -1;
-
- if (dso__load_kernel(kernel_dso, vmlinux_name, symbol_filter, verbose, use_modules) <= 0)
- goto out_delete_dso;
-
- node = rb_first(&kernel_dso->syms);
- sym = rb_entry(node, struct symbol, rb_node);
- min_ip = sym->start;
-
- node = rb_last(&kernel_dso->syms);
- sym = rb_entry(node, struct symbol, rb_node);
- max_ip = sym->end;
-
- if (dump_symtab)
- dso__fprintf(kernel_dso, stderr);
+ if (!syme->skip)
+ syme->name_len = strlen(sym->name);
return 0;
-
-out_delete_dso:
- dso__delete(kernel_dso);
- kernel_dso = NULL;
- return -1;
}
-/*
- * Binary search in the histogram table and record the hit:
- */
-static void record_ip(u64 ip, int counter)
+static void event__process_sample(const event_t *self, int counter)
{
- struct symbol *sym = dso__find_symbol(kernel_dso, ip);
-
- if (sym != NULL) {
- struct sym_entry *syme = dso__sym_priv(kernel_dso, sym);
-
- if (!syme->skip) {
- syme->count[counter]++;
- record_precise_ip(syme, counter, ip);
- pthread_mutex_lock(&active_symbols_lock);
- if (list_empty(&syme->node) || !syme->node.next)
- __list_insert_active_sym(syme);
- pthread_mutex_unlock(&active_symbols_lock);
+ u64 ip = self->ip.ip;
+ struct sym_entry *syme;
+ struct addr_location al;
+ u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+ switch (origin) {
+ case PERF_RECORD_MISC_USER:
+ if (hide_user_symbols)
return;
- }
+ break;
+ case PERF_RECORD_MISC_KERNEL:
+ if (hide_kernel_symbols)
+ return;
+ break;
+ default:
+ return;
}
- samples--;
+ if (event__preprocess_sample(self, &al, symbol_filter) < 0 ||
+ al.sym == NULL)
+ return;
+
+ syme = symbol__priv(al.sym);
+ if (!syme->skip) {
+ syme->count[counter]++;
+ syme->origin = origin;
+ record_precise_ip(syme, counter, ip);
+ pthread_mutex_lock(&active_symbols_lock);
+ if (list_empty(&syme->node) || !syme->node.next)
+ __list_insert_active_sym(syme);
+ pthread_mutex_unlock(&active_symbols_lock);
+ if (origin == PERF_RECORD_MISC_USER)
+ ++userspace_samples;
+ ++samples;
+ }
}
-static void process_event(u64 ip, int counter, int user)
+static int event__process(event_t *event)
{
- samples++;
-
- if (user) {
- userspace_samples++;
- return;
+ switch (event->header.type) {
+ case PERF_RECORD_COMM:
+ event__process_comm(event);
+ break;
+ case PERF_RECORD_MMAP:
+ event__process_mmap(event);
+ break;
+ default:
+ break;
}
- record_ip(ip, counter);
+ return 0;
}
struct mmap_data {
@@ -911,8 +999,6 @@ static unsigned int mmap_read_head(struct mmap_data *md)
return head;
}
-struct timeval last_read, this_read;
-
static void mmap_read_counter(struct mmap_data *md)
{
unsigned int head = mmap_read_head(md);
@@ -920,8 +1006,6 @@ static void mmap_read_counter(struct mmap_data *md)
unsigned char *data = md->base + page_size;
int diff;
- gettimeofday(&this_read, NULL);
-
/*
* If we're further behind than half the buffer, there's a chance
* the writer will bite our tail and mess up the samples under us.
@@ -932,14 +1016,7 @@ static void mmap_read_counter(struct mmap_data *md)
*/
diff = head - old;
if (diff > md->mask / 2 || diff < 0) {
- struct timeval iv;
- unsigned long msecs;
-
- timersub(&this_read, &last_read, &iv);
- msecs = iv.tv_sec*1000 + iv.tv_usec/1000;
-
- fprintf(stderr, "WARNING: failed to keep up with mmap data."
- " Last read %lu msecs ago.\n", msecs);
+ fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
/*
* head points to a known good entry, start there.
@@ -947,8 +1024,6 @@ static void mmap_read_counter(struct mmap_data *md)
old = head;
}
- last_read = this_read;
-
for (; old != head;) {
event_t *event = (event_t *)&data[old & md->mask];
@@ -976,13 +1051,11 @@ static void mmap_read_counter(struct mmap_data *md)
event = &event_copy;
}
+ if (event->header.type == PERF_RECORD_SAMPLE)
+ event__process_sample(event, md->counter);
+ else
+ event__process(event);
old += size;
-
- if (event->header.type == PERF_RECORD_SAMPLE) {
- int user =
- (event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK) == PERF_RECORD_MISC_USER;
- process_event(event->ip.ip, md->counter, user);
- }
}
md->prev = old;
@@ -1016,8 +1089,15 @@ static void start_counter(int i, int counter)
attr = attrs + counter;
attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
- attr->freq = freq;
+
+ if (freq) {
+ attr->sample_type |= PERF_SAMPLE_PERIOD;
+ attr->freq = 1;
+ attr->sample_freq = freq;
+ }
+
attr->inherit = (cpu < 0) && inherit;
+ attr->mmap = 1;
try_again:
fd[i][counter] = sys_perf_event_open(attr, target_pid, cpu, group_fd, 0);
@@ -1025,7 +1105,7 @@ try_again:
if (fd[i][counter] < 0) {
int err = errno;
- if (err == EPERM)
+ if (err == EPERM || err == EACCES)
die("No permission - are you root?\n");
/*
* If it's cycles then fall back to hrtimer
@@ -1076,6 +1156,11 @@ static int __cmd_top(void)
int i, counter;
int ret;
+ if (target_pid != -1)
+ event__synthesize_thread(target_pid, event__process);
+ else
+ event__synthesize_threads(event__process);
+
for (i = 0; i < nr_cpus; i++) {
group_fd = -1;
for (counter = 0; counter < nr_counters; counter++)
@@ -1131,7 +1216,10 @@ static const struct option options[] = {
"system-wide collection from all CPUs"),
OPT_INTEGER('C', "CPU", &profile_cpu,
"CPU to profile on"),
- OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"),
+ OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
+ "file", "vmlinux pathname"),
+ OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols,
+ "hide kernel symbols"),
OPT_INTEGER('m', "mmap-pages", &mmap_pages,
"number of mmap data pages"),
OPT_INTEGER('r', "realtime", &realtime_prio,
@@ -1154,6 +1242,8 @@ static const struct option options[] = {
"profile at this frequency"),
OPT_INTEGER('E', "entries", &print_entries,
"display this many functions"),
+ OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols,
+ "hide user symbols"),
OPT_BOOLEAN('v', "verbose", &verbose,
"be more verbose (show counter open errors, etc)"),
OPT_END()
@@ -1163,19 +1253,12 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
{
int counter;
- symbol__init();
-
page_size = sysconf(_SC_PAGE_SIZE);
argc = parse_options(argc, argv, options, top_usage, 0);
if (argc)
usage_with_options(top_usage, options);
- if (freq) {
- default_interval = freq;
- freq = 1;
- }
-
/* CPU and PID are mutually exclusive */
if (target_pid != -1 && profile_cpu != -1) {
printf("WARNING: PID switch overriding CPU\n");
@@ -1186,13 +1269,31 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
if (!nr_counters)
nr_counters = 1;
+ symbol_conf.priv_size = (sizeof(struct sym_entry) +
+ (nr_counters + 1) * sizeof(unsigned long));
+ if (symbol_conf.vmlinux_name == NULL)
+ symbol_conf.try_vmlinux_path = true;
+ if (symbol__init(&symbol_conf) < 0)
+ return -1;
+
if (delay_secs < 1)
delay_secs = 1;
- parse_symbols();
parse_source(sym_filter_entry);
/*
+ * User specified count overrides default frequency.
+ */
+ if (default_interval)
+ freq = 0;
+ else if (freq) {
+ default_interval = freq;
+ } else {
+ fprintf(stderr, "frequency and count are zero, aborting\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /*
* Fill in the ones not specifically initialized via -c:
*/
for (counter = 0; counter < nr_counters; counter++) {
@@ -1209,5 +1310,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
if (target_pid != -1 || profile_cpu != -1)
nr_cpus = 1;
+ get_term_dimensions(&winsize);
+ if (print_entries == 0) {
+ update_print_entries(&winsize);
+ signal(SIGWINCH, sig_winch_handler);
+ }
+
return __cmd_top();
}
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 0c5e4f72f2ba..abb914aa7be6 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -5,66 +5,73 @@
#include "util/symbol.h"
#include "util/thread.h"
#include "util/header.h"
+#include "util/exec_cmd.h"
+#include "util/trace-event.h"
-#include "util/parse-options.h"
+static char const *script_name;
+static char const *generate_script_lang;
-#include "perf.h"
-#include "util/debug.h"
+static int default_start_script(const char *script __attribute((unused)))
+{
+ return 0;
+}
-#include "util/trace-event.h"
+static int default_stop_script(void)
+{
+ return 0;
+}
-static char const *input_name = "perf.data";
-static int input;
-static unsigned long page_size;
-static unsigned long mmap_window = 32;
+static int default_generate_script(const char *outfile __attribute ((unused)))
+{
+ return 0;
+}
-static unsigned long total = 0;
-static unsigned long total_comm = 0;
+static struct scripting_ops default_scripting_ops = {
+ .start_script = default_start_script,
+ .stop_script = default_stop_script,
+ .process_event = print_event,
+ .generate_script = default_generate_script,
+};
+
+static struct scripting_ops *scripting_ops;
-static struct rb_root threads;
-static struct thread *last_match;
+static void setup_scripting(void)
+{
+ /* make sure PERF_EXEC_PATH is set for scripts */
+ perf_set_argv_exec_path(perf_exec_path());
-static struct perf_header *header;
-static u64 sample_type;
+ setup_perl_scripting();
+ scripting_ops = &default_scripting_ops;
+}
-static int
-process_comm_event(event_t *event, unsigned long offset, unsigned long head)
+static int cleanup_scripting(void)
{
- struct thread *thread;
+ return scripting_ops->stop_script();
+}
- thread = threads__findnew(event->comm.pid, &threads, &last_match);
+#include "util/parse-options.h"
- dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->comm.comm, event->comm.pid);
+#include "perf.h"
+#include "util/debug.h"
- if (thread == NULL ||
- thread__set_comm(thread, event->comm.comm)) {
- dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
- return -1;
- }
- total_comm++;
+#include "util/trace-event.h"
+#include "util/data_map.h"
+#include "util/exec_cmd.h"
- return 0;
-}
+static char const *input_name = "perf.data";
-static int
-process_sample_event(event_t *event, unsigned long offset, unsigned long head)
+static struct perf_header *header;
+static u64 sample_type;
+
+static int process_sample_event(event_t *event)
{
- char level;
- int show = 0;
- struct dso *dso = NULL;
- struct thread *thread;
u64 ip = event->ip.ip;
u64 timestamp = -1;
u32 cpu = -1;
u64 period = 1;
void *more_data = event->ip.__more_data;
- int cpumode;
-
- thread = threads__findnew(event->ip.pid, &threads, &last_match);
+ struct thread *thread = threads__findnew(event->ip.pid);
if (sample_type & PERF_SAMPLE_TIME) {
timestamp = *(u64 *)more_data;
@@ -82,45 +89,19 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
more_data += sizeof(u64);
}
- dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
+ dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
event->header.misc,
event->ip.pid, event->ip.tid,
(void *)(long)ip,
(long long)period);
- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
-
if (thread == NULL) {
- eprintf("problem processing %d event, skipping it.\n",
- event->header.type);
+ pr_debug("problem processing %d event, skipping it.\n",
+ event->header.type);
return -1;
}
- cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
-
- if (cpumode == PERF_RECORD_MISC_KERNEL) {
- show = SHOW_KERNEL;
- level = 'k';
-
- dso = kernel_dso;
-
- dump_printf(" ...... dso: %s\n", dso->name);
-
- } else if (cpumode == PERF_RECORD_MISC_USER) {
-
- show = SHOW_USER;
- level = '.';
-
- } else {
- show = SHOW_HV;
- level = 'H';
-
- dso = hypervisor_dso;
-
- dump_printf(" ...... dso: [hypervisor]\n");
- }
+ dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
if (sample_type & PERF_SAMPLE_RAW) {
struct {
@@ -133,128 +114,189 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
* field, although it should be the same than this perf
* event pid
*/
- print_event(cpu, raw->data, raw->size, timestamp, thread->comm);
+ scripting_ops->process_event(cpu, raw->data, raw->size,
+ timestamp, thread->comm);
}
- total += period;
+ event__stats.total += period;
return 0;
}
-static int
-process_event(event_t *event, unsigned long offset, unsigned long head)
+static int sample_type_check(u64 type)
{
- trace_event(event);
-
- switch (event->header.type) {
- case PERF_RECORD_MMAP ... PERF_RECORD_LOST:
- return 0;
-
- case PERF_RECORD_COMM:
- return process_comm_event(event, offset, head);
-
- case PERF_RECORD_EXIT ... PERF_RECORD_READ:
- return 0;
-
- case PERF_RECORD_SAMPLE:
- return process_sample_event(event, offset, head);
+ sample_type = type;
- case PERF_RECORD_MAX:
- default:
+ if (!(sample_type & PERF_SAMPLE_RAW)) {
+ fprintf(stderr,
+ "No trace sample to read. Did you call perf record "
+ "without -R?");
return -1;
}
return 0;
}
+static struct perf_file_handler file_handler = {
+ .process_sample_event = process_sample_event,
+ .process_comm_event = event__process_comm,
+ .sample_type_check = sample_type_check,
+};
+
static int __cmd_trace(void)
{
- int ret, rc = EXIT_FAILURE;
- unsigned long offset = 0;
- unsigned long head = 0;
- struct stat perf_stat;
- event_t *event;
- uint32_t size;
- char *buf;
-
- trace_report();
- register_idle_thread(&threads, &last_match);
-
- input = open(input_name, O_RDONLY);
- if (input < 0) {
- perror("failed to open file");
- exit(-1);
- }
+ register_idle_thread();
+ register_perf_file_handler(&file_handler);
- ret = fstat(input, &perf_stat);
- if (ret < 0) {
- perror("failed to stat file");
- exit(-1);
- }
+ return mmap_dispatch_perf_file(&header, input_name,
+ 0, 0, &event__cwdlen, &event__cwd);
+}
- if (!perf_stat.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- exit(0);
- }
- header = perf_header__read(input);
- head = header->data_offset;
- sample_type = perf_header__sample_type(header);
+struct script_spec {
+ struct list_head node;
+ struct scripting_ops *ops;
+ char spec[0];
+};
- if (!(sample_type & PERF_SAMPLE_RAW))
- die("No trace sample to read. Did you call perf record "
- "without -R?");
+LIST_HEAD(script_specs);
- if (load_kernel() < 0) {
- perror("failed to load kernel symbols");
- return EXIT_FAILURE;
- }
+static struct script_spec *script_spec__new(const char *spec,
+ struct scripting_ops *ops)
+{
+ struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
-remap:
- buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
- MAP_SHARED, input, offset);
- if (buf == MAP_FAILED) {
- perror("failed to mmap file");
- exit(-1);
+ if (s != NULL) {
+ strcpy(s->spec, spec);
+ s->ops = ops;
}
-more:
- event = (event_t *)(buf + head);
+ return s;
+}
- if (head + event->header.size >= page_size * mmap_window) {
- unsigned long shift = page_size * (head / page_size);
- int res;
+static void script_spec__delete(struct script_spec *s)
+{
+ free(s->spec);
+ free(s);
+}
- res = munmap(buf, page_size * mmap_window);
- assert(res == 0);
+static void script_spec__add(struct script_spec *s)
+{
+ list_add_tail(&s->node, &script_specs);
+}
- offset += shift;
- head -= shift;
- goto remap;
- }
+static struct script_spec *script_spec__find(const char *spec)
+{
+ struct script_spec *s;
- size = event->header.size;
+ list_for_each_entry(s, &script_specs, node)
+ if (strcasecmp(s->spec, spec) == 0)
+ return s;
+ return NULL;
+}
- if (!size || process_event(event, offset, head) < 0) {
+static struct script_spec *script_spec__findnew(const char *spec,
+ struct scripting_ops *ops)
+{
+ struct script_spec *s = script_spec__find(spec);
- /*
- * assume we lost track of the stream, check alignment, and
- * increment a single u64 in the hope to catch on again 'soon'.
- */
+ if (s)
+ return s;
- if (unlikely(head & 7))
- head &= ~7ULL;
+ s = script_spec__new(spec, ops);
+ if (!s)
+ goto out_delete_spec;
- size = 8;
- }
+ script_spec__add(s);
+
+ return s;
- head += size;
+out_delete_spec:
+ script_spec__delete(s);
+
+ return NULL;
+}
- if (offset + head < (unsigned long)perf_stat.st_size)
- goto more;
+int script_spec_register(const char *spec, struct scripting_ops *ops)
+{
+ struct script_spec *s;
+
+ s = script_spec__find(spec);
+ if (s)
+ return -1;
- rc = EXIT_SUCCESS;
- close(input);
+ s = script_spec__findnew(spec, ops);
+ if (!s)
+ return -1;
+
+ return 0;
+}
+
+static struct scripting_ops *script_spec__lookup(const char *spec)
+{
+ struct script_spec *s = script_spec__find(spec);
+ if (!s)
+ return NULL;
- return rc;
+ return s->ops;
+}
+
+static void list_available_languages(void)
+{
+ struct script_spec *s;
+
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Scripting language extensions (used in "
+ "perf trace -s [spec:]script.[spec]):\n\n");
+
+ list_for_each_entry(s, &script_specs, node)
+ fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name);
+
+ fprintf(stderr, "\n");
+}
+
+static int parse_scriptname(const struct option *opt __used,
+ const char *str, int unset __used)
+{
+ char spec[PATH_MAX];
+ const char *script, *ext;
+ int len;
+
+ if (strcmp(str, "list") == 0) {
+ list_available_languages();
+ return 0;
+ }
+
+ script = strchr(str, ':');
+ if (script) {
+ len = script - str;
+ if (len >= PATH_MAX) {
+ fprintf(stderr, "invalid language specifier");
+ return -1;
+ }
+ strncpy(spec, str, len);
+ spec[len] = '\0';
+ scripting_ops = script_spec__lookup(spec);
+ if (!scripting_ops) {
+ fprintf(stderr, "invalid language specifier");
+ return -1;
+ }
+ script++;
+ } else {
+ script = str;
+ ext = strchr(script, '.');
+ if (!ext) {
+ fprintf(stderr, "invalid script extension");
+ return -1;
+ }
+ scripting_ops = script_spec__lookup(++ext);
+ if (!scripting_ops) {
+ fprintf(stderr, "invalid script extension");
+ return -1;
+ }
+ }
+
+ script_name = strdup(script);
+
+ return 0;
}
static const char * const annotate_usage[] = {
@@ -267,13 +309,24 @@ static const struct option options[] = {
"dump raw trace in ASCII"),
OPT_BOOLEAN('v', "verbose", &verbose,
"be more verbose (show symbol address, etc)"),
+ OPT_BOOLEAN('l', "latency", &latency_format,
+ "show latency attributes (irqs/preemption disabled, etc)"),
+ OPT_CALLBACK('s', "script", NULL, "name",
+ "script file name (lang:script name, script name, or *)",
+ parse_scriptname),
+ OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
+ "generate perf-trace.xx script in specified language"),
+
OPT_END()
};
int cmd_trace(int argc, const char **argv, const char *prefix __used)
{
- symbol__init();
- page_size = getpagesize();
+ int err;
+
+ symbol__init(0);
+
+ setup_scripting();
argc = parse_options(argc, argv, options, annotate_usage, 0);
if (argc) {
@@ -287,5 +340,50 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
setup_pager();
- return __cmd_trace();
+ if (generate_script_lang) {
+ struct stat perf_stat;
+
+ int input = open(input_name, O_RDONLY);
+ if (input < 0) {
+ perror("failed to open file");
+ exit(-1);
+ }
+
+ err = fstat(input, &perf_stat);
+ if (err < 0) {
+ perror("failed to stat file");
+ exit(-1);
+ }
+
+ if (!perf_stat.st_size) {
+ fprintf(stderr, "zero-sized file, nothing to do!\n");
+ exit(0);
+ }
+
+ scripting_ops = script_spec__lookup(generate_script_lang);
+ if (!scripting_ops) {
+ fprintf(stderr, "invalid language specifier");
+ return -1;
+ }
+
+ header = perf_header__new();
+ if (header == NULL)
+ return -1;
+
+ perf_header__read(header, input);
+ err = scripting_ops->generate_script("perf-trace");
+ goto out;
+ }
+
+ if (script_name) {
+ err = scripting_ops->start_script(script_name);
+ if (err)
+ goto out;
+ }
+
+ err = __cmd_trace();
+
+ cleanup_scripting();
+out:
+ return err;
}
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index e11d8d231c3b..a3d8bf65f26c 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -15,6 +15,8 @@ extern int read_line_with_nul(char *buf, int size, FILE *file);
extern int check_pager_config(const char *cmd);
extern int cmd_annotate(int argc, const char **argv, const char *prefix);
+extern int cmd_bench(int argc, const char **argv, const char *prefix);
+extern int cmd_buildid_list(int argc, const char **argv, const char *prefix);
extern int cmd_help(int argc, const char **argv, const char *prefix);
extern int cmd_sched(int argc, const char **argv, const char *prefix);
extern int cmd_list(int argc, const char **argv, const char *prefix);
@@ -25,5 +27,7 @@ extern int cmd_timechart(int argc, const char **argv, const char *prefix);
extern int cmd_top(int argc, const char **argv, const char *prefix);
extern int cmd_trace(int argc, const char **argv, const char *prefix);
extern int cmd_version(int argc, const char **argv, const char *prefix);
+extern int cmd_probe(int argc, const char **argv, const char *prefix);
+extern int cmd_kmem(int argc, const char **argv, const char *prefix);
#endif
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index 00326e230d87..02b09ea17a3e 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -3,6 +3,8 @@
# command name category [deprecated] [common]
#
perf-annotate mainporcelain common
+perf-bench mainporcelain common
+perf-buildid-list mainporcelain common
perf-list mainporcelain common
perf-sched mainporcelain common
perf-record mainporcelain common
@@ -11,3 +13,5 @@ perf-stat mainporcelain common
perf-timechart mainporcelain common
perf-top mainporcelain common
perf-trace mainporcelain common
+perf-probe mainporcelain common
+perf-kmem mainporcelain common
diff --git a/tools/perf/design.txt b/tools/perf/design.txt
index fdd42a824c98..f000c30877ac 100644
--- a/tools/perf/design.txt
+++ b/tools/perf/design.txt
@@ -137,6 +137,8 @@ enum sw_event_ids {
PERF_COUNT_SW_CPU_MIGRATIONS = 4,
PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
+ PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
+ PERF_COUNT_SW_EMULATION_FAULTS = 8,
};
Counters of the type PERF_TYPE_TRACEPOINT are available when the ftrace event
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 19fc7feb9d59..cf64049bc9bd 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -14,6 +14,7 @@
#include "util/run-command.h"
#include "util/parse-events.h"
#include "util/string.h"
+#include "util/debugfs.h"
const char perf_usage_string[] =
"perf [--version] [--help] COMMAND [ARGS]";
@@ -89,8 +90,8 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
/*
* Check remaining flags.
*/
- if (!prefixcmp(cmd, "--exec-path")) {
- cmd += 11;
+ if (!prefixcmp(cmd, CMD_EXEC_PATH)) {
+ cmd += strlen(CMD_EXEC_PATH);
if (*cmd == '=')
perf_set_argv_exec_path(cmd + 1);
else {
@@ -117,8 +118,8 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
(*argv)++;
(*argc)--;
handled++;
- } else if (!prefixcmp(cmd, "--perf-dir=")) {
- setenv(PERF_DIR_ENVIRONMENT, cmd + 10, 1);
+ } else if (!prefixcmp(cmd, CMD_PERF_DIR)) {
+ setenv(PERF_DIR_ENVIRONMENT, cmd + strlen(CMD_PERF_DIR), 1);
if (envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--work-tree")) {
@@ -131,8 +132,8 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
*envchanged = 1;
(*argv)++;
(*argc)--;
- } else if (!prefixcmp(cmd, "--work-tree=")) {
- setenv(PERF_WORK_TREE_ENVIRONMENT, cmd + 12, 1);
+ } else if (!prefixcmp(cmd, CMD_WORK_TREE)) {
+ setenv(PERF_WORK_TREE_ENVIRONMENT, cmd + strlen(CMD_WORK_TREE), 1);
if (envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--debugfs-dir")) {
@@ -146,8 +147,8 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
*envchanged = 1;
(*argv)++;
(*argc)--;
- } else if (!prefixcmp(cmd, "--debugfs-dir=")) {
- strncpy(debugfs_mntpt, cmd + 14, MAXPATHLEN);
+ } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) {
+ strncpy(debugfs_mntpt, cmd + strlen(CMD_DEBUGFS_DIR), MAXPATHLEN);
debugfs_mntpt[MAXPATHLEN - 1] = '\0';
if (envchanged)
*envchanged = 1;
@@ -284,17 +285,21 @@ static void handle_internal_command(int argc, const char **argv)
{
const char *cmd = argv[0];
static struct cmd_struct commands[] = {
- { "help", cmd_help, 0 },
- { "list", cmd_list, 0 },
- { "record", cmd_record, 0 },
- { "report", cmd_report, 0 },
- { "stat", cmd_stat, 0 },
- { "timechart", cmd_timechart, 0 },
- { "top", cmd_top, 0 },
- { "annotate", cmd_annotate, 0 },
- { "version", cmd_version, 0 },
- { "trace", cmd_trace, 0 },
- { "sched", cmd_sched, 0 },
+ { "buildid-list", cmd_buildid_list, 0 },
+ { "help", cmd_help, 0 },
+ { "list", cmd_list, 0 },
+ { "record", cmd_record, 0 },
+ { "report", cmd_report, 0 },
+ { "bench", cmd_bench, 0 },
+ { "stat", cmd_stat, 0 },
+ { "timechart", cmd_timechart, 0 },
+ { "top", cmd_top, 0 },
+ { "annotate", cmd_annotate, 0 },
+ { "version", cmd_version, 0 },
+ { "trace", cmd_trace, 0 },
+ { "sched", cmd_sched, 0 },
+ { "probe", cmd_probe, 0 },
+ { "kmem", cmd_kmem, 0 },
};
unsigned int i;
static const char ext[] = STRIP_EXTENSION;
@@ -382,45 +387,12 @@ static int run_argv(int *argcp, const char ***argv)
/* mini /proc/mounts parser: searching for "^blah /mount/point debugfs" */
static void get_debugfs_mntpt(void)
{
- FILE *file;
- char fs_type[100];
- char debugfs[MAXPATHLEN];
+ const char *path = debugfs_find_mountpoint();
- /*
- * try the standard location
- */
- if (valid_debugfs_mount("/sys/kernel/debug/") == 0) {
- strcpy(debugfs_mntpt, "/sys/kernel/debug/");
- return;
- }
-
- /*
- * try the sane location
- */
- if (valid_debugfs_mount("/debug/") == 0) {
- strcpy(debugfs_mntpt, "/debug/");
- return;
- }
-
- /*
- * give up and parse /proc/mounts
- */
- file = fopen("/proc/mounts", "r");
- if (file == NULL)
- return;
-
- while (fscanf(file, "%*s %"
- STR(MAXPATHLEN)
- "s %99s %*s %*d %*d\n",
- debugfs, fs_type) == 2) {
- if (strcmp(fs_type, "debugfs") == 0)
- break;
- }
- fclose(file);
- if (strcmp(fs_type, "debugfs") == 0) {
- strncpy(debugfs_mntpt, debugfs, MAXPATHLEN);
- debugfs_mntpt[MAXPATHLEN - 1] = '\0';
- }
+ if (path)
+ strncpy(debugfs_mntpt, path, sizeof(debugfs_mntpt));
+ else
+ debugfs_mntpt[0] = '\0';
}
int main(int argc, const char **argv)
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 8cc4623afd6f..454d5d55f32d 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -47,6 +47,18 @@
#define cpu_relax() asm volatile("":::"memory")
#endif
+#ifdef __alpha__
+#include "../../arch/alpha/include/asm/unistd.h"
+#define rmb() asm volatile("mb" ::: "memory")
+#define cpu_relax() asm volatile("" ::: "memory")
+#endif
+
+#ifdef __ia64__
+#include "../../arch/ia64/include/asm/unistd.h"
+#define rmb() asm volatile ("mf" ::: "memory")
+#define cpu_relax() asm volatile ("hint @pause" ::: "memory")
+#endif
+
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c
new file mode 100644
index 000000000000..af78d9a52a7d
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c
@@ -0,0 +1,134 @@
+/*
+ * This file was generated automatically by ExtUtils::ParseXS version 2.18_02 from the
+ * contents of Context.xs. Do not edit this file, edit Context.xs instead.
+ *
+ * ANY CHANGES MADE HERE WILL BE LOST!
+ *
+ */
+
+#line 1 "Context.xs"
+/*
+ * Context.xs. XS interfaces for perf trace.
+ *
+ * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.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 "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "../../../util/trace-event-perl.h"
+
+#ifndef PERL_UNUSED_VAR
+# define PERL_UNUSED_VAR(var) if (0) var = var
+#endif
+
+#line 41 "Context.c"
+
+XS(XS_Perf__Trace__Context_common_pc); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Perf__Trace__Context_common_pc)
+{
+#ifdef dVAR
+ dVAR; dXSARGS;
+#else
+ dXSARGS;
+#endif
+ if (items != 1)
+ Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_pc", "context");
+ PERL_UNUSED_VAR(cv); /* -W */
+ {
+ struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
+ int RETVAL;
+ dXSTARG;
+
+ RETVAL = common_pc(context);
+ XSprePUSH; PUSHi((IV)RETVAL);
+ }
+ XSRETURN(1);
+}
+
+
+XS(XS_Perf__Trace__Context_common_flags); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Perf__Trace__Context_common_flags)
+{
+#ifdef dVAR
+ dVAR; dXSARGS;
+#else
+ dXSARGS;
+#endif
+ if (items != 1)
+ Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_flags", "context");
+ PERL_UNUSED_VAR(cv); /* -W */
+ {
+ struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
+ int RETVAL;
+ dXSTARG;
+
+ RETVAL = common_flags(context);
+ XSprePUSH; PUSHi((IV)RETVAL);
+ }
+ XSRETURN(1);
+}
+
+
+XS(XS_Perf__Trace__Context_common_lock_depth); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Perf__Trace__Context_common_lock_depth)
+{
+#ifdef dVAR
+ dVAR; dXSARGS;
+#else
+ dXSARGS;
+#endif
+ if (items != 1)
+ Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_lock_depth", "context");
+ PERL_UNUSED_VAR(cv); /* -W */
+ {
+ struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
+ int RETVAL;
+ dXSTARG;
+
+ RETVAL = common_lock_depth(context);
+ XSprePUSH; PUSHi((IV)RETVAL);
+ }
+ XSRETURN(1);
+}
+
+#ifdef __cplusplus
+extern "C"
+#endif
+XS(boot_Perf__Trace__Context); /* prototype to pass -Wmissing-prototypes */
+XS(boot_Perf__Trace__Context)
+{
+#ifdef dVAR
+ dVAR; dXSARGS;
+#else
+ dXSARGS;
+#endif
+ const char* file = __FILE__;
+
+ PERL_UNUSED_VAR(cv); /* -W */
+ PERL_UNUSED_VAR(items); /* -W */
+ XS_VERSION_BOOTCHECK ;
+
+ newXSproto("Perf::Trace::Context::common_pc", XS_Perf__Trace__Context_common_pc, file, "$");
+ newXSproto("Perf::Trace::Context::common_flags", XS_Perf__Trace__Context_common_flags, file, "$");
+ newXSproto("Perf::Trace::Context::common_lock_depth", XS_Perf__Trace__Context_common_lock_depth, file, "$");
+ if (PL_unitcheckav)
+ call_list(PL_scopestack_ix, PL_unitcheckav);
+ XSRETURN_YES;
+}
+
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
new file mode 100644
index 000000000000..fb78006c165e
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
@@ -0,0 +1,41 @@
+/*
+ * Context.xs. XS interfaces for perf trace.
+ *
+ * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.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 "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "../../../util/trace-event-perl.h"
+
+MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context
+PROTOTYPES: ENABLE
+
+int
+common_pc(context)
+ struct scripting_context * context
+
+int
+common_flags(context)
+ struct scripting_context * context
+
+int
+common_lock_depth(context)
+ struct scripting_context * context
+
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL b/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL
new file mode 100644
index 000000000000..decdeb0f6789
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL
@@ -0,0 +1,17 @@
+use 5.010000;
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+ NAME => 'Perf::Trace::Context',
+ VERSION_FROM => 'lib/Perf/Trace/Context.pm', # finds $VERSION
+ PREREQ_PM => {}, # e.g., Module::Name => 1.1
+ ($] >= 5.005 ? ## Add these new keywords supported since 5.005
+ (ABSTRACT_FROM => 'lib/Perf/Trace/Context.pm', # retrieve abstract from module
+ AUTHOR => 'Tom Zanussi <tzanussi@gmail.com>') : ()),
+ LIBS => [''], # e.g., '-lm'
+ DEFINE => '-I ../..', # e.g., '-DHAVE_SOMETHING'
+ INC => '-I.', # e.g., '-I. -I/usr/include/other'
+ # Un-comment this if you add C files to link with later:
+ OBJECT => 'Context.o', # link all the C files too
+);
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/README b/tools/perf/scripts/perl/Perf-Trace-Util/README
new file mode 100644
index 000000000000..9a9707630791
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/README
@@ -0,0 +1,59 @@
+Perf-Trace-Util version 0.01
+============================
+
+This module contains utility functions for use with perf trace.
+
+Core.pm and Util.pm are pure Perl modules; Core.pm contains routines
+that the core perf support for Perl calls on and should always be
+'used', while Util.pm contains useful but optional utility functions
+that scripts may want to use. Context.pm contains the Perl->C
+interface that allows scripts to access data in the embedding perf
+executable; scripts wishing to do that should 'use Context.pm'.
+
+The Perl->C perf interface is completely driven by Context.xs. If you
+want to add new Perl functions that end up accessing C data in the
+perf executable, you add desciptions of the new functions here.
+scripting_context is a pointer to the perf data in the perf executable
+that you want to access - it's passed as the second parameter,
+$context, to all handler functions.
+
+After you do that:
+
+ perl Makefile.PL # to create a Makefile for the next step
+ make # to create Context.c
+
+ edit Context.c to add const to the char* file = __FILE__ line in
+ XS(boot_Perf__Trace__Context) to silence a warning/error.
+
+ You can delete the Makefile, object files and anything else that was
+ generated e.g. blib and shared library, etc, except for of course
+ Context.c
+
+ You should then be able to run the normal perf make as usual.
+
+INSTALLATION
+
+Building perf with perf trace Perl scripting should install this
+module in the right place.
+
+You should make sure libperl and ExtUtils/Embed.pm are installed first
+e.g. apt-get install libperl-dev or yum install perl-ExtUtils-Embed.
+
+DEPENDENCIES
+
+This module requires these other modules and libraries:
+
+ None
+
+COPYRIGHT AND LICENCE
+
+Copyright (C) 2009 by Tom Zanussi <tzanussi@gmail.com>
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.10.0 or,
+at your option, any later version of Perl 5 you may have available.
+
+Alternatively, this software may be distributed under the terms of the
+GNU General Public License ("GPL") version 2 as published by the Free
+Software Foundation.
+
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm
new file mode 100644
index 000000000000..6c7f3659cb17
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm
@@ -0,0 +1,55 @@
+package Perf::Trace::Context;
+
+use 5.010000;
+use strict;
+use warnings;
+
+require Exporter;
+
+our @ISA = qw(Exporter);
+
+our %EXPORT_TAGS = ( 'all' => [ qw(
+) ] );
+
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+
+our @EXPORT = qw(
+ common_pc common_flags common_lock_depth
+);
+
+our $VERSION = '0.01';
+
+require XSLoader;
+XSLoader::load('Perf::Trace::Context', $VERSION);
+
+1;
+__END__
+=head1 NAME
+
+Perf::Trace::Context - Perl extension for accessing functions in perf.
+
+=head1 SYNOPSIS
+
+ use Perf::Trace::Context;
+
+=head1 SEE ALSO
+
+Perf (trace) documentation
+
+=head1 AUTHOR
+
+Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2009 by Tom Zanussi
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.10.0 or,
+at your option, any later version of Perl 5 you may have available.
+
+Alternatively, this software may be distributed under the terms of the
+GNU General Public License ("GPL") version 2 as published by the Free
+Software Foundation.
+
+=cut
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm
new file mode 100644
index 000000000000..9df376a9f629
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm
@@ -0,0 +1,192 @@
+package Perf::Trace::Core;
+
+use 5.010000;
+use strict;
+use warnings;
+
+require Exporter;
+
+our @ISA = qw(Exporter);
+
+our %EXPORT_TAGS = ( 'all' => [ qw(
+) ] );
+
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+
+our @EXPORT = qw(
+define_flag_field define_flag_value flag_str dump_flag_fields
+define_symbolic_field define_symbolic_value symbol_str dump_symbolic_fields
+trace_flag_str
+);
+
+our $VERSION = '0.01';
+
+my %trace_flags = (0x00 => "NONE",
+ 0x01 => "IRQS_OFF",
+ 0x02 => "IRQS_NOSUPPORT",
+ 0x04 => "NEED_RESCHED",
+ 0x08 => "HARDIRQ",
+ 0x10 => "SOFTIRQ");
+
+sub trace_flag_str
+{
+ my ($value) = @_;
+
+ my $string;
+
+ my $print_delim = 0;
+
+ foreach my $idx (sort {$a <=> $b} keys %trace_flags) {
+ if (!$value && !$idx) {
+ $string .= "NONE";
+ last;
+ }
+
+ if ($idx && ($value & $idx) == $idx) {
+ if ($print_delim) {
+ $string .= " | ";
+ }
+ $string .= "$trace_flags{$idx}";
+ $print_delim = 1;
+ $value &= ~$idx;
+ }
+ }
+
+ return $string;
+}
+
+my %flag_fields;
+my %symbolic_fields;
+
+sub flag_str
+{
+ my ($event_name, $field_name, $value) = @_;
+
+ my $string;
+
+ if ($flag_fields{$event_name}{$field_name}) {
+ my $print_delim = 0;
+ foreach my $idx (sort {$a <=> $b} keys %{$flag_fields{$event_name}{$field_name}{"values"}}) {
+ if (!$value && !$idx) {
+ $string .= "$flag_fields{$event_name}{$field_name}{'values'}{$idx}";
+ last;
+ }
+ if ($idx && ($value & $idx) == $idx) {
+ if ($print_delim && $flag_fields{$event_name}{$field_name}{'delim'}) {
+ $string .= " $flag_fields{$event_name}{$field_name}{'delim'} ";
+ }
+ $string .= "$flag_fields{$event_name}{$field_name}{'values'}{$idx}";
+ $print_delim = 1;
+ $value &= ~$idx;
+ }
+ }
+ }
+
+ return $string;
+}
+
+sub define_flag_field
+{
+ my ($event_name, $field_name, $delim) = @_;
+
+ $flag_fields{$event_name}{$field_name}{"delim"} = $delim;
+}
+
+sub define_flag_value
+{
+ my ($event_name, $field_name, $value, $field_str) = @_;
+
+ $flag_fields{$event_name}{$field_name}{"values"}{$value} = $field_str;
+}
+
+sub dump_flag_fields
+{
+ for my $event (keys %flag_fields) {
+ print "event $event:\n";
+ for my $field (keys %{$flag_fields{$event}}) {
+ print " field: $field:\n";
+ print " delim: $flag_fields{$event}{$field}{'delim'}\n";
+ foreach my $idx (sort {$a <=> $b} keys %{$flag_fields{$event}{$field}{"values"}}) {
+ print " value $idx: $flag_fields{$event}{$field}{'values'}{$idx}\n";
+ }
+ }
+ }
+}
+
+sub symbol_str
+{
+ my ($event_name, $field_name, $value) = @_;
+
+ if ($symbolic_fields{$event_name}{$field_name}) {
+ foreach my $idx (sort {$a <=> $b} keys %{$symbolic_fields{$event_name}{$field_name}{"values"}}) {
+ if (!$value && !$idx) {
+ return "$symbolic_fields{$event_name}{$field_name}{'values'}{$idx}";
+ last;
+ }
+ if ($value == $idx) {
+ return "$symbolic_fields{$event_name}{$field_name}{'values'}{$idx}";
+ }
+ }
+ }
+
+ return undef;
+}
+
+sub define_symbolic_field
+{
+ my ($event_name, $field_name) = @_;
+
+ # nothing to do, really
+}
+
+sub define_symbolic_value
+{
+ my ($event_name, $field_name, $value, $field_str) = @_;
+
+ $symbolic_fields{$event_name}{$field_name}{"values"}{$value} = $field_str;
+}
+
+sub dump_symbolic_fields
+{
+ for my $event (keys %symbolic_fields) {
+ print "event $event:\n";
+ for my $field (keys %{$symbolic_fields{$event}}) {
+ print " field: $field:\n";
+ foreach my $idx (sort {$a <=> $b} keys %{$symbolic_fields{$event}{$field}{"values"}}) {
+ print " value $idx: $symbolic_fields{$event}{$field}{'values'}{$idx}\n";
+ }
+ }
+ }
+}
+
+1;
+__END__
+=head1 NAME
+
+Perf::Trace::Core - Perl extension for perf trace
+
+=head1 SYNOPSIS
+
+ use Perf::Trace::Core
+
+=head1 SEE ALSO
+
+Perf (trace) documentation
+
+=head1 AUTHOR
+
+Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2009 by Tom Zanussi
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.10.0 or,
+at your option, any later version of Perl 5 you may have available.
+
+Alternatively, this software may be distributed under the terms of the
+GNU General Public License ("GPL") version 2 as published by the Free
+Software Foundation.
+
+=cut
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
new file mode 100644
index 000000000000..052f132ced24
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
@@ -0,0 +1,88 @@
+package Perf::Trace::Util;
+
+use 5.010000;
+use strict;
+use warnings;
+
+require Exporter;
+
+our @ISA = qw(Exporter);
+
+our %EXPORT_TAGS = ( 'all' => [ qw(
+) ] );
+
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+
+our @EXPORT = qw(
+avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs
+);
+
+our $VERSION = '0.01';
+
+sub avg
+{
+ my ($total, $n) = @_;
+
+ return $total / $n;
+}
+
+my $NSECS_PER_SEC = 1000000000;
+
+sub nsecs
+{
+ my ($secs, $nsecs) = @_;
+
+ return $secs * $NSECS_PER_SEC + $nsecs;
+}
+
+sub nsecs_secs {
+ my ($nsecs) = @_;
+
+ return $nsecs / $NSECS_PER_SEC;
+}
+
+sub nsecs_nsecs {
+ my ($nsecs) = @_;
+
+ return $nsecs - nsecs_secs($nsecs);
+}
+
+sub nsecs_str {
+ my ($nsecs) = @_;
+
+ my $str = sprintf("%5u.%09u", nsecs_secs($nsecs), nsecs_nsecs($nsecs));
+
+ return $str;
+}
+
+1;
+__END__
+=head1 NAME
+
+Perf::Trace::Util - Perl extension for perf trace
+
+=head1 SYNOPSIS
+
+ use Perf::Trace::Util;
+
+=head1 SEE ALSO
+
+Perf (trace) documentation
+
+=head1 AUTHOR
+
+Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2009 by Tom Zanussi
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.10.0 or,
+at your option, any later version of Perl 5 you may have available.
+
+Alternatively, this software may be distributed under the terms of the
+GNU General Public License ("GPL") version 2 as published by the Free
+Software Foundation.
+
+=cut
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/typemap b/tools/perf/scripts/perl/Perf-Trace-Util/typemap
new file mode 100644
index 000000000000..840836804aa7
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/typemap
@@ -0,0 +1 @@
+struct scripting_context * T_PTR
diff --git a/tools/perf/scripts/perl/bin/check-perf-trace-record b/tools/perf/scripts/perl/bin/check-perf-trace-record
new file mode 100644
index 000000000000..c7ec5de2f535
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/check-perf-trace-record
@@ -0,0 +1,7 @@
+#!/bin/bash
+perf record -c 1 -f -a -M -R -e kmem:kmalloc -e irq:softirq_entry
+
+
+
+
+
diff --git a/tools/perf/scripts/perl/bin/check-perf-trace-report b/tools/perf/scripts/perl/bin/check-perf-trace-report
new file mode 100644
index 000000000000..89948b015020
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/check-perf-trace-report
@@ -0,0 +1,5 @@
+#!/bin/bash
+perf trace -s ~/libexec/perf-core/scripts/perl/check-perf-trace.pl
+
+
+
diff --git a/tools/perf/scripts/perl/bin/rw-by-file-record b/tools/perf/scripts/perl/bin/rw-by-file-record
new file mode 100644
index 000000000000..b25056ebf963
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/rw-by-file-record
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_enter_write
diff --git a/tools/perf/scripts/perl/bin/rw-by-file-report b/tools/perf/scripts/perl/bin/rw-by-file-report
new file mode 100644
index 000000000000..f5dcf9cb5bd2
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/rw-by-file-report
@@ -0,0 +1,5 @@
+#!/bin/bash
+perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl
+
+
+
diff --git a/tools/perf/scripts/perl/bin/rw-by-pid-record b/tools/perf/scripts/perl/bin/rw-by-pid-record
new file mode 100644
index 000000000000..8903979c5b6c
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/rw-by-pid-record
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write
diff --git a/tools/perf/scripts/perl/bin/rw-by-pid-report b/tools/perf/scripts/perl/bin/rw-by-pid-report
new file mode 100644
index 000000000000..cea16f78a3a2
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/rw-by-pid-report
@@ -0,0 +1,5 @@
+#!/bin/bash
+perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl
+
+
+
diff --git a/tools/perf/scripts/perl/bin/wakeup-latency-record b/tools/perf/scripts/perl/bin/wakeup-latency-record
new file mode 100644
index 000000000000..6abedda911a4
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/wakeup-latency-record
@@ -0,0 +1,6 @@
+#!/bin/bash
+perf record -c 1 -f -a -M -R -e sched:sched_switch -e sched:sched_wakeup
+
+
+
+
diff --git a/tools/perf/scripts/perl/bin/wakeup-latency-report b/tools/perf/scripts/perl/bin/wakeup-latency-report
new file mode 100644
index 000000000000..85769dc456eb
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/wakeup-latency-report
@@ -0,0 +1,5 @@
+#!/bin/bash
+perf trace -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl
+
+
+
diff --git a/tools/perf/scripts/perl/bin/workqueue-stats-record b/tools/perf/scripts/perl/bin/workqueue-stats-record
new file mode 100644
index 000000000000..fce6637b19ba
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/workqueue-stats-record
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -c 1 -f -a -M -R -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion
diff --git a/tools/perf/scripts/perl/bin/workqueue-stats-report b/tools/perf/scripts/perl/bin/workqueue-stats-report
new file mode 100644
index 000000000000..aa68435be926
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/workqueue-stats-report
@@ -0,0 +1,6 @@
+#!/bin/bash
+perf trace -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl
+
+
+
+
diff --git a/tools/perf/scripts/perl/check-perf-trace.pl b/tools/perf/scripts/perl/check-perf-trace.pl
new file mode 100644
index 000000000000..4e7dc0a407a5
--- /dev/null
+++ b/tools/perf/scripts/perl/check-perf-trace.pl
@@ -0,0 +1,106 @@
+# perf trace event handlers, generated by perf trace -g perl
+# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
+# Licensed under the terms of the GNU GPL License version 2
+
+# This script tests basic functionality such as flag and symbol
+# strings, common_xxx() calls back into perf, begin, end, unhandled
+# events, etc. Basically, if this script runs successfully and
+# displays expected results, perl scripting support should be ok.
+
+use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
+use lib "./Perf-Trace-Util/lib";
+use Perf::Trace::Core;
+use Perf::Trace::Context;
+use Perf::Trace::Util;
+
+sub trace_begin
+{
+ print "trace_begin\n";
+}
+
+sub trace_end
+{
+ print "trace_end\n";
+
+ print_unhandled();
+}
+
+sub irq::softirq_entry
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $vec) = @_;
+
+ print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm);
+
+ print_uncommon($context);
+
+ printf("vec=%s\n",
+ symbol_str("irq::softirq_entry", "vec", $vec));
+}
+
+sub kmem::kmalloc
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $call_site, $ptr, $bytes_req, $bytes_alloc,
+ $gfp_flags) = @_;
+
+ print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm);
+
+ print_uncommon($context);
+
+ printf("call_site=%p, ptr=%p, bytes_req=%u, bytes_alloc=%u, ".
+ "gfp_flags=%s\n",
+ $call_site, $ptr, $bytes_req, $bytes_alloc,
+
+ flag_str("kmem::kmalloc", "gfp_flags", $gfp_flags));
+}
+
+# print trace fields not included in handler args
+sub print_uncommon
+{
+ my ($context) = @_;
+
+ printf("common_preempt_count=%d, common_flags=%s, common_lock_depth=%d, ",
+ common_pc($context), trace_flag_str(common_flags($context)),
+ common_lock_depth($context));
+
+}
+
+my %unhandled;
+
+sub print_unhandled
+{
+ if ((scalar keys %unhandled) == 0) {
+ return;
+ }
+
+ print "\nunhandled events:\n\n";
+
+ printf("%-40s %10s\n", "event", "count");
+ printf("%-40s %10s\n", "----------------------------------------",
+ "-----------");
+
+ foreach my $event_name (keys %unhandled) {
+ printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
+ }
+}
+
+sub trace_unhandled
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm) = @_;
+
+ $unhandled{$event_name}++;
+}
+
+sub print_header
+{
+ my ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;
+
+ printf("%-20s %5u %05u.%09u %8u %-20s ",
+ $event_name, $cpu, $secs, $nsecs, $pid, $comm);
+}
diff --git a/tools/perf/scripts/perl/rw-by-file.pl b/tools/perf/scripts/perl/rw-by-file.pl
new file mode 100644
index 000000000000..61f91561d848
--- /dev/null
+++ b/tools/perf/scripts/perl/rw-by-file.pl
@@ -0,0 +1,105 @@
+#!/usr/bin/perl -w
+# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
+# Licensed under the terms of the GNU GPL License version 2
+
+# Display r/w activity for files read/written to for a given program
+
+# The common_* event handler fields are the most useful fields common to
+# all events. They don't necessarily correspond to the 'common_*' fields
+# in the status files. Those fields not available as handler params can
+# be retrieved via script functions of the form get_common_*().
+
+use 5.010000;
+use strict;
+use warnings;
+
+use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
+use lib "./Perf-Trace-Util/lib";
+use Perf::Trace::Core;
+use Perf::Trace::Util;
+
+# change this to the comm of the program you're interested in
+my $for_comm = "perf";
+
+my %reads;
+my %writes;
+
+sub syscalls::sys_enter_read
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm, $nr, $fd, $buf, $count) = @_;
+
+ if ($common_comm eq $for_comm) {
+ $reads{$fd}{bytes_requested} += $count;
+ $reads{$fd}{total_reads}++;
+ }
+}
+
+sub syscalls::sys_enter_write
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm, $nr, $fd, $buf, $count) = @_;
+
+ if ($common_comm eq $for_comm) {
+ $writes{$fd}{bytes_written} += $count;
+ $writes{$fd}{total_writes}++;
+ }
+}
+
+sub trace_end
+{
+ printf("file read counts for $for_comm:\n\n");
+
+ printf("%6s %10s %10s\n", "fd", "# reads", "bytes_requested");
+ printf("%6s %10s %10s\n", "------", "----------", "-----------");
+
+ foreach my $fd (sort {$reads{$b}{bytes_requested} <=>
+ $reads{$a}{bytes_requested}} keys %reads) {
+ my $total_reads = $reads{$fd}{total_reads};
+ my $bytes_requested = $reads{$fd}{bytes_requested};
+ printf("%6u %10u %10u\n", $fd, $total_reads, $bytes_requested);
+ }
+
+ printf("\nfile write counts for $for_comm:\n\n");
+
+ printf("%6s %10s %10s\n", "fd", "# writes", "bytes_written");
+ printf("%6s %10s %10s\n", "------", "----------", "-----------");
+
+ foreach my $fd (sort {$writes{$b}{bytes_written} <=>
+ $writes{$a}{bytes_written}} keys %writes) {
+ my $total_writes = $writes{$fd}{total_writes};
+ my $bytes_written = $writes{$fd}{bytes_written};
+ printf("%6u %10u %10u\n", $fd, $total_writes, $bytes_written);
+ }
+
+ print_unhandled();
+}
+
+my %unhandled;
+
+sub print_unhandled
+{
+ if ((scalar keys %unhandled) == 0) {
+ return;
+ }
+
+ print "\nunhandled events:\n\n";
+
+ printf("%-40s %10s\n", "event", "count");
+ printf("%-40s %10s\n", "----------------------------------------",
+ "-----------");
+
+ foreach my $event_name (keys %unhandled) {
+ printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
+ }
+}
+
+sub trace_unhandled
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm) = @_;
+
+ $unhandled{$event_name}++;
+}
+
+
diff --git a/tools/perf/scripts/perl/rw-by-pid.pl b/tools/perf/scripts/perl/rw-by-pid.pl
new file mode 100644
index 000000000000..da601fae1a00
--- /dev/null
+++ b/tools/perf/scripts/perl/rw-by-pid.pl
@@ -0,0 +1,170 @@
+#!/usr/bin/perl -w
+# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
+# Licensed under the terms of the GNU GPL License version 2
+
+# Display r/w activity for all processes
+
+# The common_* event handler fields are the most useful fields common to
+# all events. They don't necessarily correspond to the 'common_*' fields
+# in the status files. Those fields not available as handler params can
+# be retrieved via script functions of the form get_common_*().
+
+use 5.010000;
+use strict;
+use warnings;
+
+use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
+use lib "./Perf-Trace-Util/lib";
+use Perf::Trace::Core;
+use Perf::Trace::Util;
+
+my %reads;
+my %writes;
+
+sub syscalls::sys_exit_read
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $nr, $ret) = @_;
+
+ if ($ret > 0) {
+ $reads{$common_pid}{bytes_read} += $ret;
+ } else {
+ if (!defined ($reads{$common_pid}{bytes_read})) {
+ $reads{$common_pid}{bytes_read} = 0;
+ }
+ $reads{$common_pid}{errors}{$ret}++;
+ }
+}
+
+sub syscalls::sys_enter_read
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $nr, $fd, $buf, $count) = @_;
+
+ $reads{$common_pid}{bytes_requested} += $count;
+ $reads{$common_pid}{total_reads}++;
+ $reads{$common_pid}{comm} = $common_comm;
+}
+
+sub syscalls::sys_exit_write
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $nr, $ret) = @_;
+
+ if ($ret <= 0) {
+ $writes{$common_pid}{errors}{$ret}++;
+ }
+}
+
+sub syscalls::sys_enter_write
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $nr, $fd, $buf, $count) = @_;
+
+ $writes{$common_pid}{bytes_written} += $count;
+ $writes{$common_pid}{total_writes}++;
+ $writes{$common_pid}{comm} = $common_comm;
+}
+
+sub trace_end
+{
+ printf("read counts by pid:\n\n");
+
+ printf("%6s %20s %10s %10s %10s\n", "pid", "comm",
+ "# reads", "bytes_requested", "bytes_read");
+ printf("%6s %-20s %10s %10s %10s\n", "------", "--------------------",
+ "-----------", "----------", "----------");
+
+ foreach my $pid (sort {$reads{$b}{bytes_read} <=>
+ $reads{$a}{bytes_read}} keys %reads) {
+ my $comm = $reads{$pid}{comm};
+ my $total_reads = $reads{$pid}{total_reads};
+ my $bytes_requested = $reads{$pid}{bytes_requested};
+ my $bytes_read = $reads{$pid}{bytes_read};
+
+ printf("%6s %-20s %10s %10s %10s\n", $pid, $comm,
+ $total_reads, $bytes_requested, $bytes_read);
+ }
+
+ printf("\nfailed reads by pid:\n\n");
+
+ printf("%6s %20s %6s %10s\n", "pid", "comm", "error #", "# errors");
+ printf("%6s %20s %6s %10s\n", "------", "--------------------",
+ "------", "----------");
+
+ foreach my $pid (keys %reads) {
+ my $comm = $reads{$pid}{comm};
+ foreach my $err (sort {$reads{$b}{comm} cmp $reads{$a}{comm}}
+ keys %{$reads{$pid}{errors}}) {
+ my $errors = $reads{$pid}{errors}{$err};
+
+ printf("%6d %-20s %6d %10s\n", $pid, $comm, $err, $errors);
+ }
+ }
+
+ printf("\nwrite counts by pid:\n\n");
+
+ printf("%6s %20s %10s %10s\n", "pid", "comm",
+ "# writes", "bytes_written");
+ printf("%6s %-20s %10s %10s\n", "------", "--------------------",
+ "-----------", "----------");
+
+ foreach my $pid (sort {$writes{$b}{bytes_written} <=>
+ $writes{$a}{bytes_written}} keys %writes) {
+ my $comm = $writes{$pid}{comm};
+ my $total_writes = $writes{$pid}{total_writes};
+ my $bytes_written = $writes{$pid}{bytes_written};
+
+ printf("%6s %-20s %10s %10s\n", $pid, $comm,
+ $total_writes, $bytes_written);
+ }
+
+ printf("\nfailed writes by pid:\n\n");
+
+ printf("%6s %20s %6s %10s\n", "pid", "comm", "error #", "# errors");
+ printf("%6s %20s %6s %10s\n", "------", "--------------------",
+ "------", "----------");
+
+ foreach my $pid (keys %writes) {
+ my $comm = $writes{$pid}{comm};
+ foreach my $err (sort {$writes{$b}{comm} cmp $writes{$a}{comm}}
+ keys %{$writes{$pid}{errors}}) {
+ my $errors = $writes{$pid}{errors}{$err};
+
+ printf("%6d %-20s %6d %10s\n", $pid, $comm, $err, $errors);
+ }
+ }
+
+ print_unhandled();
+}
+
+my %unhandled;
+
+sub print_unhandled
+{
+ if ((scalar keys %unhandled) == 0) {
+ return;
+ }
+
+ print "\nunhandled events:\n\n";
+
+ printf("%-40s %10s\n", "event", "count");
+ printf("%-40s %10s\n", "----------------------------------------",
+ "-----------");
+
+ foreach my $event_name (keys %unhandled) {
+ printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
+ }
+}
+
+sub trace_unhandled
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm) = @_;
+
+ $unhandled{$event_name}++;
+}
diff --git a/tools/perf/scripts/perl/wakeup-latency.pl b/tools/perf/scripts/perl/wakeup-latency.pl
new file mode 100644
index 000000000000..ed58ef284e23
--- /dev/null
+++ b/tools/perf/scripts/perl/wakeup-latency.pl
@@ -0,0 +1,103 @@
+#!/usr/bin/perl -w
+# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
+# Licensed under the terms of the GNU GPL License version 2
+
+# Display avg/min/max wakeup latency
+
+# The common_* event handler fields are the most useful fields common to
+# all events. They don't necessarily correspond to the 'common_*' fields
+# in the status files. Those fields not available as handler params can
+# be retrieved via script functions of the form get_common_*().
+
+use 5.010000;
+use strict;
+use warnings;
+
+use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
+use lib "./Perf-Trace-Util/lib";
+use Perf::Trace::Core;
+use Perf::Trace::Util;
+
+my %last_wakeup;
+
+my $max_wakeup_latency;
+my $min_wakeup_latency;
+my $total_wakeup_latency;
+my $total_wakeups;
+
+sub sched::sched_switch
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $prev_comm, $prev_pid, $prev_prio, $prev_state, $next_comm, $next_pid,
+ $next_prio) = @_;
+
+ my $wakeup_ts = $last_wakeup{$common_cpu}{ts};
+ if ($wakeup_ts) {
+ my $switch_ts = nsecs($common_secs, $common_nsecs);
+ my $wakeup_latency = $switch_ts - $wakeup_ts;
+ if ($wakeup_latency > $max_wakeup_latency) {
+ $max_wakeup_latency = $wakeup_latency;
+ }
+ if ($wakeup_latency < $min_wakeup_latency) {
+ $min_wakeup_latency = $wakeup_latency;
+ }
+ $total_wakeup_latency += $wakeup_latency;
+ $total_wakeups++;
+ }
+ $last_wakeup{$common_cpu}{ts} = 0;
+}
+
+sub sched::sched_wakeup
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $comm, $pid, $prio, $success, $target_cpu) = @_;
+
+ $last_wakeup{$target_cpu}{ts} = nsecs($common_secs, $common_nsecs);
+}
+
+sub trace_begin
+{
+ $min_wakeup_latency = 1000000000;
+ $max_wakeup_latency = 0;
+}
+
+sub trace_end
+{
+ printf("wakeup_latency stats:\n\n");
+ print "total_wakeups: $total_wakeups\n";
+ printf("avg_wakeup_latency (ns): %u\n",
+ avg($total_wakeup_latency, $total_wakeups));
+ printf("min_wakeup_latency (ns): %u\n", $min_wakeup_latency);
+ printf("max_wakeup_latency (ns): %u\n", $max_wakeup_latency);
+
+ print_unhandled();
+}
+
+my %unhandled;
+
+sub print_unhandled
+{
+ if ((scalar keys %unhandled) == 0) {
+ return;
+ }
+
+ print "\nunhandled events:\n\n";
+
+ printf("%-40s %10s\n", "event", "count");
+ printf("%-40s %10s\n", "----------------------------------------",
+ "-----------");
+
+ foreach my $event_name (keys %unhandled) {
+ printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
+ }
+}
+
+sub trace_unhandled
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm) = @_;
+
+ $unhandled{$event_name}++;
+}
diff --git a/tools/perf/scripts/perl/workqueue-stats.pl b/tools/perf/scripts/perl/workqueue-stats.pl
new file mode 100644
index 000000000000..511302c8a494
--- /dev/null
+++ b/tools/perf/scripts/perl/workqueue-stats.pl
@@ -0,0 +1,129 @@
+#!/usr/bin/perl -w
+# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
+# Licensed under the terms of the GNU GPL License version 2
+
+# Displays workqueue stats
+#
+# Usage:
+#
+# perf record -c 1 -f -a -R -e workqueue:workqueue_creation -e
+# workqueue:workqueue_destruction -e workqueue:workqueue_execution
+# -e workqueue:workqueue_insertion
+#
+# perf trace -p -s tools/perf/scripts/perl/workqueue-stats.pl
+
+use 5.010000;
+use strict;
+use warnings;
+
+use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
+use lib "./Perf-Trace-Util/lib";
+use Perf::Trace::Core;
+use Perf::Trace::Util;
+
+my @cpus;
+
+sub workqueue::workqueue_destruction
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $thread_comm, $thread_pid) = @_;
+
+ $cpus[$common_cpu]{$thread_pid}{destroyed}++;
+ $cpus[$common_cpu]{$thread_pid}{comm} = $thread_comm;
+}
+
+sub workqueue::workqueue_creation
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $thread_comm, $thread_pid, $cpu) = @_;
+
+ $cpus[$common_cpu]{$thread_pid}{created}++;
+ $cpus[$common_cpu]{$thread_pid}{comm} = $thread_comm;
+}
+
+sub workqueue::workqueue_execution
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $thread_comm, $thread_pid, $func) = @_;
+
+ $cpus[$common_cpu]{$thread_pid}{executed}++;
+ $cpus[$common_cpu]{$thread_pid}{comm} = $thread_comm;
+}
+
+sub workqueue::workqueue_insertion
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm,
+ $thread_comm, $thread_pid, $func) = @_;
+
+ $cpus[$common_cpu]{$thread_pid}{inserted}++;
+ $cpus[$common_cpu]{$thread_pid}{comm} = $thread_comm;
+}
+
+sub trace_end
+{
+ print "workqueue work stats:\n\n";
+ my $cpu = 0;
+ printf("%3s %6s %6s\t%-20s\n", "cpu", "ins", "exec", "name");
+ printf("%3s %6s %6s\t%-20s\n", "---", "---", "----", "----");
+ foreach my $pidhash (@cpus) {
+ while ((my $pid, my $wqhash) = each %$pidhash) {
+ my $ins = $$wqhash{'inserted'};
+ my $exe = $$wqhash{'executed'};
+ my $comm = $$wqhash{'comm'};
+ if ($ins || $exe) {
+ printf("%3u %6u %6u\t%-20s\n", $cpu, $ins, $exe, $comm);
+ }
+ }
+ $cpu++;
+ }
+
+ $cpu = 0;
+ print "\nworkqueue lifecycle stats:\n\n";
+ printf("%3s %6s %6s\t%-20s\n", "cpu", "created", "destroyed", "name");
+ printf("%3s %6s %6s\t%-20s\n", "---", "-------", "---------", "----");
+ foreach my $pidhash (@cpus) {
+ while ((my $pid, my $wqhash) = each %$pidhash) {
+ my $created = $$wqhash{'created'};
+ my $destroyed = $$wqhash{'destroyed'};
+ my $comm = $$wqhash{'comm'};
+ if ($created || $destroyed) {
+ printf("%3u %6u %6u\t%-20s\n", $cpu, $created, $destroyed,
+ $comm);
+ }
+ }
+ $cpu++;
+ }
+
+ print_unhandled();
+}
+
+my %unhandled;
+
+sub print_unhandled
+{
+ if ((scalar keys %unhandled) == 0) {
+ return;
+ }
+
+ print "\nunhandled events:\n\n";
+
+ printf("%-40s %10s\n", "event", "count");
+ printf("%-40s %10s\n", "----------------------------------------",
+ "-----------");
+
+ foreach my $event_name (keys %unhandled) {
+ printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
+ }
+}
+
+sub trace_unhandled
+{
+ my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+ $common_pid, $common_comm) = @_;
+
+ $unhandled{$event_name}++;
+}
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN
index c561d1538c03..54552a00a117 100755
--- a/tools/perf/util/PERF-VERSION-GEN
+++ b/tools/perf/util/PERF-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=PERF-VERSION-FILE
-DEF_VER=v0.0.1.PERF
+DEF_VER=v0.0.2.PERF
LF='
'
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 6f8ea9d210b6..918eb376abe3 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -1,10 +1,15 @@
-#ifndef CACHE_H
-#define CACHE_H
+#ifndef __PERF_CACHE_H
+#define __PERF_CACHE_H
#include "util.h"
#include "strbuf.h"
#include "../perf.h"
+#define CMD_EXEC_PATH "--exec-path"
+#define CMD_PERF_DIR "--perf-dir="
+#define CMD_WORK_TREE "--work-tree="
+#define CMD_DEBUGFS_DIR "--debugfs-dir="
+
#define PERF_DIR_ENVIRONMENT "PERF_DIR"
#define PERF_WORK_TREE_ENVIRONMENT "PERF_WORK_TREE"
#define DEFAULT_PERF_DIR_ENVIRONMENT ".perf"
@@ -117,4 +122,4 @@ extern char *perf_pathdup(const char *fmt, ...)
extern size_t strlcpy(char *dest, const char *src, size_t size);
-#endif /* CACHE_H */
+#endif /* __PERF_CACHE_H */
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 3b8380f1b478..b3b71258272a 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -206,7 +206,7 @@ fill_node(struct callchain_node *node, struct ip_callchain *chain,
}
node->val_nr = chain->nr - start;
if (!node->val_nr)
- printf("Warning: empty node in callchain tree\n");
+ pr_warning("Warning: empty node in callchain tree\n");
}
static void
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 43cf3ea9e088..ad4626de4c2b 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -58,4 +58,4 @@ static inline u64 cumul_hits(struct callchain_node *node)
int register_callchain_param(struct callchain_param *param);
void append_chain(struct callchain_node *root, struct ip_callchain *chain,
struct symbol **syms);
-#endif
+#endif /* __PERF_CALLCHAIN_H */
diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h
index 58d597564b99..24e8809210bb 100644
--- a/tools/perf/util/color.h
+++ b/tools/perf/util/color.h
@@ -1,5 +1,5 @@
-#ifndef COLOR_H
-#define COLOR_H
+#ifndef __PERF_COLOR_H
+#define __PERF_COLOR_H
/* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */
#define COLOR_MAXLEN 24
@@ -39,4 +39,4 @@ int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *bu
int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
const char *get_percent_color(double percent);
-#endif /* COLOR_H */
+#endif /* __PERF_COLOR_H */
diff --git a/tools/perf/util/ctype.c b/tools/perf/util/ctype.c
index 0b791bd346bc..35073621e5de 100644
--- a/tools/perf/util/ctype.c
+++ b/tools/perf/util/ctype.c
@@ -29,3 +29,11 @@ unsigned char sane_ctype[256] = {
A, A, A, A, A, A, A, A, A, A, A, R, R, P, P, 0, /* 112..127 */
/* Nothing in the 128.. range */
};
+
+const char *graph_line =
+ "_____________________________________________________________________"
+ "_____________________________________________________________________";
+const char *graph_dotted_line =
+ "---------------------------------------------------------------------"
+ "---------------------------------------------------------------------"
+ "---------------------------------------------------------------------";
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
new file mode 100644
index 000000000000..ca0bedf637c2
--- /dev/null
+++ b/tools/perf/util/data_map.c
@@ -0,0 +1,291 @@
+#include "data_map.h"
+#include "symbol.h"
+#include "util.h"
+#include "debug.h"
+
+
+static struct perf_file_handler *curr_handler;
+static unsigned long mmap_window = 32;
+static char __cwd[PATH_MAX];
+
+static int process_event_stub(event_t *event __used)
+{
+ dump_printf(": unhandled!\n");
+ return 0;
+}
+
+void register_perf_file_handler(struct perf_file_handler *handler)
+{
+ if (!handler->process_sample_event)
+ handler->process_sample_event = process_event_stub;
+ if (!handler->process_mmap_event)
+ handler->process_mmap_event = process_event_stub;
+ if (!handler->process_comm_event)
+ handler->process_comm_event = process_event_stub;
+ if (!handler->process_fork_event)
+ handler->process_fork_event = process_event_stub;
+ if (!handler->process_exit_event)
+ handler->process_exit_event = process_event_stub;
+ if (!handler->process_lost_event)
+ handler->process_lost_event = process_event_stub;
+ if (!handler->process_read_event)
+ handler->process_read_event = process_event_stub;
+ if (!handler->process_throttle_event)
+ handler->process_throttle_event = process_event_stub;
+ if (!handler->process_unthrottle_event)
+ handler->process_unthrottle_event = process_event_stub;
+
+ curr_handler = handler;
+}
+
+static const char *event__name[] = {
+ [0] = "TOTAL",
+ [PERF_RECORD_MMAP] = "MMAP",
+ [PERF_RECORD_LOST] = "LOST",
+ [PERF_RECORD_COMM] = "COMM",
+ [PERF_RECORD_EXIT] = "EXIT",
+ [PERF_RECORD_THROTTLE] = "THROTTLE",
+ [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE",
+ [PERF_RECORD_FORK] = "FORK",
+ [PERF_RECORD_READ] = "READ",
+ [PERF_RECORD_SAMPLE] = "SAMPLE",
+};
+
+unsigned long event__total[PERF_RECORD_MAX];
+
+void event__print_totals(void)
+{
+ int i;
+ for (i = 0; i < PERF_RECORD_MAX; ++i)
+ pr_info("%10s events: %10ld\n",
+ event__name[i], event__total[i]);
+}
+
+static int
+process_event(event_t *event, unsigned long offset, unsigned long head)
+{
+ trace_event(event);
+
+ if (event->header.type < PERF_RECORD_MAX) {
+ dump_printf("%p [%p]: PERF_RECORD_%s",
+ (void *)(offset + head),
+ (void *)(long)(event->header.size),
+ event__name[event->header.type]);
+ ++event__total[0];
+ ++event__total[event->header.type];
+ }
+
+ switch (event->header.type) {
+ case PERF_RECORD_SAMPLE:
+ return curr_handler->process_sample_event(event);
+ case PERF_RECORD_MMAP:
+ return curr_handler->process_mmap_event(event);
+ case PERF_RECORD_COMM:
+ return curr_handler->process_comm_event(event);
+ case PERF_RECORD_FORK:
+ return curr_handler->process_fork_event(event);
+ case PERF_RECORD_EXIT:
+ return curr_handler->process_exit_event(event);
+ case PERF_RECORD_LOST:
+ return curr_handler->process_lost_event(event);
+ case PERF_RECORD_READ:
+ return curr_handler->process_read_event(event);
+ case PERF_RECORD_THROTTLE:
+ return curr_handler->process_throttle_event(event);
+ case PERF_RECORD_UNTHROTTLE:
+ return curr_handler->process_unthrottle_event(event);
+ default:
+ curr_handler->total_unknown++;
+ return -1;
+ }
+}
+
+int perf_header__read_build_ids(int input, off_t offset, off_t size)
+{
+ struct build_id_event bev;
+ char filename[PATH_MAX];
+ off_t limit = offset + size;
+ int err = -1;
+
+ while (offset < limit) {
+ struct dso *dso;
+ ssize_t len;
+
+ if (read(input, &bev, sizeof(bev)) != sizeof(bev))
+ goto out;
+
+ len = bev.header.size - sizeof(bev);
+ if (read(input, filename, len) != len)
+ goto out;
+
+ dso = dsos__findnew(filename);
+ if (dso != NULL)
+ dso__set_build_id(dso, &bev.build_id);
+
+ offset += bev.header.size;
+ }
+ err = 0;
+out:
+ return err;
+}
+
+int mmap_dispatch_perf_file(struct perf_header **pheader,
+ const char *input_name,
+ int force,
+ int full_paths,
+ int *cwdlen,
+ char **cwd)
+{
+ int err;
+ struct perf_header *header;
+ unsigned long head, shift;
+ unsigned long offset = 0;
+ struct stat input_stat;
+ size_t page_size;
+ u64 sample_type;
+ event_t *event;
+ uint32_t size;
+ int input;
+ char *buf;
+
+ if (curr_handler == NULL) {
+ pr_debug("Forgot to register perf file handler\n");
+ return -EINVAL;
+ }
+
+ page_size = getpagesize();
+
+ input = open(input_name, O_RDONLY);
+ if (input < 0) {
+ pr_err("Failed to open file: %s", input_name);
+ if (!strcmp(input_name, "perf.data"))
+ pr_err(" (try 'perf record' first)");
+ pr_err("\n");
+ return -errno;
+ }
+
+ if (fstat(input, &input_stat) < 0) {
+ pr_err("failed to stat file");
+ err = -errno;
+ goto out_close;
+ }
+
+ err = -EACCES;
+ if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
+ pr_err("file: %s not owned by current user or root\n",
+ input_name);
+ goto out_close;
+ }
+
+ if (input_stat.st_size == 0) {
+ pr_info("zero-sized file, nothing to do!\n");
+ goto done;
+ }
+
+ err = -ENOMEM;
+ header = perf_header__new();
+ if (header == NULL)
+ goto out_close;
+
+ err = perf_header__read(header, input);
+ if (err < 0)
+ goto out_delete;
+ *pheader = header;
+ head = header->data_offset;
+
+ sample_type = perf_header__sample_type(header);
+
+ err = -EINVAL;
+ if (curr_handler->sample_type_check &&
+ curr_handler->sample_type_check(sample_type) < 0)
+ goto out_delete;
+
+ if (!full_paths) {
+ if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
+ pr_err("failed to get the current directory\n");
+ err = -errno;
+ goto out_delete;
+ }
+ *cwd = __cwd;
+ *cwdlen = strlen(*cwd);
+ } else {
+ *cwd = NULL;
+ *cwdlen = 0;
+ }
+
+ shift = page_size * (head / page_size);
+ offset += shift;
+ head -= shift;
+
+remap:
+ buf = mmap(NULL, page_size * mmap_window, PROT_READ,
+ MAP_SHARED, input, offset);
+ if (buf == MAP_FAILED) {
+ pr_err("failed to mmap file\n");
+ err = -errno;
+ goto out_delete;
+ }
+
+more:
+ event = (event_t *)(buf + head);
+
+ size = event->header.size;
+ if (!size)
+ size = 8;
+
+ if (head + event->header.size >= page_size * mmap_window) {
+ int munmap_ret;
+
+ shift = page_size * (head / page_size);
+
+ munmap_ret = munmap(buf, page_size * mmap_window);
+ assert(munmap_ret == 0);
+
+ offset += shift;
+ head -= shift;
+ goto remap;
+ }
+
+ size = event->header.size;
+
+ dump_printf("\n%p [%p]: event: %d\n",
+ (void *)(offset + head),
+ (void *)(long)event->header.size,
+ event->header.type);
+
+ if (!size || process_event(event, offset, head) < 0) {
+
+ dump_printf("%p [%p]: skipping unknown header type: %d\n",
+ (void *)(offset + head),
+ (void *)(long)(event->header.size),
+ event->header.type);
+
+ /*
+ * assume we lost track of the stream, check alignment, and
+ * increment a single u64 in the hope to catch on again 'soon'.
+ */
+
+ if (unlikely(head & 7))
+ head &= ~7ULL;
+
+ size = 8;
+ }
+
+ head += size;
+
+ if (offset + head >= header->data_offset + header->data_size)
+ goto done;
+
+ if (offset + head < (unsigned long)input_stat.st_size)
+ goto more;
+
+done:
+ err = 0;
+out_close:
+ close(input);
+
+ return err;
+out_delete:
+ perf_header__delete(header);
+ goto out_close;
+}
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h
new file mode 100644
index 000000000000..3180ff7e3633
--- /dev/null
+++ b/tools/perf/util/data_map.h
@@ -0,0 +1,32 @@
+#ifndef __PERF_DATAMAP_H
+#define __PERF_DATAMAP_H
+
+#include "event.h"
+#include "header.h"
+
+typedef int (*event_type_handler_t)(event_t *);
+
+struct perf_file_handler {
+ event_type_handler_t process_sample_event;
+ event_type_handler_t process_mmap_event;
+ event_type_handler_t process_comm_event;
+ event_type_handler_t process_fork_event;
+ event_type_handler_t process_exit_event;
+ event_type_handler_t process_lost_event;
+ event_type_handler_t process_read_event;
+ event_type_handler_t process_throttle_event;
+ event_type_handler_t process_unthrottle_event;
+ int (*sample_type_check)(u64 sample_type);
+ unsigned long total_unknown;
+};
+
+void register_perf_file_handler(struct perf_file_handler *handler);
+int mmap_dispatch_perf_file(struct perf_header **pheader,
+ const char *input_name,
+ int force,
+ int full_paths,
+ int *cwdlen,
+ char **cwd);
+int perf_header__read_build_ids(int input, off_t offset, off_t file_size);
+
+#endif
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index e8ca98fe0bd4..28d520d5a1fb 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -13,12 +13,12 @@
int verbose = 0;
int dump_trace = 0;
-int eprintf(const char *fmt, ...)
+int eprintf(int level, const char *fmt, ...)
{
va_list args;
int ret = 0;
- if (verbose) {
+ if (verbose >= level) {
va_start(args, fmt);
ret = vfprintf(stderr, fmt, args);
va_end(args);
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 437eea58ce40..c6c24c522dea 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -1,8 +1,15 @@
/* For debugging general purposes */
+#ifndef __PERF_DEBUG_H
+#define __PERF_DEBUG_H
+
+#include "event.h"
extern int verbose;
extern int dump_trace;
-int eprintf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
+int eprintf(int level,
+ const char *fmt, ...) __attribute__((format(printf, 2, 3)));
int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
void trace_event(event_t *event);
+
+#endif /* __PERF_DEBUG_H */
diff --git a/tools/perf/util/debugfs.c b/tools/perf/util/debugfs.c
new file mode 100644
index 000000000000..06b73ee02c49
--- /dev/null
+++ b/tools/perf/util/debugfs.c
@@ -0,0 +1,241 @@
+#include "util.h"
+#include "debugfs.h"
+#include "cache.h"
+
+static int debugfs_premounted;
+static char debugfs_mountpoint[MAX_PATH+1];
+
+static const char *debugfs_known_mountpoints[] = {
+ "/sys/kernel/debug/",
+ "/debug/",
+ 0,
+};
+
+/* use this to force a umount */
+void debugfs_force_cleanup(void)
+{
+ debugfs_find_mountpoint();
+ debugfs_premounted = 0;
+ debugfs_umount();
+}
+
+/* construct a full path to a debugfs element */
+int debugfs_make_path(const char *element, char *buffer, int size)
+{
+ int len;
+
+ if (strlen(debugfs_mountpoint) == 0) {
+ buffer[0] = '\0';
+ return -1;
+ }
+
+ len = strlen(debugfs_mountpoint) + strlen(element) + 1;
+ if (len >= size)
+ return len+1;
+
+ snprintf(buffer, size-1, "%s/%s", debugfs_mountpoint, element);
+ return 0;
+}
+
+static int debugfs_found;
+
+/* find the path to the mounted debugfs */
+const char *debugfs_find_mountpoint(void)
+{
+ const char **ptr;
+ char type[100];
+ FILE *fp;
+
+ if (debugfs_found)
+ return (const char *) debugfs_mountpoint;
+
+ ptr = debugfs_known_mountpoints;
+ while (*ptr) {
+ if (debugfs_valid_mountpoint(*ptr) == 0) {
+ debugfs_found = 1;
+ strcpy(debugfs_mountpoint, *ptr);
+ return debugfs_mountpoint;
+ }
+ ptr++;
+ }
+
+ /* give up and parse /proc/mounts */
+ fp = fopen("/proc/mounts", "r");
+ if (fp == NULL)
+ die("Can't open /proc/mounts for read");
+
+ while (fscanf(fp, "%*s %"
+ STR(MAX_PATH)
+ "s %99s %*s %*d %*d\n",
+ debugfs_mountpoint, type) == 2) {
+ if (strcmp(type, "debugfs") == 0)
+ break;
+ }
+ fclose(fp);
+
+ if (strcmp(type, "debugfs") != 0)
+ return NULL;
+
+ debugfs_found = 1;
+
+ return debugfs_mountpoint;
+}
+
+/* verify that a mountpoint is actually a debugfs instance */
+
+int debugfs_valid_mountpoint(const char *debugfs)
+{
+ struct statfs st_fs;
+
+ if (statfs(debugfs, &st_fs) < 0)
+ return -ENOENT;
+ else if (st_fs.f_type != (long) DEBUGFS_MAGIC)
+ return -ENOENT;
+
+ return 0;
+}
+
+
+int debugfs_valid_entry(const char *path)
+{
+ struct stat st;
+
+ if (stat(path, &st))
+ return -errno;
+
+ return 0;
+}
+
+/* mount the debugfs somewhere */
+
+int debugfs_mount(const char *mountpoint)
+{
+ char mountcmd[128];
+
+ /* see if it's already mounted */
+ if (debugfs_find_mountpoint()) {
+ debugfs_premounted = 1;
+ return 0;
+ }
+
+ /* if not mounted and no argument */
+ if (mountpoint == NULL) {
+ /* see if environment variable set */
+ mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT);
+ /* if no environment variable, use default */
+ if (mountpoint == NULL)
+ mountpoint = "/sys/kernel/debug";
+ }
+
+ /* save the mountpoint */
+ strncpy(debugfs_mountpoint, mountpoint, sizeof(debugfs_mountpoint));
+
+ /* mount it */
+ snprintf(mountcmd, sizeof(mountcmd),
+ "/bin/mount -t debugfs debugfs %s", mountpoint);
+ return system(mountcmd);
+}
+
+/* umount the debugfs */
+
+int debugfs_umount(void)
+{
+ char umountcmd[128];
+ int ret;
+
+ /* if it was already mounted, leave it */
+ if (debugfs_premounted)
+ return 0;
+
+ /* make sure it's a valid mount point */
+ ret = debugfs_valid_mountpoint(debugfs_mountpoint);
+ if (ret)
+ return ret;
+
+ snprintf(umountcmd, sizeof(umountcmd),
+ "/bin/umount %s", debugfs_mountpoint);
+ return system(umountcmd);
+}
+
+int debugfs_write(const char *entry, const char *value)
+{
+ char path[MAX_PATH+1];
+ int ret, count;
+ int fd;
+
+ /* construct the path */
+ snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry);
+
+ /* verify that it exists */
+ ret = debugfs_valid_entry(path);
+ if (ret)
+ return ret;
+
+ /* get how many chars we're going to write */
+ count = strlen(value);
+
+ /* open the debugfs entry */
+ fd = open(path, O_RDWR);
+ if (fd < 0)
+ return -errno;
+
+ while (count > 0) {
+ /* write it */
+ ret = write(fd, value, count);
+ if (ret <= 0) {
+ if (ret == EAGAIN)
+ continue;
+ close(fd);
+ return -errno;
+ }
+ count -= ret;
+ }
+
+ /* close it */
+ close(fd);
+
+ /* return success */
+ return 0;
+}
+
+/*
+ * read a debugfs entry
+ * returns the number of chars read or a negative errno
+ */
+int debugfs_read(const char *entry, char *buffer, size_t size)
+{
+ char path[MAX_PATH+1];
+ int ret;
+ int fd;
+
+ /* construct the path */
+ snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry);
+
+ /* verify that it exists */
+ ret = debugfs_valid_entry(path);
+ if (ret)
+ return ret;
+
+ /* open the debugfs entry */
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -errno;
+
+ do {
+ /* read it */
+ ret = read(fd, buffer, size);
+ if (ret == 0) {
+ close(fd);
+ return EOF;
+ }
+ } while (ret < 0 && errno == EAGAIN);
+
+ /* close it */
+ close(fd);
+
+ /* make *sure* there's a null character at the end */
+ buffer[ret] = '\0';
+
+ /* return the number of chars read */
+ return ret;
+}
diff --git a/tools/perf/util/debugfs.h b/tools/perf/util/debugfs.h
new file mode 100644
index 000000000000..3cd14f9ae784
--- /dev/null
+++ b/tools/perf/util/debugfs.h
@@ -0,0 +1,25 @@
+#ifndef __DEBUGFS_H__
+#define __DEBUGFS_H__
+
+#include <sys/mount.h>
+
+#ifndef MAX_PATH
+# define MAX_PATH 256
+#endif
+
+#ifndef STR
+# define _STR(x) #x
+# define STR(x) _STR(x)
+#endif
+
+extern const char *debugfs_find_mountpoint(void);
+extern int debugfs_valid_mountpoint(const char *debugfs);
+extern int debugfs_valid_entry(const char *path);
+extern int debugfs_mount(const char *mountpoint);
+extern int debugfs_umount(void);
+extern int debugfs_write(const char *entry, const char *value);
+extern int debugfs_read(const char *entry, char *buffer, size_t size);
+extern void debugfs_force_cleanup(void);
+extern int debugfs_make_path(const char *element, char *buffer, int size);
+
+#endif /* __DEBUGFS_H__ */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
new file mode 100644
index 000000000000..414b89d1bde9
--- /dev/null
+++ b/tools/perf/util/event.c
@@ -0,0 +1,312 @@
+#include <linux/types.h>
+#include "event.h"
+#include "debug.h"
+#include "string.h"
+#include "thread.h"
+
+static pid_t event__synthesize_comm(pid_t pid, int full,
+ int (*process)(event_t *event))
+{
+ event_t ev;
+ char filename[PATH_MAX];
+ char bf[BUFSIZ];
+ FILE *fp;
+ size_t size = 0;
+ DIR *tasks;
+ struct dirent dirent, *next;
+ pid_t tgid = 0;
+
+ snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+out_race:
+ /*
+ * We raced with a task exiting - just return:
+ */
+ pr_debug("couldn't open %s\n", filename);
+ return 0;
+ }
+
+ memset(&ev.comm, 0, sizeof(ev.comm));
+ while (!ev.comm.comm[0] || !ev.comm.pid) {
+ if (fgets(bf, sizeof(bf), fp) == NULL)
+ goto out_failure;
+
+ if (memcmp(bf, "Name:", 5) == 0) {
+ char *name = bf + 5;
+ while (*name && isspace(*name))
+ ++name;
+ size = strlen(name) - 1;
+ memcpy(ev.comm.comm, name, size++);
+ } else if (memcmp(bf, "Tgid:", 5) == 0) {
+ char *tgids = bf + 5;
+ while (*tgids && isspace(*tgids))
+ ++tgids;
+ tgid = ev.comm.pid = atoi(tgids);
+ }
+ }
+
+ ev.comm.header.type = PERF_RECORD_COMM;
+ size = ALIGN(size, sizeof(u64));
+ ev.comm.header.size = sizeof(ev.comm) - (sizeof(ev.comm.comm) - size);
+
+ if (!full) {
+ ev.comm.tid = pid;
+
+ process(&ev);
+ goto out_fclose;
+ }
+
+ snprintf(filename, sizeof(filename), "/proc/%d/task", pid);
+
+ tasks = opendir(filename);
+ if (tasks == NULL)
+ goto out_race;
+
+ while (!readdir_r(tasks, &dirent, &next) && next) {
+ char *end;
+ pid = strtol(dirent.d_name, &end, 10);
+ if (*end)
+ continue;
+
+ ev.comm.tid = pid;
+
+ process(&ev);
+ }
+ closedir(tasks);
+
+out_fclose:
+ fclose(fp);
+ return tgid;
+
+out_failure:
+ pr_warning("couldn't get COMM and pgid, malformed %s\n", filename);
+ return -1;
+}
+
+static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
+ int (*process)(event_t *event))
+{
+ char filename[PATH_MAX];
+ FILE *fp;
+
+ snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ /*
+ * We raced with a task exiting - just return:
+ */
+ pr_debug("couldn't open %s\n", filename);
+ return -1;
+ }
+
+ while (1) {
+ char bf[BUFSIZ], *pbf = bf;
+ event_t ev = {
+ .header = { .type = PERF_RECORD_MMAP },
+ };
+ int n;
+ size_t size;
+ if (fgets(bf, sizeof(bf), fp) == NULL)
+ break;
+
+ /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */
+ n = hex2u64(pbf, &ev.mmap.start);
+ if (n < 0)
+ continue;
+ pbf += n + 1;
+ n = hex2u64(pbf, &ev.mmap.len);
+ if (n < 0)
+ continue;
+ pbf += n + 3;
+ if (*pbf == 'x') { /* vm_exec */
+ char *execname = strchr(bf, '/');
+
+ /* Catch VDSO */
+ if (execname == NULL)
+ execname = strstr(bf, "[vdso]");
+
+ if (execname == NULL)
+ continue;
+
+ size = strlen(execname);
+ execname[size - 1] = '\0'; /* Remove \n */
+ memcpy(ev.mmap.filename, execname, size);
+ size = ALIGN(size, sizeof(u64));
+ ev.mmap.len -= ev.mmap.start;
+ ev.mmap.header.size = (sizeof(ev.mmap) -
+ (sizeof(ev.mmap.filename) - size));
+ ev.mmap.pid = tgid;
+ ev.mmap.tid = pid;
+
+ process(&ev);
+ }
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+int event__synthesize_thread(pid_t pid, int (*process)(event_t *event))
+{
+ pid_t tgid = event__synthesize_comm(pid, 1, process);
+ if (tgid == -1)
+ return -1;
+ return event__synthesize_mmap_events(pid, tgid, process);
+}
+
+void event__synthesize_threads(int (*process)(event_t *event))
+{
+ DIR *proc;
+ struct dirent dirent, *next;
+
+ proc = opendir("/proc");
+
+ while (!readdir_r(proc, &dirent, &next) && next) {
+ char *end;
+ pid_t pid = strtol(dirent.d_name, &end, 10);
+
+ if (*end) /* only interested in proper numerical dirents */
+ continue;
+
+ event__synthesize_thread(pid, process);
+ }
+
+ closedir(proc);
+}
+
+char *event__cwd;
+int event__cwdlen;
+
+struct events_stats event__stats;
+
+int event__process_comm(event_t *self)
+{
+ struct thread *thread = threads__findnew(self->comm.pid);
+
+ dump_printf(": %s:%d\n", self->comm.comm, self->comm.pid);
+
+ if (thread == NULL || thread__set_comm(thread, self->comm.comm)) {
+ dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int event__process_lost(event_t *self)
+{
+ dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost);
+ event__stats.lost += self->lost.lost;
+ return 0;
+}
+
+int event__process_mmap(event_t *self)
+{
+ struct thread *thread = threads__findnew(self->mmap.pid);
+ struct map *map = map__new(&self->mmap, MAP__FUNCTION,
+ event__cwd, event__cwdlen);
+
+ dump_printf(" %d/%d: [%p(%p) @ %p]: %s\n",
+ self->mmap.pid, self->mmap.tid,
+ (void *)(long)self->mmap.start,
+ (void *)(long)self->mmap.len,
+ (void *)(long)self->mmap.pgoff,
+ self->mmap.filename);
+
+ if (thread == NULL || map == NULL)
+ dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
+ else
+ thread__insert_map(thread, map);
+
+ return 0;
+}
+
+int event__process_task(event_t *self)
+{
+ struct thread *thread = threads__findnew(self->fork.pid);
+ struct thread *parent = threads__findnew(self->fork.ppid);
+
+ dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid,
+ self->fork.ppid, self->fork.ptid);
+ /*
+ * A thread clone will have the same PID for both parent and child.
+ */
+ if (thread == parent)
+ return 0;
+
+ if (self->header.type == PERF_RECORD_EXIT)
+ return 0;
+
+ if (thread == NULL || parent == NULL ||
+ thread__fork(thread, parent) < 0) {
+ dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+void thread__find_addr_location(struct thread *self, u8 cpumode,
+ enum map_type type, u64 addr,
+ struct addr_location *al,
+ symbol_filter_t filter)
+{
+ struct thread *thread = al->thread = self;
+
+ al->addr = addr;
+
+ if (cpumode & PERF_RECORD_MISC_KERNEL) {
+ al->level = 'k';
+ thread = kthread;
+ } else if (cpumode & PERF_RECORD_MISC_USER)
+ al->level = '.';
+ else {
+ al->level = 'H';
+ al->map = NULL;
+ al->sym = NULL;
+ return;
+ }
+try_again:
+ al->map = thread__find_map(thread, type, al->addr);
+ if (al->map == NULL) {
+ /*
+ * If this is outside of all known maps, and is a negative
+ * address, try to look it up in the kernel dso, as it might be
+ * a vsyscall or vdso (which executes in user-mode).
+ *
+ * XXX This is nasty, we should have a symbol list in the
+ * "[vdso]" dso, but for now lets use the old trick of looking
+ * in the whole kernel symbol list.
+ */
+ if ((long long)al->addr < 0 && thread != kthread) {
+ thread = kthread;
+ goto try_again;
+ }
+ al->sym = NULL;
+ } else {
+ al->addr = al->map->map_ip(al->map, al->addr);
+ al->sym = map__find_symbol(al->map, al->addr, filter);
+ }
+}
+
+int event__preprocess_sample(const event_t *self, struct addr_location *al,
+ symbol_filter_t filter)
+{
+ u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+ struct thread *thread = threads__findnew(self->ip.pid);
+
+ if (thread == NULL)
+ return -1;
+
+ dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
+
+ thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
+ self->ip.ip, al, filter);
+ dump_printf(" ...... dso: %s\n",
+ al->map ? al->map->dso->long_name :
+ al->level == 'H' ? "[hypervisor]" : "<not found>");
+ return 0;
+}
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 2c9c26d6ded0..a4cc8105cf67 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -1,14 +1,10 @@
#ifndef __PERF_RECORD_H
#define __PERF_RECORD_H
+
#include "../perf.h"
#include "util.h"
#include <linux/list.h>
-
-enum {
- SHOW_KERNEL = 1,
- SHOW_USER = 2,
- SHOW_HV = 4,
-};
+#include <linux/rbtree.h>
/*
* PERF_SAMPLE_IP | PERF_SAMPLE_TID | *
@@ -65,6 +61,13 @@ struct sample_event{
u64 array[];
};
+#define BUILD_ID_SIZE 20
+
+struct build_id_event {
+ struct perf_event_header header;
+ u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))];
+ char filename[];
+};
typedef union event_union {
struct perf_event_header header;
@@ -77,12 +80,30 @@ typedef union event_union {
struct sample_event sample;
} event_t;
+struct events_stats {
+ unsigned long total;
+ unsigned long lost;
+};
+
+void event__print_totals(void);
+
+enum map_type {
+ MAP__FUNCTION = 0,
+
+ MAP__NR_TYPES,
+};
+
struct map {
- struct list_head node;
+ union {
+ struct rb_node rb_node;
+ struct list_head node;
+ };
u64 start;
u64 end;
+ enum map_type type;
u64 pgoff;
u64 (*map_ip)(struct map *, u64);
+ u64 (*unmap_ip)(struct map *, u64);
struct dso *dso;
};
@@ -91,14 +112,48 @@ static inline u64 map__map_ip(struct map *map, u64 ip)
return ip - map->start + map->pgoff;
}
-static inline u64 vdso__map_ip(struct map *map __used, u64 ip)
+static inline u64 map__unmap_ip(struct map *map, u64 ip)
+{
+ return ip + map->start - map->pgoff;
+}
+
+static inline u64 identity__map_ip(struct map *map __used, u64 ip)
{
return ip;
}
-struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen);
+struct symbol;
+
+typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
+
+void map__init(struct map *self, enum map_type type,
+ u64 start, u64 end, u64 pgoff, struct dso *dso);
+struct map *map__new(struct mmap_event *event, enum map_type,
+ char *cwd, int cwdlen);
+void map__delete(struct map *self);
struct map *map__clone(struct map *self);
int map__overlap(struct map *l, struct map *r);
size_t map__fprintf(struct map *self, FILE *fp);
+struct symbol *map__find_symbol(struct map *self, u64 addr,
+ symbol_filter_t filter);
+void map__fixup_start(struct map *self);
+void map__fixup_end(struct map *self);
+
+int event__synthesize_thread(pid_t pid, int (*process)(event_t *event));
+void event__synthesize_threads(int (*process)(event_t *event));
+
+extern char *event__cwd;
+extern int event__cwdlen;
+extern struct events_stats event__stats;
+extern unsigned long event__total[PERF_RECORD_MAX];
+
+int event__process_comm(event_t *self);
+int event__process_lost(event_t *self);
+int event__process_mmap(event_t *self);
+int event__process_task(event_t *self);
+
+struct addr_location;
+int event__preprocess_sample(const event_t *self, struct addr_location *al,
+ symbol_filter_t filter);
-#endif
+#endif /* __PERF_RECORD_H */
diff --git a/tools/perf/util/exec_cmd.h b/tools/perf/util/exec_cmd.h
index effe25eb1545..31647ac92ed1 100644
--- a/tools/perf/util/exec_cmd.h
+++ b/tools/perf/util/exec_cmd.h
@@ -1,5 +1,5 @@
-#ifndef PERF_EXEC_CMD_H
-#define PERF_EXEC_CMD_H
+#ifndef __PERF_EXEC_CMD_H
+#define __PERF_EXEC_CMD_H
extern void perf_set_argv_exec_path(const char *exec_path);
extern const char *perf_extract_argv0_path(const char *path);
@@ -10,4 +10,4 @@ extern int execv_perf_cmd(const char **argv); /* NULL terminated */
extern int execl_perf_cmd(const char *cmd, ...);
extern const char *system_path(const char *path);
-#endif /* PERF_EXEC_CMD_H */
+#endif /* __PERF_EXEC_CMD_H */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index e306857b2c2b..4805e6dfd23c 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2,9 +2,15 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <linux/list.h>
#include "util.h"
#include "header.h"
+#include "../perf.h"
+#include "trace-event.h"
+#include "symbol.h"
+#include "data_map.h"
+#include "debug.h"
/*
* Create new perf.data header attribute:
@@ -13,32 +19,43 @@ struct perf_header_attr *perf_header_attr__new(struct perf_event_attr *attr)
{
struct perf_header_attr *self = malloc(sizeof(*self));
- if (!self)
- die("nomem");
-
- self->attr = *attr;
- self->ids = 0;
- self->size = 1;
- self->id = malloc(sizeof(u64));
-
- if (!self->id)
- die("nomem");
+ if (self != NULL) {
+ self->attr = *attr;
+ self->ids = 0;
+ self->size = 1;
+ self->id = malloc(sizeof(u64));
+ if (self->id == NULL) {
+ free(self);
+ self = NULL;
+ }
+ }
return self;
}
-void perf_header_attr__add_id(struct perf_header_attr *self, u64 id)
+void perf_header_attr__delete(struct perf_header_attr *self)
+{
+ free(self->id);
+ free(self);
+}
+
+int perf_header_attr__add_id(struct perf_header_attr *self, u64 id)
{
int pos = self->ids;
self->ids++;
if (self->ids > self->size) {
- self->size *= 2;
- self->id = realloc(self->id, self->size * sizeof(u64));
- if (!self->id)
- die("nomem");
+ int nsize = self->size * 2;
+ u64 *nid = realloc(self->id, nsize * sizeof(u64));
+
+ if (nid == NULL)
+ return -1;
+
+ self->size = nsize;
+ self->id = nid;
}
self->id[pos] = id;
+ return 0;
}
/*
@@ -46,42 +63,52 @@ void perf_header_attr__add_id(struct perf_header_attr *self, u64 id)
*/
struct perf_header *perf_header__new(void)
{
- struct perf_header *self = malloc(sizeof(*self));
+ struct perf_header *self = zalloc(sizeof(*self));
- if (!self)
- die("nomem");
+ if (self != NULL) {
+ self->size = 1;
+ self->attr = malloc(sizeof(void *));
- self->frozen = 0;
+ if (self->attr == NULL) {
+ free(self);
+ self = NULL;
+ }
+ }
- self->attrs = 0;
- self->size = 1;
- self->attr = malloc(sizeof(void *));
+ return self;
+}
- if (!self->attr)
- die("nomem");
+void perf_header__delete(struct perf_header *self)
+{
+ int i;
- self->data_offset = 0;
- self->data_size = 0;
+ for (i = 0; i < self->attrs; ++i)
+ perf_header_attr__delete(self->attr[i]);
- return self;
+ free(self->attr);
+ free(self);
}
-void perf_header__add_attr(struct perf_header *self,
- struct perf_header_attr *attr)
+int perf_header__add_attr(struct perf_header *self,
+ struct perf_header_attr *attr)
{
- int pos = self->attrs;
-
if (self->frozen)
- die("frozen");
+ return -1;
- self->attrs++;
- if (self->attrs > self->size) {
- self->size *= 2;
- self->attr = realloc(self->attr, self->size * sizeof(void *));
- if (!self->attr)
- die("nomem");
+ if (self->attrs == self->size) {
+ int nsize = self->size * 2;
+ struct perf_header_attr **nattr;
+
+ nattr = realloc(self->attr, nsize * sizeof(void *));
+ if (nattr == NULL)
+ return -1;
+
+ self->size = nsize;
+ self->attr = nattr;
}
- self->attr[pos] = attr;
+
+ self->attr[self->attrs++] = attr;
+ return 0;
}
#define MAX_EVENT_NAME 64
@@ -97,7 +124,7 @@ static struct perf_trace_event_type *events;
void perf_header__push_event(u64 id, const char *name)
{
if (strlen(name) > MAX_EVENT_NAME)
- printf("Event %s will be truncated\n", name);
+ pr_warning("Event %s will be truncated\n", name);
if (!events) {
events = malloc(sizeof(struct perf_trace_event_type));
@@ -128,44 +155,137 @@ static const char *__perf_magic = "PERFFILE";
#define PERF_MAGIC (*(u64 *)__perf_magic)
-struct perf_file_section {
- u64 offset;
- u64 size;
-};
-
struct perf_file_attr {
struct perf_event_attr attr;
struct perf_file_section ids;
};
-struct perf_file_header {
- u64 magic;
- u64 size;
- u64 attr_size;
- struct perf_file_section attrs;
- struct perf_file_section data;
- struct perf_file_section event_types;
-};
+void perf_header__set_feat(struct perf_header *self, int feat)
+{
+ set_bit(feat, self->adds_features);
+}
-static void do_write(int fd, void *buf, size_t size)
+bool perf_header__has_feat(const struct perf_header *self, int feat)
+{
+ return test_bit(feat, self->adds_features);
+}
+
+static int do_write(int fd, const void *buf, size_t size)
{
while (size) {
int ret = write(fd, buf, size);
if (ret < 0)
- die("failed to write");
+ return -errno;
size -= ret;
buf += ret;
}
+
+ return 0;
+}
+
+static int __dsos__write_buildid_table(struct list_head *head, int fd)
+{
+ struct dso *pos;
+
+ list_for_each_entry(pos, head, node) {
+ int err;
+ struct build_id_event b;
+ size_t len;
+
+ if (!pos->has_build_id)
+ continue;
+ len = pos->long_name_len + 1;
+ len = ALIGN(len, 64);
+ memset(&b, 0, sizeof(b));
+ memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id));
+ b.header.size = sizeof(b) + len;
+ err = do_write(fd, &b, sizeof(b));
+ if (err < 0)
+ return err;
+ err = do_write(fd, pos->long_name, len);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
}
-void perf_header__write(struct perf_header *self, int fd)
+static int dsos__write_buildid_table(int fd)
+{
+ int err = __dsos__write_buildid_table(&dsos__kernel, fd);
+ if (err == 0)
+ err = __dsos__write_buildid_table(&dsos__user, fd);
+ return err;
+}
+
+static int perf_header__adds_write(struct perf_header *self, int fd)
+{
+ int nr_sections;
+ struct perf_file_section *feat_sec;
+ int sec_size;
+ u64 sec_start;
+ int idx = 0, err;
+
+ if (dsos__read_build_ids())
+ perf_header__set_feat(self, HEADER_BUILD_ID);
+
+ nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
+ if (!nr_sections)
+ return 0;
+
+ feat_sec = calloc(sizeof(*feat_sec), nr_sections);
+ if (feat_sec == NULL)
+ return -ENOMEM;
+
+ sec_size = sizeof(*feat_sec) * nr_sections;
+
+ sec_start = self->data_offset + self->data_size;
+ lseek(fd, sec_start + sec_size, SEEK_SET);
+
+ if (perf_header__has_feat(self, HEADER_TRACE_INFO)) {
+ struct perf_file_section *trace_sec;
+
+ trace_sec = &feat_sec[idx++];
+
+ /* Write trace info */
+ trace_sec->offset = lseek(fd, 0, SEEK_CUR);
+ read_tracing_data(fd, attrs, nr_counters);
+ trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset;
+ }
+
+
+ if (perf_header__has_feat(self, HEADER_BUILD_ID)) {
+ struct perf_file_section *buildid_sec;
+
+ buildid_sec = &feat_sec[idx++];
+
+ /* Write build-ids */
+ buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
+ err = dsos__write_buildid_table(fd);
+ if (err < 0) {
+ pr_debug("failed to write buildid table\n");
+ goto out_free;
+ }
+ buildid_sec->size = lseek(fd, 0, SEEK_CUR) - buildid_sec->offset;
+ }
+
+ lseek(fd, sec_start, SEEK_SET);
+ err = do_write(fd, feat_sec, sec_size);
+ if (err < 0)
+ pr_debug("failed to write feature section\n");
+out_free:
+ free(feat_sec);
+ return err;
+}
+
+int perf_header__write(struct perf_header *self, int fd, bool at_exit)
{
struct perf_file_header f_header;
struct perf_file_attr f_attr;
struct perf_header_attr *attr;
- int i;
+ int i, err;
lseek(fd, sizeof(f_header), SEEK_SET);
@@ -174,7 +294,11 @@ void perf_header__write(struct perf_header *self, int fd)
attr = self->attr[i];
attr->id_offset = lseek(fd, 0, SEEK_CUR);
- do_write(fd, attr->id, attr->ids * sizeof(u64));
+ err = do_write(fd, attr->id, attr->ids * sizeof(u64));
+ if (err < 0) {
+ pr_debug("failed to write perf header\n");
+ return err;
+ }
}
@@ -190,17 +314,31 @@ void perf_header__write(struct perf_header *self, int fd)
.size = attr->ids * sizeof(u64),
}
};
- do_write(fd, &f_attr, sizeof(f_attr));
+ err = do_write(fd, &f_attr, sizeof(f_attr));
+ if (err < 0) {
+ pr_debug("failed to write perf header attribute\n");
+ return err;
+ }
}
self->event_offset = lseek(fd, 0, SEEK_CUR);
self->event_size = event_count * sizeof(struct perf_trace_event_type);
- if (events)
- do_write(fd, events, self->event_size);
-
+ if (events) {
+ err = do_write(fd, events, self->event_size);
+ if (err < 0) {
+ pr_debug("failed to write perf header events\n");
+ return err;
+ }
+ }
self->data_offset = lseek(fd, 0, SEEK_CUR);
+ if (at_exit) {
+ err = perf_header__adds_write(self, fd);
+ if (err < 0)
+ return err;
+ }
+
f_header = (struct perf_file_header){
.magic = PERF_MAGIC,
.size = sizeof(f_header),
@@ -219,11 +357,18 @@ void perf_header__write(struct perf_header *self, int fd)
},
};
+ memcpy(&f_header.adds_features, &self->adds_features, sizeof(self->adds_features));
+
lseek(fd, 0, SEEK_SET);
- do_write(fd, &f_header, sizeof(f_header));
+ err = do_write(fd, &f_header, sizeof(f_header));
+ if (err < 0) {
+ pr_debug("failed to write perf header\n");
+ return err;
+ }
lseek(fd, self->data_offset + self->data_size, SEEK_SET);
self->frozen = 1;
+ return 0;
}
static void do_read(int fd, void *buf, size_t size)
@@ -241,22 +386,109 @@ static void do_read(int fd, void *buf, size_t size)
}
}
-struct perf_header *perf_header__read(int fd)
+int perf_header__process_sections(struct perf_header *self, int fd,
+ int (*process)(struct perf_file_section *self,
+ int feat, int fd))
+{
+ struct perf_file_section *feat_sec;
+ int nr_sections;
+ int sec_size;
+ int idx = 0;
+ int err = 0, feat = 1;
+
+ nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
+ if (!nr_sections)
+ return 0;
+
+ feat_sec = calloc(sizeof(*feat_sec), nr_sections);
+ if (!feat_sec)
+ return -1;
+
+ sec_size = sizeof(*feat_sec) * nr_sections;
+
+ lseek(fd, self->data_offset + self->data_size, SEEK_SET);
+
+ do_read(fd, feat_sec, sec_size);
+
+ while (idx < nr_sections && feat < HEADER_LAST_FEATURE) {
+ if (perf_header__has_feat(self, feat)) {
+ struct perf_file_section *sec = &feat_sec[idx++];
+
+ err = process(sec, feat, fd);
+ if (err < 0)
+ break;
+ }
+ ++feat;
+ }
+
+ free(feat_sec);
+ return err;
+};
+
+int perf_file_header__read(struct perf_file_header *self,
+ struct perf_header *ph, int fd)
+{
+ lseek(fd, 0, SEEK_SET);
+ do_read(fd, self, sizeof(*self));
+
+ if (self->magic != PERF_MAGIC ||
+ self->attr_size != sizeof(struct perf_file_attr))
+ return -1;
+
+ if (self->size != sizeof(*self)) {
+ /* Support the previous format */
+ if (self->size == offsetof(typeof(*self), adds_features))
+ bitmap_zero(self->adds_features, HEADER_FEAT_BITS);
+ else
+ return -1;
+ }
+
+ memcpy(&ph->adds_features, &self->adds_features,
+ sizeof(self->adds_features));
+
+ ph->event_offset = self->event_types.offset;
+ ph->event_size = self->event_types.size;
+ ph->data_offset = self->data.offset;
+ ph->data_size = self->data.size;
+ return 0;
+}
+
+static int perf_file_section__process(struct perf_file_section *self,
+ int feat, int fd)
+{
+ if (lseek(fd, self->offset, SEEK_SET) < 0) {
+ pr_debug("Failed to lseek to %Ld offset for feature %d, "
+ "continuing...\n", self->offset, feat);
+ return 0;
+ }
+
+ switch (feat) {
+ case HEADER_TRACE_INFO:
+ trace_report(fd);
+ break;
+
+ case HEADER_BUILD_ID:
+ if (perf_header__read_build_ids(fd, self->offset, self->size))
+ pr_debug("Failed to read buildids, continuing...\n");
+ break;
+ default:
+ pr_debug("unknown feature %d, continuing...\n", feat);
+ }
+
+ return 0;
+}
+
+int perf_header__read(struct perf_header *self, int fd)
{
- struct perf_header *self = perf_header__new();
struct perf_file_header f_header;
struct perf_file_attr f_attr;
u64 f_id;
-
int nr_attrs, nr_ids, i, j;
- lseek(fd, 0, SEEK_SET);
- do_read(fd, &f_header, sizeof(f_header));
-
- if (f_header.magic != PERF_MAGIC ||
- f_header.size != sizeof(f_header) ||
- f_header.attr_size != sizeof(f_attr))
- die("incompatible file format");
+ if (perf_file_header__read(&f_header, self, fd) < 0) {
+ pr_debug("incompatible file format\n");
+ return -EINVAL;
+ }
nr_attrs = f_header.attrs.size / sizeof(f_attr);
lseek(fd, f_header.attrs.offset, SEEK_SET);
@@ -269,6 +501,8 @@ struct perf_header *perf_header__read(int fd)
tmp = lseek(fd, 0, SEEK_CUR);
attr = perf_header_attr__new(&f_attr.attr);
+ if (attr == NULL)
+ return -ENOMEM;
nr_ids = f_attr.ids.size / sizeof(u64);
lseek(fd, f_attr.ids.offset, SEEK_SET);
@@ -276,31 +510,34 @@ struct perf_header *perf_header__read(int fd)
for (j = 0; j < nr_ids; j++) {
do_read(fd, &f_id, sizeof(f_id));
- perf_header_attr__add_id(attr, f_id);
+ if (perf_header_attr__add_id(attr, f_id) < 0) {
+ perf_header_attr__delete(attr);
+ return -ENOMEM;
+ }
}
- perf_header__add_attr(self, attr);
+ if (perf_header__add_attr(self, attr) < 0) {
+ perf_header_attr__delete(attr);
+ return -ENOMEM;
+ }
+
lseek(fd, tmp, SEEK_SET);
}
if (f_header.event_types.size) {
lseek(fd, f_header.event_types.offset, SEEK_SET);
events = malloc(f_header.event_types.size);
- if (!events)
- die("nomem");
+ if (events == NULL)
+ return -ENOMEM;
do_read(fd, events, f_header.event_types.size);
event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
}
- self->event_offset = f_header.event_types.offset;
- self->event_size = f_header.event_types.size;
- self->data_offset = f_header.data.offset;
- self->data_size = f_header.data.size;
+ perf_header__process_sections(self, fd, perf_file_section__process);
lseek(fd, self->data_offset, SEEK_SET);
self->frozen = 1;
-
- return self;
+ return 0;
}
u64 perf_header__sample_type(struct perf_header *header)
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index a0761bc7863c..d1dbe2b79c42 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -1,10 +1,13 @@
-#ifndef _PERF_HEADER_H
-#define _PERF_HEADER_H
+#ifndef __PERF_HEADER_H
+#define __PERF_HEADER_H
#include "../../../include/linux/perf_event.h"
#include <sys/types.h>
+#include <stdbool.h>
#include "types.h"
+#include <linux/bitmap.h>
+
struct perf_header_attr {
struct perf_event_attr attr;
int ids, size;
@@ -12,36 +15,71 @@ struct perf_header_attr {
off_t id_offset;
};
+enum {
+ HEADER_TRACE_INFO = 1,
+ HEADER_BUILD_ID,
+ HEADER_LAST_FEATURE,
+};
+
+#define HEADER_FEAT_BITS 256
+
+struct perf_file_section {
+ u64 offset;
+ u64 size;
+};
+
+struct perf_file_header {
+ u64 magic;
+ u64 size;
+ u64 attr_size;
+ struct perf_file_section attrs;
+ struct perf_file_section data;
+ struct perf_file_section event_types;
+ DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
+};
+
+struct perf_header;
+
+int perf_file_header__read(struct perf_file_header *self,
+ struct perf_header *ph, int fd);
+
struct perf_header {
- int frozen;
- int attrs, size;
+ int frozen;
+ int attrs, size;
struct perf_header_attr **attr;
- s64 attr_offset;
- u64 data_offset;
- u64 data_size;
- u64 event_offset;
- u64 event_size;
+ s64 attr_offset;
+ u64 data_offset;
+ u64 data_size;
+ u64 event_offset;
+ u64 event_size;
+ DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
};
-struct perf_header *perf_header__read(int fd);
-void perf_header__write(struct perf_header *self, int fd);
+struct perf_header *perf_header__new(void);
+void perf_header__delete(struct perf_header *self);
-void perf_header__add_attr(struct perf_header *self,
- struct perf_header_attr *attr);
+int perf_header__read(struct perf_header *self, int fd);
+int perf_header__write(struct perf_header *self, int fd, bool at_exit);
+
+int perf_header__add_attr(struct perf_header *self,
+ struct perf_header_attr *attr);
void perf_header__push_event(u64 id, const char *name);
char *perf_header__find_event(u64 id);
+struct perf_header_attr *perf_header_attr__new(struct perf_event_attr *attr);
+void perf_header_attr__delete(struct perf_header_attr *self);
-struct perf_header_attr *
-perf_header_attr__new(struct perf_event_attr *attr);
-void perf_header_attr__add_id(struct perf_header_attr *self, u64 id);
+int perf_header_attr__add_id(struct perf_header_attr *self, u64 id);
u64 perf_header__sample_type(struct perf_header *header);
struct perf_event_attr *
perf_header__find_attr(u64 id, struct perf_header *header);
+void perf_header__set_feat(struct perf_header *self, int feat);
+bool perf_header__has_feat(const struct perf_header *self, int feat);
+int perf_header__process_sections(struct perf_header *self, int fd,
+ int (*process)(struct perf_file_section *self,
+ int feat, int fd));
-struct perf_header *perf_header__new(void);
-
-#endif /* _PERF_HEADER_H */
+#endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/help.h b/tools/perf/util/help.h
index 7128783637b4..7f5c6dedd714 100644
--- a/tools/perf/util/help.h
+++ b/tools/perf/util/help.h
@@ -1,5 +1,5 @@
-#ifndef HELP_H
-#define HELP_H
+#ifndef __PERF_HELP_H
+#define __PERF_HELP_H
struct cmdnames {
size_t alloc;
@@ -26,4 +26,4 @@ int is_in_cmdlist(struct cmdnames *c, const char *s);
void list_commands(const char *title, struct cmdnames *main_cmds,
struct cmdnames *other_cmds);
-#endif /* HELP_H */
+#endif /* __PERF_HELP_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
new file mode 100644
index 000000000000..0ebf6ee16caa
--- /dev/null
+++ b/tools/perf/util/hist.c
@@ -0,0 +1,202 @@
+#include "hist.h"
+
+struct rb_root hist;
+struct rb_root collapse_hists;
+struct rb_root output_hists;
+int callchain;
+
+struct callchain_param callchain_param = {
+ .mode = CHAIN_GRAPH_REL,
+ .min_percent = 0.5
+};
+
+/*
+ * histogram, sorted on item, collects counts
+ */
+
+struct hist_entry *__hist_entry__add(struct addr_location *al,
+ struct symbol *sym_parent,
+ u64 count, bool *hit)
+{
+ struct rb_node **p = &hist.rb_node;
+ struct rb_node *parent = NULL;
+ struct hist_entry *he;
+ struct hist_entry entry = {
+ .thread = al->thread,
+ .map = al->map,
+ .sym = al->sym,
+ .ip = al->addr,
+ .level = al->level,
+ .count = count,
+ .parent = sym_parent,
+ };
+ int cmp;
+
+ while (*p != NULL) {
+ parent = *p;
+ he = rb_entry(parent, struct hist_entry, rb_node);
+
+ cmp = hist_entry__cmp(&entry, he);
+
+ if (!cmp) {
+ *hit = true;
+ return he;
+ }
+
+ if (cmp < 0)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ he = malloc(sizeof(*he));
+ if (!he)
+ return NULL;
+ *he = entry;
+ rb_link_node(&he->rb_node, parent, p);
+ rb_insert_color(&he->rb_node, &hist);
+ *hit = false;
+ return he;
+}
+
+int64_t
+hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ struct sort_entry *se;
+ int64_t cmp = 0;
+
+ list_for_each_entry(se, &hist_entry__sort_list, list) {
+ cmp = se->cmp(left, right);
+ if (cmp)
+ break;
+ }
+
+ return cmp;
+}
+
+int64_t
+hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
+{
+ struct sort_entry *se;
+ int64_t cmp = 0;
+
+ list_for_each_entry(se, &hist_entry__sort_list, list) {
+ int64_t (*f)(struct hist_entry *, struct hist_entry *);
+
+ f = se->collapse ?: se->cmp;
+
+ cmp = f(left, right);
+ if (cmp)
+ break;
+ }
+
+ return cmp;
+}
+
+void hist_entry__free(struct hist_entry *he)
+{
+ free(he);
+}
+
+/*
+ * collapse the histogram
+ */
+
+void collapse__insert_entry(struct hist_entry *he)
+{
+ struct rb_node **p = &collapse_hists.rb_node;
+ struct rb_node *parent = NULL;
+ struct hist_entry *iter;
+ int64_t cmp;
+
+ while (*p != NULL) {
+ parent = *p;
+ iter = rb_entry(parent, struct hist_entry, rb_node);
+
+ cmp = hist_entry__collapse(iter, he);
+
+ if (!cmp) {
+ iter->count += he->count;
+ hist_entry__free(he);
+ return;
+ }
+
+ if (cmp < 0)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&he->rb_node, parent, p);
+ rb_insert_color(&he->rb_node, &collapse_hists);
+}
+
+void collapse__resort(void)
+{
+ struct rb_node *next;
+ struct hist_entry *n;
+
+ if (!sort__need_collapse)
+ return;
+
+ next = rb_first(&hist);
+ while (next) {
+ n = rb_entry(next, struct hist_entry, rb_node);
+ next = rb_next(&n->rb_node);
+
+ rb_erase(&n->rb_node, &hist);
+ collapse__insert_entry(n);
+ }
+}
+
+/*
+ * reverse the map, sort on count.
+ */
+
+void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
+{
+ struct rb_node **p = &output_hists.rb_node;
+ struct rb_node *parent = NULL;
+ struct hist_entry *iter;
+
+ if (callchain)
+ callchain_param.sort(&he->sorted_chain, &he->callchain,
+ min_callchain_hits, &callchain_param);
+
+ while (*p != NULL) {
+ parent = *p;
+ iter = rb_entry(parent, struct hist_entry, rb_node);
+
+ if (he->count > iter->count)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&he->rb_node, parent, p);
+ rb_insert_color(&he->rb_node, &output_hists);
+}
+
+void output__resort(u64 total_samples)
+{
+ struct rb_node *next;
+ struct hist_entry *n;
+ struct rb_root *tree = &hist;
+ u64 min_callchain_hits;
+
+ min_callchain_hits =
+ total_samples * (callchain_param.min_percent / 100);
+
+ if (sort__need_collapse)
+ tree = &collapse_hists;
+
+ next = rb_first(tree);
+
+ while (next) {
+ n = rb_entry(next, struct hist_entry, rb_node);
+ next = rb_next(&n->rb_node);
+
+ rb_erase(&n->rb_node, tree);
+ output__insert_entry(n, min_callchain_hits);
+ }
+}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
new file mode 100644
index 000000000000..3020db0c9292
--- /dev/null
+++ b/tools/perf/util/hist.h
@@ -0,0 +1,50 @@
+#ifndef __PERF_HIST_H
+#define __PERF_HIST_H
+#include "../builtin.h"
+
+#include "util.h"
+
+#include "color.h"
+#include <linux/list.h>
+#include "cache.h"
+#include <linux/rbtree.h>
+#include "symbol.h"
+#include "string.h"
+#include "callchain.h"
+#include "strlist.h"
+#include "values.h"
+
+#include "../perf.h"
+#include "debug.h"
+#include "header.h"
+
+#include "parse-options.h"
+#include "parse-events.h"
+
+#include "thread.h"
+#include "sort.h"
+
+extern struct rb_root hist;
+extern struct rb_root collapse_hists;
+extern struct rb_root output_hists;
+extern int callchain;
+extern struct callchain_param callchain_param;
+extern unsigned long total;
+extern unsigned long total_mmap;
+extern unsigned long total_comm;
+extern unsigned long total_fork;
+extern unsigned long total_unknown;
+extern unsigned long total_lost;
+
+struct hist_entry *__hist_entry__add(struct addr_location *al,
+ struct symbol *parent,
+ u64 count, bool *hit);
+extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
+extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
+extern void hist_entry__free(struct hist_entry *);
+extern void collapse__insert_entry(struct hist_entry *);
+extern void collapse__resort(void);
+extern void output__insert_entry(struct hist_entry *, u64);
+extern void output__resort(u64);
+
+#endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/include/asm/asm-offsets.h b/tools/perf/util/include/asm/asm-offsets.h
new file mode 100644
index 000000000000..ed538942523d
--- /dev/null
+++ b/tools/perf/util/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+/* stub */
diff --git a/tools/perf/util/include/asm/bitops.h b/tools/perf/util/include/asm/bitops.h
new file mode 100644
index 000000000000..58e9817ffae0
--- /dev/null
+++ b/tools/perf/util/include/asm/bitops.h
@@ -0,0 +1,18 @@
+#ifndef _PERF_ASM_BITOPS_H_
+#define _PERF_ASM_BITOPS_H_
+
+#include <sys/types.h>
+#include "../../types.h"
+#include <linux/compiler.h>
+
+/* CHECKME: Not sure both always match */
+#define BITS_PER_LONG __WORDSIZE
+
+#include "../../../../include/asm-generic/bitops/__fls.h"
+#include "../../../../include/asm-generic/bitops/fls.h"
+#include "../../../../include/asm-generic/bitops/fls64.h"
+#include "../../../../include/asm-generic/bitops/__ffs.h"
+#include "../../../../include/asm-generic/bitops/ffz.h"
+#include "../../../../include/asm-generic/bitops/hweight.h"
+
+#endif
diff --git a/tools/perf/util/include/asm/bug.h b/tools/perf/util/include/asm/bug.h
new file mode 100644
index 000000000000..7fcc6810adc2
--- /dev/null
+++ b/tools/perf/util/include/asm/bug.h
@@ -0,0 +1,22 @@
+#ifndef _PERF_ASM_GENERIC_BUG_H
+#define _PERF_ASM_GENERIC_BUG_H
+
+#define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0)
+
+#define WARN(condition, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ if (unlikely(__ret_warn_on)) \
+ __WARN_printf(format); \
+ unlikely(__ret_warn_on); \
+})
+
+#define WARN_ONCE(condition, format...) ({ \
+ static int __warned; \
+ int __ret_warn_once = !!(condition); \
+ \
+ if (unlikely(__ret_warn_once)) \
+ if (WARN(!__warned, format)) \
+ __warned = 1; \
+ unlikely(__ret_warn_once); \
+})
+#endif
diff --git a/tools/perf/util/include/asm/byteorder.h b/tools/perf/util/include/asm/byteorder.h
new file mode 100644
index 000000000000..b722abe3a626
--- /dev/null
+++ b/tools/perf/util/include/asm/byteorder.h
@@ -0,0 +1,2 @@
+#include <asm/types.h>
+#include "../../../../include/linux/swab.h"
diff --git a/tools/perf/util/include/asm/swab.h b/tools/perf/util/include/asm/swab.h
new file mode 100644
index 000000000000..ed538942523d
--- /dev/null
+++ b/tools/perf/util/include/asm/swab.h
@@ -0,0 +1 @@
+/* stub */
diff --git a/tools/perf/util/include/asm/uaccess.h b/tools/perf/util/include/asm/uaccess.h
new file mode 100644
index 000000000000..d0f72b8fcc35
--- /dev/null
+++ b/tools/perf/util/include/asm/uaccess.h
@@ -0,0 +1,14 @@
+#ifndef _PERF_ASM_UACCESS_H_
+#define _PERF_ASM_UACCESS_H_
+
+#define __get_user(src, dest) \
+({ \
+ (src) = *dest; \
+ 0; \
+})
+
+#define get_user __get_user
+
+#define access_ok(type, addr, size) 1
+
+#endif
diff --git a/tools/perf/util/include/linux/bitmap.h b/tools/perf/util/include/linux/bitmap.h
new file mode 100644
index 000000000000..94507639a8c4
--- /dev/null
+++ b/tools/perf/util/include/linux/bitmap.h
@@ -0,0 +1,3 @@
+#include "../../../../include/linux/bitmap.h"
+#include "../../../../include/asm-generic/bitops/find.h"
+#include <linux/errno.h>
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h
new file mode 100644
index 000000000000..8d63116e9435
--- /dev/null
+++ b/tools/perf/util/include/linux/bitops.h
@@ -0,0 +1,29 @@
+#ifndef _PERF_LINUX_BITOPS_H_
+#define _PERF_LINUX_BITOPS_H_
+
+#define __KERNEL__
+
+#define CONFIG_GENERIC_FIND_NEXT_BIT
+#define CONFIG_GENERIC_FIND_FIRST_BIT
+#include "../../../../include/linux/bitops.h"
+
+#undef __KERNEL__
+
+static inline void set_bit(int nr, unsigned long *addr)
+{
+ addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
+}
+
+static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
+{
+ return ((1UL << (nr % BITS_PER_LONG)) &
+ (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
+}
+
+unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, unsigned
+ long size, unsigned long offset);
+
+unsigned long generic_find_next_le_bit(const unsigned long *addr, unsigned
+ long size, unsigned long offset);
+
+#endif
diff --git a/tools/perf/util/include/linux/compiler.h b/tools/perf/util/include/linux/compiler.h
new file mode 100644
index 000000000000..dfb0713ed47f
--- /dev/null
+++ b/tools/perf/util/include/linux/compiler.h
@@ -0,0 +1,10 @@
+#ifndef _PERF_LINUX_COMPILER_H_
+#define _PERF_LINUX_COMPILER_H_
+
+#ifndef __always_inline
+#define __always_inline inline
+#endif
+#define __user
+#define __attribute_const__
+
+#endif
diff --git a/tools/perf/util/include/linux/ctype.h b/tools/perf/util/include/linux/ctype.h
new file mode 100644
index 000000000000..a53d4ee1e0b7
--- /dev/null
+++ b/tools/perf/util/include/linux/ctype.h
@@ -0,0 +1 @@
+#include "../util.h"
diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h
index a6b87390cb52..21c0274c02fa 100644
--- a/tools/perf/util/include/linux/kernel.h
+++ b/tools/perf/util/include/linux/kernel.h
@@ -1,6 +1,16 @@
#ifndef PERF_LINUX_KERNEL_H_
#define PERF_LINUX_KERNEL_H_
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
+#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
+#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
+
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
@@ -26,4 +36,70 @@
_max1 > _max2 ? _max1 : _max2; })
#endif
+#ifndef min
+#define min(x, y) ({ \
+ typeof(x) _min1 = (x); \
+ typeof(y) _min2 = (y); \
+ (void) (&_min1 == &_min2); \
+ _min1 < _min2 ? _min1 : _min2; })
+#endif
+
+#ifndef BUG_ON
+#define BUG_ON(cond) assert(!(cond))
+#endif
+
+/*
+ * Both need more care to handle endianness
+ * (Don't use bitmap_copy_le() for now)
+ */
+#define cpu_to_le64(x) (x)
+#define cpu_to_le32(x) (x)
+
+static inline int
+vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
+{
+ int i;
+ ssize_t ssize = size;
+
+ i = vsnprintf(buf, size, fmt, args);
+
+ return (i >= ssize) ? (ssize - 1) : i;
+}
+
+static inline int scnprintf(char * buf, size_t size, const char * fmt, ...)
+{
+ va_list args;
+ ssize_t ssize = size;
+ int i;
+
+ va_start(args, fmt);
+ i = vsnprintf(buf, size, fmt, args);
+ va_end(args);
+
+ return (i >= ssize) ? (ssize - 1) : i;
+}
+
+static inline unsigned long
+simple_strtoul(const char *nptr, char **endptr, int base)
+{
+ return strtoul(nptr, endptr, base);
+}
+
+#ifndef pr_fmt
+#define pr_fmt(fmt) fmt
+#endif
+
+#define pr_err(fmt, ...) \
+ do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+#define pr_warning(fmt, ...) \
+ do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+#define pr_info(fmt, ...) \
+ do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+#define pr_debug(fmt, ...) \
+ eprintf(1, pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_debugN(n, fmt, ...) \
+ eprintf(n, pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_debug2(fmt, ...) pr_debugN(2, pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__)
+
#endif
diff --git a/tools/perf/util/include/linux/string.h b/tools/perf/util/include/linux/string.h
new file mode 100644
index 000000000000..3b2f5900276f
--- /dev/null
+++ b/tools/perf/util/include/linux/string.h
@@ -0,0 +1 @@
+#include <string.h>
diff --git a/tools/perf/util/include/linux/types.h b/tools/perf/util/include/linux/types.h
new file mode 100644
index 000000000000..196862a81a21
--- /dev/null
+++ b/tools/perf/util/include/linux/types.h
@@ -0,0 +1,9 @@
+#ifndef _PERF_LINUX_TYPES_H_
+#define _PERF_LINUX_TYPES_H_
+
+#include <asm/types.h>
+
+#define DECLARE_BITMAP(name,bits) \
+ unsigned long name[BITS_TO_LONGS(bits)]
+
+#endif
diff --git a/tools/perf/util/levenshtein.h b/tools/perf/util/levenshtein.h
index 0173abeef52c..b0fcb6d8a881 100644
--- a/tools/perf/util/levenshtein.h
+++ b/tools/perf/util/levenshtein.h
@@ -1,8 +1,8 @@
-#ifndef LEVENSHTEIN_H
-#define LEVENSHTEIN_H
+#ifndef __PERF_LEVENSHTEIN_H
+#define __PERF_LEVENSHTEIN_H
int levenshtein(const char *string1, const char *string2,
int swap_penalty, int substition_penalty,
int insertion_penalty, int deletion_penalty);
-#endif
+#endif /* __PERF_LEVENSHTEIN_H */
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 804e02382739..69f94fe9db20 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include "debug.h"
static inline int is_anon_memory(const char *filename)
{
@@ -19,13 +20,28 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen)
return n;
}
- struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen)
+void map__init(struct map *self, enum map_type type,
+ u64 start, u64 end, u64 pgoff, struct dso *dso)
+{
+ self->type = type;
+ self->start = start;
+ self->end = end;
+ self->pgoff = pgoff;
+ self->dso = dso;
+ self->map_ip = map__map_ip;
+ self->unmap_ip = map__unmap_ip;
+ RB_CLEAR_NODE(&self->rb_node);
+}
+
+struct map *map__new(struct mmap_event *event, enum map_type type,
+ char *cwd, int cwdlen)
{
struct map *self = malloc(sizeof(*self));
if (self != NULL) {
const char *filename = event->filename;
char newfilename[PATH_MAX];
+ struct dso *dso;
int anon;
if (cwd) {
@@ -45,18 +61,15 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen)
filename = newfilename;
}
- self->start = event->start;
- self->end = event->start + event->len;
- self->pgoff = event->pgoff;
-
- self->dso = dsos__findnew(filename);
- if (self->dso == NULL)
+ dso = dsos__findnew(filename);
+ if (dso == NULL)
goto out_delete;
+ map__init(self, type, event->start, event->start + event->len,
+ event->pgoff, dso);
+
if (self->dso == vdso || anon)
- self->map_ip = vdso__map_ip;
- else
- self->map_ip = map__map_ip;
+ self->map_ip = self->unmap_ip = identity__map_ip;
}
return self;
out_delete:
@@ -64,6 +77,72 @@ out_delete:
return NULL;
}
+void map__delete(struct map *self)
+{
+ free(self);
+}
+
+void map__fixup_start(struct map *self)
+{
+ struct rb_root *symbols = &self->dso->symbols[self->type];
+ struct rb_node *nd = rb_first(symbols);
+ if (nd != NULL) {
+ struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
+ self->start = sym->start;
+ }
+}
+
+void map__fixup_end(struct map *self)
+{
+ struct rb_root *symbols = &self->dso->symbols[self->type];
+ struct rb_node *nd = rb_last(symbols);
+ if (nd != NULL) {
+ struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
+ self->end = sym->end;
+ }
+}
+
+#define DSO__DELETED "(deleted)"
+
+struct symbol *map__find_symbol(struct map *self, u64 addr,
+ symbol_filter_t filter)
+{
+ if (!dso__loaded(self->dso, self->type)) {
+ int nr = dso__load(self->dso, self, filter);
+
+ if (nr < 0) {
+ if (self->dso->has_build_id) {
+ char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+ build_id__sprintf(self->dso->build_id,
+ sizeof(self->dso->build_id),
+ sbuild_id);
+ pr_warning("%s with build id %s not found",
+ self->dso->long_name, sbuild_id);
+ } else
+ pr_warning("Failed to open %s",
+ self->dso->long_name);
+ pr_warning(", continuing without symbols\n");
+ return NULL;
+ } else if (nr == 0) {
+ const char *name = self->dso->long_name;
+ const size_t len = strlen(name);
+ const size_t real_len = len - sizeof(DSO__DELETED);
+
+ if (len > sizeof(DSO__DELETED) &&
+ strcmp(name + real_len + 1, DSO__DELETED) == 0) {
+ pr_warning("%.*s was updated, restart the long running apps that use it!\n",
+ (int)real_len, name);
+ } else {
+ pr_warning("no symbols found in %s, maybe install a debug package?\n", name);
+ }
+ return NULL;
+ }
+ }
+
+ return self->dso->find_symbol(self->dso, self->type, addr);
+}
+
struct map *map__clone(struct map *self)
{
struct map *map = malloc(sizeof(*self));
diff --git a/tools/perf/util/module.c b/tools/perf/util/module.c
deleted file mode 100644
index 0d8c85defcd2..000000000000
--- a/tools/perf/util/module.c
+++ /dev/null
@@ -1,545 +0,0 @@
-#include "util.h"
-#include "../perf.h"
-#include "string.h"
-#include "module.h"
-
-#include <libelf.h>
-#include <libgen.h>
-#include <gelf.h>
-#include <elf.h>
-#include <dirent.h>
-#include <sys/utsname.h>
-
-static unsigned int crc32(const char *p, unsigned int len)
-{
- int i;
- unsigned int crc = 0;
-
- while (len--) {
- crc ^= *p++;
- for (i = 0; i < 8; i++)
- crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
- }
- return crc;
-}
-
-/* module section methods */
-
-struct sec_dso *sec_dso__new_dso(const char *name)
-{
- struct sec_dso *self = malloc(sizeof(*self) + strlen(name) + 1);
-
- if (self != NULL) {
- strcpy(self->name, name);
- self->secs = RB_ROOT;
- self->find_section = sec_dso__find_section;
- }
-
- return self;
-}
-
-static void sec_dso__delete_section(struct section *self)
-{
- free(((void *)self));
-}
-
-void sec_dso__delete_sections(struct sec_dso *self)
-{
- struct section *pos;
- struct rb_node *next = rb_first(&self->secs);
-
- while (next) {
- pos = rb_entry(next, struct section, rb_node);
- next = rb_next(&pos->rb_node);
- rb_erase(&pos->rb_node, &self->secs);
- sec_dso__delete_section(pos);
- }
-}
-
-void sec_dso__delete_self(struct sec_dso *self)
-{
- sec_dso__delete_sections(self);
- free(self);
-}
-
-static void sec_dso__insert_section(struct sec_dso *self, struct section *sec)
-{
- struct rb_node **p = &self->secs.rb_node;
- struct rb_node *parent = NULL;
- const u64 hash = sec->hash;
- struct section *s;
-
- while (*p != NULL) {
- parent = *p;
- s = rb_entry(parent, struct section, rb_node);
- if (hash < s->hash)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
- rb_link_node(&sec->rb_node, parent, p);
- rb_insert_color(&sec->rb_node, &self->secs);
-}
-
-struct section *sec_dso__find_section(struct sec_dso *self, const char *name)
-{
- struct rb_node *n;
- u64 hash;
- int len;
-
- if (self == NULL)
- return NULL;
-
- len = strlen(name);
- hash = crc32(name, len);
-
- n = self->secs.rb_node;
-
- while (n) {
- struct section *s = rb_entry(n, struct section, rb_node);
-
- if (hash < s->hash)
- n = n->rb_left;
- else if (hash > s->hash)
- n = n->rb_right;
- else {
- if (!strcmp(name, s->name))
- return s;
- else
- n = rb_next(&s->rb_node);
- }
- }
-
- return NULL;
-}
-
-static size_t sec_dso__fprintf_section(struct section *self, FILE *fp)
-{
- return fprintf(fp, "name:%s vma:%llx path:%s\n",
- self->name, self->vma, self->path);
-}
-
-size_t sec_dso__fprintf(struct sec_dso *self, FILE *fp)
-{
- size_t ret = fprintf(fp, "dso: %s\n", self->name);
-
- struct rb_node *nd;
- for (nd = rb_first(&self->secs); nd; nd = rb_next(nd)) {
- struct section *pos = rb_entry(nd, struct section, rb_node);
- ret += sec_dso__fprintf_section(pos, fp);
- }
-
- return ret;
-}
-
-static struct section *section__new(const char *name, const char *path)
-{
- struct section *self = calloc(1, sizeof(*self));
-
- if (!self)
- goto out_failure;
-
- self->name = calloc(1, strlen(name) + 1);
- if (!self->name)
- goto out_failure;
-
- self->path = calloc(1, strlen(path) + 1);
- if (!self->path)
- goto out_failure;
-
- strcpy(self->name, name);
- strcpy(self->path, path);
- self->hash = crc32(self->name, strlen(name));
-
- return self;
-
-out_failure:
- if (self) {
- if (self->name)
- free(self->name);
- if (self->path)
- free(self->path);
- free(self);
- }
-
- return NULL;
-}
-
-/* module methods */
-
-struct mod_dso *mod_dso__new_dso(const char *name)
-{
- struct mod_dso *self = malloc(sizeof(*self) + strlen(name) + 1);
-
- if (self != NULL) {
- strcpy(self->name, name);
- self->mods = RB_ROOT;
- self->find_module = mod_dso__find_module;
- }
-
- return self;
-}
-
-static void mod_dso__delete_module(struct module *self)
-{
- free(((void *)self));
-}
-
-void mod_dso__delete_modules(struct mod_dso *self)
-{
- struct module *pos;
- struct rb_node *next = rb_first(&self->mods);
-
- while (next) {
- pos = rb_entry(next, struct module, rb_node);
- next = rb_next(&pos->rb_node);
- rb_erase(&pos->rb_node, &self->mods);
- mod_dso__delete_module(pos);
- }
-}
-
-void mod_dso__delete_self(struct mod_dso *self)
-{
- mod_dso__delete_modules(self);
- free(self);
-}
-
-static void mod_dso__insert_module(struct mod_dso *self, struct module *mod)
-{
- struct rb_node **p = &self->mods.rb_node;
- struct rb_node *parent = NULL;
- const u64 hash = mod->hash;
- struct module *m;
-
- while (*p != NULL) {
- parent = *p;
- m = rb_entry(parent, struct module, rb_node);
- if (hash < m->hash)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
- rb_link_node(&mod->rb_node, parent, p);
- rb_insert_color(&mod->rb_node, &self->mods);
-}
-
-struct module *mod_dso__find_module(struct mod_dso *self, const char *name)
-{
- struct rb_node *n;
- u64 hash;
- int len;
-
- if (self == NULL)
- return NULL;
-
- len = strlen(name);
- hash = crc32(name, len);
-
- n = self->mods.rb_node;
-
- while (n) {
- struct module *m = rb_entry(n, struct module, rb_node);
-
- if (hash < m->hash)
- n = n->rb_left;
- else if (hash > m->hash)
- n = n->rb_right;
- else {
- if (!strcmp(name, m->name))
- return m;
- else
- n = rb_next(&m->rb_node);
- }
- }
-
- return NULL;
-}
-
-static size_t mod_dso__fprintf_module(struct module *self, FILE *fp)
-{
- return fprintf(fp, "name:%s path:%s\n", self->name, self->path);
-}
-
-size_t mod_dso__fprintf(struct mod_dso *self, FILE *fp)
-{
- struct rb_node *nd;
- size_t ret;
-
- ret = fprintf(fp, "dso: %s\n", self->name);
-
- for (nd = rb_first(&self->mods); nd; nd = rb_next(nd)) {
- struct module *pos = rb_entry(nd, struct module, rb_node);
-
- ret += mod_dso__fprintf_module(pos, fp);
- }
-
- return ret;
-}
-
-static struct module *module__new(const char *name, const char *path)
-{
- struct module *self = calloc(1, sizeof(*self));
-
- if (!self)
- goto out_failure;
-
- self->name = calloc(1, strlen(name) + 1);
- if (!self->name)
- goto out_failure;
-
- self->path = calloc(1, strlen(path) + 1);
- if (!self->path)
- goto out_failure;
-
- strcpy(self->name, name);
- strcpy(self->path, path);
- self->hash = crc32(self->name, strlen(name));
-
- return self;
-
-out_failure:
- if (self) {
- if (self->name)
- free(self->name);
- if (self->path)
- free(self->path);
- free(self);
- }
-
- return NULL;
-}
-
-static int mod_dso__load_sections(struct module *mod)
-{
- int count = 0, path_len;
- struct dirent *entry;
- char *line = NULL;
- char *dir_path;
- DIR *dir;
- size_t n;
-
- path_len = strlen("/sys/module/");
- path_len += strlen(mod->name);
- path_len += strlen("/sections/");
-
- dir_path = calloc(1, path_len + 1);
- if (dir_path == NULL)
- goto out_failure;
-
- strcat(dir_path, "/sys/module/");
- strcat(dir_path, mod->name);
- strcat(dir_path, "/sections/");
-
- dir = opendir(dir_path);
- if (dir == NULL)
- goto out_free;
-
- while ((entry = readdir(dir))) {
- struct section *section;
- char *path, *vma;
- int line_len;
- FILE *file;
-
- if (!strcmp(".", entry->d_name) || !strcmp("..", entry->d_name))
- continue;
-
- path = calloc(1, path_len + strlen(entry->d_name) + 1);
- if (path == NULL)
- break;
- strcat(path, dir_path);
- strcat(path, entry->d_name);
-
- file = fopen(path, "r");
- if (file == NULL) {
- free(path);
- break;
- }
-
- line_len = getline(&line, &n, file);
- if (line_len < 0) {
- free(path);
- fclose(file);
- break;
- }
-
- if (!line) {
- free(path);
- fclose(file);
- break;
- }
-
- line[--line_len] = '\0'; /* \n */
-
- vma = strstr(line, "0x");
- if (!vma) {
- free(path);
- fclose(file);
- break;
- }
- vma += 2;
-
- section = section__new(entry->d_name, path);
- if (!section) {
- fprintf(stderr, "load_sections: allocation error\n");
- free(path);
- fclose(file);
- break;
- }
-
- hex2u64(vma, &section->vma);
- sec_dso__insert_section(mod->sections, section);
-
- free(path);
- fclose(file);
- count++;
- }
-
- closedir(dir);
- free(line);
- free(dir_path);
-
- return count;
-
-out_free:
- free(dir_path);
-
-out_failure:
- return count;
-}
-
-static int mod_dso__load_module_paths(struct mod_dso *self)
-{
- struct utsname uts;
- int count = 0, len, err = -1;
- char *line = NULL;
- FILE *file;
- char *dpath, *dir;
- size_t n;
-
- if (uname(&uts) < 0)
- return err;
-
- len = strlen("/lib/modules/");
- len += strlen(uts.release);
- len += strlen("/modules.dep");
-
- dpath = calloc(1, len + 1);
- if (dpath == NULL)
- return err;
-
- strcat(dpath, "/lib/modules/");
- strcat(dpath, uts.release);
- strcat(dpath, "/modules.dep");
-
- file = fopen(dpath, "r");
- if (file == NULL)
- goto out_failure;
-
- dir = dirname(dpath);
- if (!dir)
- goto out_failure;
- strcat(dir, "/");
-
- while (!feof(file)) {
- struct module *module;
- char *name, *path, *tmp;
- FILE *modfile;
- int line_len;
-
- line_len = getline(&line, &n, file);
- if (line_len < 0)
- break;
-
- if (!line)
- break;
-
- line[--line_len] = '\0'; /* \n */
-
- path = strchr(line, ':');
- if (!path)
- break;
- *path = '\0';
-
- path = strdup(line);
- if (!path)
- break;
-
- if (!strstr(path, dir)) {
- if (strncmp(path, "kernel/", 7))
- break;
-
- free(path);
- path = calloc(1, strlen(dir) + strlen(line) + 1);
- if (!path)
- break;
- strcat(path, dir);
- strcat(path, line);
- }
-
- modfile = fopen(path, "r");
- if (modfile == NULL)
- break;
- fclose(modfile);
-
- name = strdup(path);
- if (!name)
- break;
-
- name = strtok(name, "/");
- tmp = name;
-
- while (tmp) {
- tmp = strtok(NULL, "/");
- if (tmp)
- name = tmp;
- }
-
- name = strsep(&name, ".");
- if (!name)
- break;
-
- /* Quirk: replace '-' with '_' in all modules */
- for (len = strlen(name); len; len--) {
- if (*(name+len) == '-')
- *(name+len) = '_';
- }
-
- module = module__new(name, path);
- if (!module)
- break;
- mod_dso__insert_module(self, module);
-
- module->sections = sec_dso__new_dso("sections");
- if (!module->sections)
- break;
-
- module->active = mod_dso__load_sections(module);
-
- if (module->active > 0)
- count++;
- }
-
- if (feof(file))
- err = count;
- else
- fprintf(stderr, "load_module_paths: modules.dep parsing failure!\n");
-
-out_failure:
- if (dpath)
- free(dpath);
- if (file)
- fclose(file);
- if (line)
- free(line);
-
- return err;
-}
-
-int mod_dso__load_modules(struct mod_dso *dso)
-{
- int err;
-
- err = mod_dso__load_module_paths(dso);
-
- return err;
-}
diff --git a/tools/perf/util/module.h b/tools/perf/util/module.h
deleted file mode 100644
index 8a592ef641ca..000000000000
--- a/tools/perf/util/module.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _PERF_MODULE_
-#define _PERF_MODULE_ 1
-
-#include <linux/types.h>
-#include "../types.h"
-#include <linux/list.h>
-#include <linux/rbtree.h>
-
-struct section {
- struct rb_node rb_node;
- u64 hash;
- u64 vma;
- char *name;
- char *path;
-};
-
-struct sec_dso {
- struct list_head node;
- struct rb_root secs;
- struct section *(*find_section)(struct sec_dso *, const char *name);
- char name[0];
-};
-
-struct module {
- struct rb_node rb_node;
- u64 hash;
- char *name;
- char *path;
- struct sec_dso *sections;
- int active;
-};
-
-struct mod_dso {
- struct list_head node;
- struct rb_root mods;
- struct module *(*find_module)(struct mod_dso *, const char *name);
- char name[0];
-};
-
-struct sec_dso *sec_dso__new_dso(const char *name);
-void sec_dso__delete_sections(struct sec_dso *self);
-void sec_dso__delete_self(struct sec_dso *self);
-size_t sec_dso__fprintf(struct sec_dso *self, FILE *fp);
-struct section *sec_dso__find_section(struct sec_dso *self, const char *name);
-
-struct mod_dso *mod_dso__new_dso(const char *name);
-void mod_dso__delete_modules(struct mod_dso *self);
-void mod_dso__delete_self(struct mod_dso *self);
-size_t mod_dso__fprintf(struct mod_dso *self, FILE *fp);
-struct module *mod_dso__find_module(struct mod_dso *self, const char *name);
-int mod_dso__load_modules(struct mod_dso *dso);
-
-#endif /* _PERF_MODULE_ */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 87c424de79ee..9e5dbd66d34d 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,4 +1,4 @@
-
+#include "../../../include/linux/hw_breakpoint.h"
#include "util.h"
#include "../perf.h"
#include "parse-options.h"
@@ -7,10 +7,12 @@
#include "string.h"
#include "cache.h"
#include "header.h"
+#include "debugfs.h"
-int nr_counters;
+int nr_counters;
struct perf_event_attr attrs[MAX_COUNTERS];
+char *filters[MAX_COUNTERS];
struct event_symbol {
u8 type;
@@ -46,6 +48,8 @@ static struct event_symbol event_symbols[] = {
{ CSW(PAGE_FAULTS_MAJ), "major-faults", "" },
{ CSW(CONTEXT_SWITCHES), "context-switches", "cs" },
{ CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" },
+ { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" },
+ { CSW(EMULATION_FAULTS), "emulation-faults", "" },
};
#define __PERF_EVENT_FIELD(config, name) \
@@ -74,6 +78,8 @@ static const char *sw_event_names[] = {
"CPU-migrations",
"minor-faults",
"major-faults",
+ "alignment-faults",
+ "emulation-faults",
};
#define MAX_ALIASES 8
@@ -148,16 +154,6 @@ static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
#define MAX_EVENT_LENGTH 512
-int valid_debugfs_mount(const char *debugfs)
-{
- struct statfs st_fs;
-
- if (statfs(debugfs, &st_fs) < 0)
- return -ENOENT;
- else if (st_fs.f_type != (long) DEBUGFS_MAGIC)
- return -ENOENT;
- return 0;
-}
struct tracepoint_path *tracepoint_id_to_path(u64 config)
{
@@ -170,7 +166,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
char evt_path[MAXPATHLEN];
char dir_path[MAXPATHLEN];
- if (valid_debugfs_mount(debugfs_path))
+ if (debugfs_valid_mountpoint(debugfs_path))
return NULL;
sys_dir = opendir(debugfs_path);
@@ -201,7 +197,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
if (id == config) {
closedir(evt_dir);
closedir(sys_dir);
- path = calloc(1, sizeof(path));
+ path = zalloc(sizeof(path));
path->system = malloc(MAX_EVENT_LENGTH);
if (!path->system) {
free(path);
@@ -509,7 +505,7 @@ static enum event_result parse_tracepoint_event(const char **strp,
char sys_name[MAX_EVENT_LENGTH];
unsigned int sys_length, evt_length;
- if (valid_debugfs_mount(debugfs_path))
+ if (debugfs_valid_mountpoint(debugfs_path))
return 0;
evt_name = strchr(*strp, ':');
@@ -544,6 +540,81 @@ static enum event_result parse_tracepoint_event(const char **strp,
attr, strp);
}
+static enum event_result
+parse_breakpoint_type(const char *type, const char **strp,
+ struct perf_event_attr *attr)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ if (!type[i])
+ break;
+
+ switch (type[i]) {
+ case 'r':
+ attr->bp_type |= HW_BREAKPOINT_R;
+ break;
+ case 'w':
+ attr->bp_type |= HW_BREAKPOINT_W;
+ break;
+ case 'x':
+ attr->bp_type |= HW_BREAKPOINT_X;
+ break;
+ default:
+ return EVT_FAILED;
+ }
+ }
+ if (!attr->bp_type) /* Default */
+ attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
+
+ *strp = type + i;
+
+ return EVT_HANDLED;
+}
+
+static enum event_result
+parse_breakpoint_event(const char **strp, struct perf_event_attr *attr)
+{
+ const char *target;
+ const char *type;
+ char *endaddr;
+ u64 addr;
+ enum event_result err;
+
+ target = strchr(*strp, ':');
+ if (!target)
+ return EVT_FAILED;
+
+ if (strncmp(*strp, "mem", target - *strp) != 0)
+ return EVT_FAILED;
+
+ target++;
+
+ addr = strtoull(target, &endaddr, 0);
+ if (target == endaddr)
+ return EVT_FAILED;
+
+ attr->bp_addr = addr;
+ *strp = endaddr;
+
+ type = strchr(target, ':');
+
+ /* If no type is defined, just rw as default */
+ if (!type) {
+ attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
+ } else {
+ err = parse_breakpoint_type(++type, strp, attr);
+ if (err == EVT_FAILED)
+ return EVT_FAILED;
+ }
+
+ /* We should find a nice way to override the access type */
+ attr->bp_len = HW_BREAKPOINT_LEN_4;
+ attr->type = PERF_TYPE_BREAKPOINT;
+
+ return EVT_HANDLED;
+}
+
static int check_events(const char *str, unsigned int i)
{
int n;
@@ -677,6 +748,12 @@ parse_event_symbols(const char **str, struct perf_event_attr *attr)
if (ret != EVT_FAILED)
goto modifier;
+ ret = parse_breakpoint_event(str, attr);
+ if (ret != EVT_FAILED)
+ goto modifier;
+
+ fprintf(stderr, "invalid or unsupported event: '%s'\n", *str);
+ fprintf(stderr, "Run 'perf list' for a list of valid events\n");
return EVT_FAILED;
modifier:
@@ -691,7 +768,10 @@ static void store_event_type(const char *orgname)
FILE *file;
int id;
- sprintf(filename, "/sys/kernel/debug/tracing/events/%s/id", orgname);
+ sprintf(filename, "%s/", debugfs_path);
+ strncat(filename, orgname, strlen(orgname));
+ strcat(filename, "/id");
+
c = strchr(filename, ':');
if (c)
*c = '/';
@@ -705,7 +785,6 @@ static void store_event_type(const char *orgname)
perf_header__push_event(id, orgname);
}
-
int parse_events(const struct option *opt __used, const char *str, int unset __used)
{
struct perf_event_attr attr;
@@ -742,6 +821,28 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u
return 0;
}
+int parse_filter(const struct option *opt __used, const char *str,
+ int unset __used)
+{
+ int i = nr_counters - 1;
+ int len = strlen(str);
+
+ if (i < 0 || attrs[i].type != PERF_TYPE_TRACEPOINT) {
+ fprintf(stderr,
+ "-F option should follow a -e tracepoint option\n");
+ return -1;
+ }
+
+ filters[i] = malloc(len + 1);
+ if (!filters[i]) {
+ fprintf(stderr, "not enough memory to hold filter string\n");
+ return -1;
+ }
+ strcpy(filters[i], str);
+
+ return 0;
+}
+
static const char * const event_type_descriptors[] = {
"",
"Hardware event",
@@ -761,7 +862,7 @@ static void print_tracepoint_events(void)
char evt_path[MAXPATHLEN];
char dir_path[MAXPATHLEN];
- if (valid_debugfs_mount(debugfs_path))
+ if (debugfs_valid_mountpoint(debugfs_path))
return;
sys_dir = opendir(debugfs_path);
@@ -779,7 +880,7 @@ static void print_tracepoint_events(void)
for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
snprintf(evt_path, MAXPATHLEN, "%s:%s",
sys_dirent.d_name, evt_dirent.d_name);
- fprintf(stderr, " %-42s [%s]\n", evt_path,
+ printf(" %-42s [%s]\n", evt_path,
event_type_descriptors[PERF_TYPE_TRACEPOINT+1]);
}
closedir(evt_dir);
@@ -796,8 +897,8 @@ void print_events(void)
unsigned int i, type, op, prev_type = -1;
char name[40];
- fprintf(stderr, "\n");
- fprintf(stderr, "List of pre-defined events (to be used in -e):\n");
+ printf("\n");
+ printf("List of pre-defined events (to be used in -e):\n");
for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
type = syms->type + 1;
@@ -805,19 +906,19 @@ void print_events(void)
type = 0;
if (type != prev_type)
- fprintf(stderr, "\n");
+ printf("\n");
if (strlen(syms->alias))
sprintf(name, "%s OR %s", syms->symbol, syms->alias);
else
strcpy(name, syms->symbol);
- fprintf(stderr, " %-42s [%s]\n", name,
+ printf(" %-42s [%s]\n", name,
event_type_descriptors[type]);
prev_type = type;
}
- fprintf(stderr, "\n");
+ printf("\n");
for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
/* skip invalid cache type */
@@ -825,17 +926,20 @@ void print_events(void)
continue;
for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
- fprintf(stderr, " %-42s [%s]\n",
+ printf(" %-42s [%s]\n",
event_cache_name(type, op, i),
event_type_descriptors[4]);
}
}
}
- fprintf(stderr, "\n");
- fprintf(stderr, " %-42s [raw hardware event descriptor]\n",
+ printf("\n");
+ printf(" %-42s [raw hardware event descriptor]\n",
"rNNN");
- fprintf(stderr, "\n");
+ printf("\n");
+
+ printf(" %-42s [hardware breakpoint]\n", "mem:<addr>[:access]");
+ printf("\n");
print_tracepoint_events();
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 30c608112845..b8c1f64bc935 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -1,5 +1,5 @@
-#ifndef _PARSE_EVENTS_H
-#define _PARSE_EVENTS_H
+#ifndef __PERF_PARSE_EVENTS_H
+#define __PERF_PARSE_EVENTS_H
/*
* Parse symbolic events/counts passed in as options:
*/
@@ -17,11 +17,13 @@ extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
extern int nr_counters;
extern struct perf_event_attr attrs[MAX_COUNTERS];
+extern char *filters[MAX_COUNTERS];
extern const char *event_name(int ctr);
extern const char *__event_name(int type, u64 config);
extern int parse_events(const struct option *opt, const char *str, int unset);
+extern int parse_filter(const struct option *opt, const char *str, int unset);
#define EVENTS_HELP_MAX (128*1024)
@@ -31,4 +33,4 @@ extern char debugfs_path[];
extern int valid_debugfs_mount(const char *debugfs);
-#endif /* _PARSE_EVENTS_H */
+#endif /* __PERF_PARSE_EVENTS_H */
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index 2ee248ff27e5..948805af43c2 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -1,5 +1,5 @@
-#ifndef PARSE_OPTIONS_H
-#define PARSE_OPTIONS_H
+#ifndef __PERF_PARSE_OPTIONS_H
+#define __PERF_PARSE_OPTIONS_H
enum parse_opt_type {
/* special types */
@@ -174,4 +174,4 @@ extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
extern const char *parse_options_fix_filename(const char *prefix, const char *file);
-#endif
+#endif /* __PERF_PARSE_OPTIONS_H */
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
new file mode 100644
index 000000000000..cd7fbda5e2a5
--- /dev/null
+++ b/tools/perf/util/probe-event.c
@@ -0,0 +1,484 @@
+/*
+ * probe-event.c : perf-probe definition to kprobe_events format converter
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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.
+ *
+ */
+
+#define _GNU_SOURCE
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <limits.h>
+
+#undef _GNU_SOURCE
+#include "event.h"
+#include "string.h"
+#include "strlist.h"
+#include "debug.h"
+#include "parse-events.h" /* For debugfs_path */
+#include "probe-event.h"
+
+#define MAX_CMDLEN 256
+#define MAX_PROBE_ARGS 128
+#define PERFPROBE_GROUP "probe"
+
+#define semantic_error(msg ...) die("Semantic error :" msg)
+
+/* If there is no space to write, returns -E2BIG. */
+static int e_snprintf(char *str, size_t size, const char *format, ...)
+{
+ int ret;
+ va_list ap;
+ va_start(ap, format);
+ ret = vsnprintf(str, size, format, ap);
+ va_end(ap);
+ if (ret >= (int)size)
+ ret = -E2BIG;
+ return ret;
+}
+
+/* Parse probepoint definition. */
+static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
+{
+ char *ptr, *tmp;
+ char c, nc = 0;
+ /*
+ * <Syntax>
+ * perf probe SRC:LN
+ * perf probe FUNC[+OFFS|%return][@SRC]
+ */
+
+ ptr = strpbrk(arg, ":+@%");
+ if (ptr) {
+ nc = *ptr;
+ *ptr++ = '\0';
+ }
+
+ /* Check arg is function or file and copy it */
+ if (strchr(arg, '.')) /* File */
+ pp->file = strdup(arg);
+ else /* Function */
+ pp->function = strdup(arg);
+ DIE_IF(pp->file == NULL && pp->function == NULL);
+
+ /* Parse other options */
+ while (ptr) {
+ arg = ptr;
+ c = nc;
+ ptr = strpbrk(arg, ":+@%");
+ if (ptr) {
+ nc = *ptr;
+ *ptr++ = '\0';
+ }
+ switch (c) {
+ case ':': /* Line number */
+ pp->line = strtoul(arg, &tmp, 0);
+ if (*tmp != '\0')
+ semantic_error("There is non-digit charactor"
+ " in line number.");
+ break;
+ case '+': /* Byte offset from a symbol */
+ pp->offset = strtoul(arg, &tmp, 0);
+ if (*tmp != '\0')
+ semantic_error("There is non-digit charactor"
+ " in offset.");
+ break;
+ case '@': /* File name */
+ if (pp->file)
+ semantic_error("SRC@SRC is not allowed.");
+ pp->file = strdup(arg);
+ DIE_IF(pp->file == NULL);
+ if (ptr)
+ semantic_error("@SRC must be the last "
+ "option.");
+ break;
+ case '%': /* Probe places */
+ if (strcmp(arg, "return") == 0) {
+ pp->retprobe = 1;
+ } else /* Others not supported yet */
+ semantic_error("%%%s is not supported.", arg);
+ break;
+ default:
+ DIE_IF("Program has a bug.");
+ break;
+ }
+ }
+
+ /* Exclusion check */
+ if (pp->line && pp->offset)
+ semantic_error("Offset can't be used with line number.");
+
+ if (!pp->line && pp->file && !pp->function)
+ semantic_error("File always requires line number.");
+
+ if (pp->offset && !pp->function)
+ semantic_error("Offset requires an entry function.");
+
+ if (pp->retprobe && !pp->function)
+ semantic_error("Return probe requires an entry function.");
+
+ if ((pp->offset || pp->line) && pp->retprobe)
+ semantic_error("Offset/Line can't be used with return probe.");
+
+ pr_debug("symbol:%s file:%s line:%d offset:%d, return:%d\n",
+ pp->function, pp->file, pp->line, pp->offset, pp->retprobe);
+}
+
+/* Parse perf-probe event definition */
+int parse_perf_probe_event(const char *str, struct probe_point *pp)
+{
+ char **argv;
+ int argc, i, need_dwarf = 0;
+
+ argv = argv_split(str, &argc);
+ if (!argv)
+ die("argv_split failed.");
+ if (argc > MAX_PROBE_ARGS + 1)
+ semantic_error("Too many arguments");
+
+ /* Parse probe point */
+ parse_perf_probe_probepoint(argv[0], pp);
+ if (pp->file || pp->line)
+ need_dwarf = 1;
+
+ /* Copy arguments and ensure return probe has no C argument */
+ pp->nr_args = argc - 1;
+ pp->args = zalloc(sizeof(char *) * pp->nr_args);
+ for (i = 0; i < pp->nr_args; i++) {
+ pp->args[i] = strdup(argv[i + 1]);
+ if (!pp->args[i])
+ die("Failed to copy argument.");
+ if (is_c_varname(pp->args[i])) {
+ if (pp->retprobe)
+ semantic_error("You can't specify local"
+ " variable for kretprobe");
+ need_dwarf = 1;
+ }
+ }
+
+ argv_free(argv);
+ return need_dwarf;
+}
+
+/* Parse kprobe_events event into struct probe_point */
+void parse_trace_kprobe_event(const char *str, char **group, char **event,
+ struct probe_point *pp)
+{
+ char pr;
+ char *p;
+ int ret, i, argc;
+ char **argv;
+
+ pr_debug("Parsing kprobe_events: %s\n", str);
+ argv = argv_split(str, &argc);
+ if (!argv)
+ die("argv_split failed.");
+ if (argc < 2)
+ semantic_error("Too less arguments.");
+
+ /* Scan event and group name. */
+ ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
+ &pr, (float *)(void *)group, (float *)(void *)event);
+ if (ret != 3)
+ semantic_error("Failed to parse event name: %s", argv[0]);
+ pr_debug("Group:%s Event:%s probe:%c\n", *group, *event, pr);
+
+ if (!pp)
+ goto end;
+
+ pp->retprobe = (pr == 'r');
+
+ /* Scan function name and offset */
+ ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function, &pp->offset);
+ if (ret == 1)
+ pp->offset = 0;
+
+ /* kprobe_events doesn't have this information */
+ pp->line = 0;
+ pp->file = NULL;
+
+ pp->nr_args = argc - 2;
+ pp->args = zalloc(sizeof(char *) * pp->nr_args);
+ for (i = 0; i < pp->nr_args; i++) {
+ p = strchr(argv[i + 2], '=');
+ if (p) /* We don't need which register is assigned. */
+ *p = '\0';
+ pp->args[i] = strdup(argv[i + 2]);
+ if (!pp->args[i])
+ die("Failed to copy argument.");
+ }
+
+end:
+ argv_free(argv);
+}
+
+int synthesize_perf_probe_event(struct probe_point *pp)
+{
+ char *buf;
+ char offs[64] = "", line[64] = "";
+ int i, len, ret;
+
+ pp->probes[0] = buf = zalloc(MAX_CMDLEN);
+ if (!buf)
+ die("Failed to allocate memory by zalloc.");
+ if (pp->offset) {
+ ret = e_snprintf(offs, 64, "+%d", pp->offset);
+ if (ret <= 0)
+ goto error;
+ }
+ if (pp->line) {
+ ret = e_snprintf(line, 64, ":%d", pp->line);
+ if (ret <= 0)
+ goto error;
+ }
+
+ if (pp->function)
+ ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function,
+ offs, pp->retprobe ? "%return" : "", line);
+ else
+ ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->file, line);
+ if (ret <= 0)
+ goto error;
+ len = ret;
+
+ for (i = 0; i < pp->nr_args; i++) {
+ ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
+ pp->args[i]);
+ if (ret <= 0)
+ goto error;
+ len += ret;
+ }
+ pp->found = 1;
+
+ return pp->found;
+error:
+ free(pp->probes[0]);
+
+ return ret;
+}
+
+int synthesize_trace_kprobe_event(struct probe_point *pp)
+{
+ char *buf;
+ int i, len, ret;
+
+ pp->probes[0] = buf = zalloc(MAX_CMDLEN);
+ if (!buf)
+ die("Failed to allocate memory by zalloc.");
+ ret = e_snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset);
+ if (ret <= 0)
+ goto error;
+ len = ret;
+
+ for (i = 0; i < pp->nr_args; i++) {
+ ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
+ pp->args[i]);
+ if (ret <= 0)
+ goto error;
+ len += ret;
+ }
+ pp->found = 1;
+
+ return pp->found;
+error:
+ free(pp->probes[0]);
+
+ return ret;
+}
+
+static int open_kprobe_events(int flags, int mode)
+{
+ char buf[PATH_MAX];
+ int ret;
+
+ ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path);
+ if (ret < 0)
+ die("Failed to make kprobe_events path.");
+
+ ret = open(buf, flags, mode);
+ if (ret < 0) {
+ if (errno == ENOENT)
+ die("kprobe_events file does not exist -"
+ " please rebuild with CONFIG_KPROBE_TRACER.");
+ else
+ die("Could not open kprobe_events file: %s",
+ strerror(errno));
+ }
+ return ret;
+}
+
+/* Get raw string list of current kprobe_events */
+static struct strlist *get_trace_kprobe_event_rawlist(int fd)
+{
+ int ret, idx;
+ FILE *fp;
+ char buf[MAX_CMDLEN];
+ char *p;
+ struct strlist *sl;
+
+ sl = strlist__new(true, NULL);
+
+ fp = fdopen(dup(fd), "r");
+ while (!feof(fp)) {
+ p = fgets(buf, MAX_CMDLEN, fp);
+ if (!p)
+ break;
+
+ idx = strlen(p) - 1;
+ if (p[idx] == '\n')
+ p[idx] = '\0';
+ ret = strlist__add(sl, buf);
+ if (ret < 0)
+ die("strlist__add failed: %s", strerror(-ret));
+ }
+ fclose(fp);
+
+ return sl;
+}
+
+/* Free and zero clear probe_point */
+static void clear_probe_point(struct probe_point *pp)
+{
+ int i;
+
+ if (pp->function)
+ free(pp->function);
+ if (pp->file)
+ free(pp->file);
+ for (i = 0; i < pp->nr_args; i++)
+ free(pp->args[i]);
+ if (pp->args)
+ free(pp->args);
+ for (i = 0; i < pp->found; i++)
+ free(pp->probes[i]);
+ memset(pp, 0, sizeof(pp));
+}
+
+/* List up current perf-probe events */
+void show_perf_probe_events(void)
+{
+ unsigned int i;
+ int fd;
+ char *group, *event;
+ struct probe_point pp;
+ struct strlist *rawlist;
+ struct str_node *ent;
+
+ fd = open_kprobe_events(O_RDONLY, 0);
+ rawlist = get_trace_kprobe_event_rawlist(fd);
+ close(fd);
+
+ for (i = 0; i < strlist__nr_entries(rawlist); i++) {
+ ent = strlist__entry(rawlist, i);
+ parse_trace_kprobe_event(ent->s, &group, &event, &pp);
+ synthesize_perf_probe_event(&pp);
+ printf("[%s:%s]\t%s\n", group, event, pp.probes[0]);
+ free(group);
+ free(event);
+ clear_probe_point(&pp);
+ }
+
+ strlist__delete(rawlist);
+}
+
+/* Get current perf-probe event names */
+static struct strlist *get_perf_event_names(int fd)
+{
+ unsigned int i;
+ char *group, *event;
+ struct strlist *sl, *rawlist;
+ struct str_node *ent;
+
+ rawlist = get_trace_kprobe_event_rawlist(fd);
+
+ sl = strlist__new(false, NULL);
+ for (i = 0; i < strlist__nr_entries(rawlist); i++) {
+ ent = strlist__entry(rawlist, i);
+ parse_trace_kprobe_event(ent->s, &group, &event, NULL);
+ strlist__add(sl, event);
+ free(group);
+ }
+
+ strlist__delete(rawlist);
+
+ return sl;
+}
+
+static int write_trace_kprobe_event(int fd, const char *buf)
+{
+ int ret;
+
+ ret = write(fd, buf, strlen(buf));
+ if (ret <= 0)
+ die("Failed to create event.");
+ else
+ printf("Added new event: %s\n", buf);
+
+ return ret;
+}
+
+static void get_new_event_name(char *buf, size_t len, const char *base,
+ struct strlist *namelist)
+{
+ int i, ret;
+ for (i = 0; i < MAX_EVENT_INDEX; i++) {
+ ret = e_snprintf(buf, len, "%s_%d", base, i);
+ if (ret < 0)
+ die("snprintf() failed: %s", strerror(-ret));
+ if (!strlist__has_entry(namelist, buf))
+ break;
+ }
+ if (i == MAX_EVENT_INDEX)
+ die("Too many events are on the same function.");
+}
+
+void add_trace_kprobe_events(struct probe_point *probes, int nr_probes)
+{
+ int i, j, fd;
+ struct probe_point *pp;
+ char buf[MAX_CMDLEN];
+ char event[64];
+ struct strlist *namelist;
+
+ fd = open_kprobe_events(O_RDWR, O_APPEND);
+ /* Get current event names */
+ namelist = get_perf_event_names(fd);
+
+ for (j = 0; j < nr_probes; j++) {
+ pp = probes + j;
+ for (i = 0; i < pp->found; i++) {
+ /* Get an unused new event name */
+ get_new_event_name(event, 64, pp->function, namelist);
+ snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
+ pp->retprobe ? 'r' : 'p',
+ PERFPROBE_GROUP, event,
+ pp->probes[i]);
+ write_trace_kprobe_event(fd, buf);
+ /* Add added event name to namelist */
+ strlist__add(namelist, event);
+ }
+ }
+ close(fd);
+}
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
new file mode 100644
index 000000000000..0c6fe56fe38a
--- /dev/null
+++ b/tools/perf/util/probe-event.h
@@ -0,0 +1,18 @@
+#ifndef _PROBE_EVENT_H
+#define _PROBE_EVENT_H
+
+#include "probe-finder.h"
+#include "strlist.h"
+
+extern int parse_perf_probe_event(const char *str, struct probe_point *pp);
+extern int synthesize_perf_probe_event(struct probe_point *pp);
+extern void parse_trace_kprobe_event(const char *str, char **group,
+ char **event, struct probe_point *pp);
+extern int synthesize_trace_kprobe_event(struct probe_point *pp);
+extern void add_trace_kprobe_events(struct probe_point *probes, int nr_probes);
+extern void show_perf_probe_events(void);
+
+/* Maximum index number of event-name postfix */
+#define MAX_EVENT_INDEX 1024
+
+#endif /*_PROBE_EVENT_H */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
new file mode 100644
index 000000000000..293cdfc1b8ca
--- /dev/null
+++ b/tools/perf/util/probe-finder.c
@@ -0,0 +1,732 @@
+/*
+ * probe-finder.c : C expression to kprobe event converter
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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 <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#include "event.h"
+#include "debug.h"
+#include "util.h"
+#include "probe-finder.h"
+
+
+/* Dwarf_Die Linkage to parent Die */
+struct die_link {
+ struct die_link *parent; /* Parent die */
+ Dwarf_Die die; /* Current die */
+};
+
+static Dwarf_Debug __dw_debug;
+static Dwarf_Error __dw_error;
+
+/*
+ * Generic dwarf analysis helpers
+ */
+
+#define X86_32_MAX_REGS 8
+const char *x86_32_regs_table[X86_32_MAX_REGS] = {
+ "%ax",
+ "%cx",
+ "%dx",
+ "%bx",
+ "$stack", /* Stack address instead of %sp */
+ "%bp",
+ "%si",
+ "%di",
+};
+
+#define X86_64_MAX_REGS 16
+const char *x86_64_regs_table[X86_64_MAX_REGS] = {
+ "%ax",
+ "%dx",
+ "%cx",
+ "%bx",
+ "%si",
+ "%di",
+ "%bp",
+ "%sp",
+ "%r8",
+ "%r9",
+ "%r10",
+ "%r11",
+ "%r12",
+ "%r13",
+ "%r14",
+ "%r15",
+};
+
+/* TODO: switching by dwarf address size */
+#ifdef __x86_64__
+#define ARCH_MAX_REGS X86_64_MAX_REGS
+#define arch_regs_table x86_64_regs_table
+#else
+#define ARCH_MAX_REGS X86_32_MAX_REGS
+#define arch_regs_table x86_32_regs_table
+#endif
+
+/* Return architecture dependent register string (for kprobe-tracer) */
+static const char *get_arch_regstr(unsigned int n)
+{
+ return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
+}
+
+/*
+ * Compare the tail of two strings.
+ * Return 0 if whole of either string is same as another's tail part.
+ */
+static int strtailcmp(const char *s1, const char *s2)
+{
+ int i1 = strlen(s1);
+ int i2 = strlen(s2);
+ while (--i1 > 0 && --i2 > 0) {
+ if (s1[i1] != s2[i2])
+ return s1[i1] - s2[i2];
+ }
+ return 0;
+}
+
+/* Find the fileno of the target file. */
+static Dwarf_Unsigned cu_find_fileno(Dwarf_Die cu_die, const char *fname)
+{
+ Dwarf_Signed cnt, i;
+ Dwarf_Unsigned found = 0;
+ char **srcs;
+ int ret;
+
+ if (!fname)
+ return 0;
+
+ ret = dwarf_srcfiles(cu_die, &srcs, &cnt, &__dw_error);
+ if (ret == DW_DLV_OK) {
+ for (i = 0; i < cnt && !found; i++) {
+ if (strtailcmp(srcs[i], fname) == 0)
+ found = i + 1;
+ dwarf_dealloc(__dw_debug, srcs[i], DW_DLA_STRING);
+ }
+ for (; i < cnt; i++)
+ dwarf_dealloc(__dw_debug, srcs[i], DW_DLA_STRING);
+ dwarf_dealloc(__dw_debug, srcs, DW_DLA_LIST);
+ }
+ if (found)
+ pr_debug("found fno: %d\n", (int)found);
+ return found;
+}
+
+/* Compare diename and tname */
+static int die_compare_name(Dwarf_Die dw_die, const char *tname)
+{
+ char *name;
+ int ret;
+ ret = dwarf_diename(dw_die, &name, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (ret == DW_DLV_OK) {
+ ret = strcmp(tname, name);
+ dwarf_dealloc(__dw_debug, name, DW_DLA_STRING);
+ } else
+ ret = -1;
+ return ret;
+}
+
+/* Check the address is in the subprogram(function). */
+static int die_within_subprogram(Dwarf_Die sp_die, Dwarf_Addr addr,
+ Dwarf_Signed *offs)
+{
+ Dwarf_Addr lopc, hipc;
+ int ret;
+
+ /* TODO: check ranges */
+ ret = dwarf_lowpc(sp_die, &lopc, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (ret == DW_DLV_NO_ENTRY)
+ return 0;
+ ret = dwarf_highpc(sp_die, &hipc, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ if (lopc <= addr && addr < hipc) {
+ *offs = addr - lopc;
+ return 1;
+ } else
+ return 0;
+}
+
+/* Check the die is inlined function */
+static Dwarf_Bool die_inlined_subprogram(Dwarf_Die dw_die)
+{
+ /* TODO: check strictly */
+ Dwarf_Bool inl;
+ int ret;
+
+ ret = dwarf_hasattr(dw_die, DW_AT_inline, &inl, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ return inl;
+}
+
+/* Get the offset of abstruct_origin */
+static Dwarf_Off die_get_abstract_origin(Dwarf_Die dw_die)
+{
+ Dwarf_Attribute attr;
+ Dwarf_Off cu_offs;
+ int ret;
+
+ ret = dwarf_attr(dw_die, DW_AT_abstract_origin, &attr, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ ret = dwarf_formref(attr, &cu_offs, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
+ return cu_offs;
+}
+
+/* Get entry pc(or low pc, 1st entry of ranges) of the die */
+static Dwarf_Addr die_get_entrypc(Dwarf_Die dw_die)
+{
+ Dwarf_Attribute attr;
+ Dwarf_Addr addr;
+ Dwarf_Off offs;
+ Dwarf_Ranges *ranges;
+ Dwarf_Signed cnt;
+ int ret;
+
+ /* Try to get entry pc */
+ ret = dwarf_attr(dw_die, DW_AT_entry_pc, &attr, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (ret == DW_DLV_OK) {
+ ret = dwarf_formaddr(attr, &addr, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
+ return addr;
+ }
+
+ /* Try to get low pc */
+ ret = dwarf_lowpc(dw_die, &addr, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (ret == DW_DLV_OK)
+ return addr;
+
+ /* Try to get ranges */
+ ret = dwarf_attr(dw_die, DW_AT_ranges, &attr, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ ret = dwarf_formref(attr, &offs, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ ret = dwarf_get_ranges(__dw_debug, offs, &ranges, &cnt, NULL,
+ &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ addr = ranges[0].dwr_addr1;
+ dwarf_ranges_dealloc(__dw_debug, ranges, cnt);
+ return addr;
+}
+
+/*
+ * Search a Die from Die tree.
+ * Note: cur_link->die should be deallocated in this function.
+ */
+static int __search_die_tree(struct die_link *cur_link,
+ int (*die_cb)(struct die_link *, void *),
+ void *data)
+{
+ Dwarf_Die new_die;
+ struct die_link new_link;
+ int ret;
+
+ if (!die_cb)
+ return 0;
+
+ /* Check current die */
+ while (!(ret = die_cb(cur_link, data))) {
+ /* Check child die */
+ ret = dwarf_child(cur_link->die, &new_die, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (ret == DW_DLV_OK) {
+ new_link.parent = cur_link;
+ new_link.die = new_die;
+ ret = __search_die_tree(&new_link, die_cb, data);
+ if (ret)
+ break;
+ }
+
+ /* Move to next sibling */
+ ret = dwarf_siblingof(__dw_debug, cur_link->die, &new_die,
+ &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ dwarf_dealloc(__dw_debug, cur_link->die, DW_DLA_DIE);
+ cur_link->die = new_die;
+ if (ret == DW_DLV_NO_ENTRY)
+ return 0;
+ }
+ dwarf_dealloc(__dw_debug, cur_link->die, DW_DLA_DIE);
+ return ret;
+}
+
+/* Search a die in its children's die tree */
+static int search_die_from_children(Dwarf_Die parent_die,
+ int (*die_cb)(struct die_link *, void *),
+ void *data)
+{
+ struct die_link new_link;
+ int ret;
+
+ new_link.parent = NULL;
+ ret = dwarf_child(parent_die, &new_link.die, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (ret == DW_DLV_OK)
+ return __search_die_tree(&new_link, die_cb, data);
+ else
+ return 0;
+}
+
+/* Find a locdesc corresponding to the address */
+static int attr_get_locdesc(Dwarf_Attribute attr, Dwarf_Locdesc *desc,
+ Dwarf_Addr addr)
+{
+ Dwarf_Signed lcnt;
+ Dwarf_Locdesc **llbuf;
+ int ret, i;
+
+ ret = dwarf_loclist_n(attr, &llbuf, &lcnt, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ ret = DW_DLV_NO_ENTRY;
+ for (i = 0; i < lcnt; ++i) {
+ if (llbuf[i]->ld_lopc <= addr &&
+ llbuf[i]->ld_hipc > addr) {
+ memcpy(desc, llbuf[i], sizeof(Dwarf_Locdesc));
+ desc->ld_s =
+ malloc(sizeof(Dwarf_Loc) * llbuf[i]->ld_cents);
+ DIE_IF(desc->ld_s == NULL);
+ memcpy(desc->ld_s, llbuf[i]->ld_s,
+ sizeof(Dwarf_Loc) * llbuf[i]->ld_cents);
+ ret = DW_DLV_OK;
+ break;
+ }
+ dwarf_dealloc(__dw_debug, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
+ dwarf_dealloc(__dw_debug, llbuf[i], DW_DLA_LOCDESC);
+ }
+ /* Releasing loop */
+ for (; i < lcnt; ++i) {
+ dwarf_dealloc(__dw_debug, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
+ dwarf_dealloc(__dw_debug, llbuf[i], DW_DLA_LOCDESC);
+ }
+ dwarf_dealloc(__dw_debug, llbuf, DW_DLA_LIST);
+ return ret;
+}
+
+/* Get decl_file attribute value (file number) */
+static Dwarf_Unsigned die_get_decl_file(Dwarf_Die sp_die)
+{
+ Dwarf_Attribute attr;
+ Dwarf_Unsigned fno;
+ int ret;
+
+ ret = dwarf_attr(sp_die, DW_AT_decl_file, &attr, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ dwarf_formudata(attr, &fno, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
+ return fno;
+}
+
+/* Get decl_line attribute value (line number) */
+static Dwarf_Unsigned die_get_decl_line(Dwarf_Die sp_die)
+{
+ Dwarf_Attribute attr;
+ Dwarf_Unsigned lno;
+ int ret;
+
+ ret = dwarf_attr(sp_die, DW_AT_decl_line, &attr, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ dwarf_formudata(attr, &lno, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
+ return lno;
+}
+
+/*
+ * Probe finder related functions
+ */
+
+/* Show a location */
+static void show_location(Dwarf_Loc *loc, struct probe_finder *pf)
+{
+ Dwarf_Small op;
+ Dwarf_Unsigned regn;
+ Dwarf_Signed offs;
+ int deref = 0, ret;
+ const char *regs;
+
+ op = loc->lr_atom;
+
+ /* If this is based on frame buffer, set the offset */
+ if (op == DW_OP_fbreg) {
+ deref = 1;
+ offs = (Dwarf_Signed)loc->lr_number;
+ op = pf->fbloc.ld_s[0].lr_atom;
+ loc = &pf->fbloc.ld_s[0];
+ } else
+ offs = 0;
+
+ if (op >= DW_OP_breg0 && op <= DW_OP_breg31) {
+ regn = op - DW_OP_breg0;
+ offs += (Dwarf_Signed)loc->lr_number;
+ deref = 1;
+ } else if (op >= DW_OP_reg0 && op <= DW_OP_reg31) {
+ regn = op - DW_OP_reg0;
+ } else if (op == DW_OP_bregx) {
+ regn = loc->lr_number;
+ offs += (Dwarf_Signed)loc->lr_number2;
+ deref = 1;
+ } else if (op == DW_OP_regx) {
+ regn = loc->lr_number;
+ } else
+ die("Dwarf_OP %d is not supported.\n", op);
+
+ regs = get_arch_regstr(regn);
+ if (!regs)
+ die("%lld exceeds max register number.\n", regn);
+
+ if (deref)
+ ret = snprintf(pf->buf, pf->len,
+ " %s=%+lld(%s)", pf->var, offs, regs);
+ else
+ ret = snprintf(pf->buf, pf->len, " %s=%s", pf->var, regs);
+ DIE_IF(ret < 0);
+ DIE_IF(ret >= pf->len);
+}
+
+/* Show a variables in kprobe event format */
+static void show_variable(Dwarf_Die vr_die, struct probe_finder *pf)
+{
+ Dwarf_Attribute attr;
+ Dwarf_Locdesc ld;
+ int ret;
+
+ ret = dwarf_attr(vr_die, DW_AT_location, &attr, &__dw_error);
+ if (ret != DW_DLV_OK)
+ goto error;
+ ret = attr_get_locdesc(attr, &ld, (pf->addr - pf->cu_base));
+ if (ret != DW_DLV_OK)
+ goto error;
+ /* TODO? */
+ DIE_IF(ld.ld_cents != 1);
+ show_location(&ld.ld_s[0], pf);
+ free(ld.ld_s);
+ dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
+ return ;
+error:
+ die("Failed to find the location of %s at this address.\n"
+ " Perhaps, it has been optimized out.\n", pf->var);
+}
+
+static int variable_callback(struct die_link *dlink, void *data)
+{
+ struct probe_finder *pf = (struct probe_finder *)data;
+ Dwarf_Half tag;
+ int ret;
+
+ ret = dwarf_tag(dlink->die, &tag, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if ((tag == DW_TAG_formal_parameter ||
+ tag == DW_TAG_variable) &&
+ (die_compare_name(dlink->die, pf->var) == 0)) {
+ show_variable(dlink->die, pf);
+ return 1;
+ }
+ /* TODO: Support struct members and arrays */
+ return 0;
+}
+
+/* Find a variable in a subprogram die */
+static void find_variable(Dwarf_Die sp_die, struct probe_finder *pf)
+{
+ int ret;
+
+ if (!is_c_varname(pf->var)) {
+ /* Output raw parameters */
+ ret = snprintf(pf->buf, pf->len, " %s", pf->var);
+ DIE_IF(ret < 0);
+ DIE_IF(ret >= pf->len);
+ return ;
+ }
+
+ pr_debug("Searching '%s' variable in context.\n", pf->var);
+ /* Search child die for local variables and parameters. */
+ ret = search_die_from_children(sp_die, variable_callback, pf);
+ if (!ret)
+ die("Failed to find '%s' in this function.\n", pf->var);
+}
+
+/* Get a frame base on the address */
+static void get_current_frame_base(Dwarf_Die sp_die, struct probe_finder *pf)
+{
+ Dwarf_Attribute attr;
+ int ret;
+
+ ret = dwarf_attr(sp_die, DW_AT_frame_base, &attr, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ ret = attr_get_locdesc(attr, &pf->fbloc, (pf->addr - pf->cu_base));
+ DIE_IF(ret != DW_DLV_OK);
+ dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
+}
+
+static void free_current_frame_base(struct probe_finder *pf)
+{
+ free(pf->fbloc.ld_s);
+ memset(&pf->fbloc, 0, sizeof(Dwarf_Locdesc));
+}
+
+/* Show a probe point to output buffer */
+static void show_probepoint(Dwarf_Die sp_die, Dwarf_Signed offs,
+ struct probe_finder *pf)
+{
+ struct probe_point *pp = pf->pp;
+ char *name;
+ char tmp[MAX_PROBE_BUFFER];
+ int ret, i, len;
+
+ /* Output name of probe point */
+ ret = dwarf_diename(sp_die, &name, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (ret == DW_DLV_OK) {
+ ret = snprintf(tmp, MAX_PROBE_BUFFER, "%s+%u", name,
+ (unsigned int)offs);
+ /* Copy the function name if possible */
+ if (!pp->function) {
+ pp->function = strdup(name);
+ pp->offset = offs;
+ }
+ dwarf_dealloc(__dw_debug, name, DW_DLA_STRING);
+ } else {
+ /* This function has no name. */
+ ret = snprintf(tmp, MAX_PROBE_BUFFER, "0x%llx", pf->addr);
+ if (!pp->function) {
+ /* TODO: Use _stext */
+ pp->function = strdup("");
+ pp->offset = (int)pf->addr;
+ }
+ }
+ DIE_IF(ret < 0);
+ DIE_IF(ret >= MAX_PROBE_BUFFER);
+ len = ret;
+ pr_debug("Probe point found: %s\n", tmp);
+
+ /* Find each argument */
+ get_current_frame_base(sp_die, pf);
+ for (i = 0; i < pp->nr_args; i++) {
+ pf->var = pp->args[i];
+ pf->buf = &tmp[len];
+ pf->len = MAX_PROBE_BUFFER - len;
+ find_variable(sp_die, pf);
+ len += strlen(pf->buf);
+ }
+ free_current_frame_base(pf);
+
+ pp->probes[pp->found] = strdup(tmp);
+ pp->found++;
+}
+
+static int probeaddr_callback(struct die_link *dlink, void *data)
+{
+ struct probe_finder *pf = (struct probe_finder *)data;
+ Dwarf_Half tag;
+ Dwarf_Signed offs;
+ int ret;
+
+ ret = dwarf_tag(dlink->die, &tag, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ /* Check the address is in this subprogram */
+ if (tag == DW_TAG_subprogram &&
+ die_within_subprogram(dlink->die, pf->addr, &offs)) {
+ show_probepoint(dlink->die, offs, pf);
+ return 1;
+ }
+ return 0;
+}
+
+/* Find probe point from its line number */
+static void find_by_line(struct probe_finder *pf)
+{
+ Dwarf_Signed cnt, i, clm;
+ Dwarf_Line *lines;
+ Dwarf_Unsigned lineno = 0;
+ Dwarf_Addr addr;
+ Dwarf_Unsigned fno;
+ int ret;
+
+ ret = dwarf_srclines(pf->cu_die, &lines, &cnt, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+
+ for (i = 0; i < cnt; i++) {
+ ret = dwarf_line_srcfileno(lines[i], &fno, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ if (fno != pf->fno)
+ continue;
+
+ ret = dwarf_lineno(lines[i], &lineno, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ if (lineno != pf->lno)
+ continue;
+
+ ret = dwarf_lineoff(lines[i], &clm, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+
+ ret = dwarf_lineaddr(lines[i], &addr, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ pr_debug("Probe line found: line[%d]:%u,%d addr:0x%llx\n",
+ (int)i, (unsigned)lineno, (int)clm, addr);
+ pf->addr = addr;
+ /* Search a real subprogram including this line, */
+ ret = search_die_from_children(pf->cu_die,
+ probeaddr_callback, pf);
+ if (ret == 0)
+ die("Probe point is not found in subprograms.\n");
+ /* Continuing, because target line might be inlined. */
+ }
+ dwarf_srclines_dealloc(__dw_debug, lines, cnt);
+}
+
+/* Search function from function name */
+static int probefunc_callback(struct die_link *dlink, void *data)
+{
+ struct probe_finder *pf = (struct probe_finder *)data;
+ struct probe_point *pp = pf->pp;
+ struct die_link *lk;
+ Dwarf_Signed offs;
+ Dwarf_Half tag;
+ int ret;
+
+ ret = dwarf_tag(dlink->die, &tag, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (tag == DW_TAG_subprogram) {
+ if (die_compare_name(dlink->die, pp->function) == 0) {
+ if (pp->line) { /* Function relative line */
+ pf->fno = die_get_decl_file(dlink->die);
+ pf->lno = die_get_decl_line(dlink->die)
+ + pp->line;
+ find_by_line(pf);
+ return 1;
+ }
+ if (die_inlined_subprogram(dlink->die)) {
+ /* Inlined function, save it. */
+ ret = dwarf_die_CU_offset(dlink->die,
+ &pf->inl_offs,
+ &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+ pr_debug("inline definition offset %lld\n",
+ pf->inl_offs);
+ return 0; /* Continue to search */
+ }
+ /* Get probe address */
+ pf->addr = die_get_entrypc(dlink->die);
+ pf->addr += pp->offset;
+ /* TODO: Check the address in this function */
+ show_probepoint(dlink->die, pp->offset, pf);
+ return 1; /* Exit; no same symbol in this CU. */
+ }
+ } else if (tag == DW_TAG_inlined_subroutine && pf->inl_offs) {
+ if (die_get_abstract_origin(dlink->die) == pf->inl_offs) {
+ /* Get probe address */
+ pf->addr = die_get_entrypc(dlink->die);
+ pf->addr += pp->offset;
+ pr_debug("found inline addr: 0x%llx\n", pf->addr);
+ /* Inlined function. Get a real subprogram */
+ for (lk = dlink->parent; lk != NULL; lk = lk->parent) {
+ tag = 0;
+ dwarf_tag(lk->die, &tag, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (tag == DW_TAG_subprogram &&
+ !die_inlined_subprogram(lk->die))
+ goto found;
+ }
+ die("Failed to find real subprogram.\n");
+found:
+ /* Get offset from subprogram */
+ ret = die_within_subprogram(lk->die, pf->addr, &offs);
+ DIE_IF(!ret);
+ show_probepoint(lk->die, offs, pf);
+ /* Continue to search */
+ }
+ }
+ return 0;
+}
+
+static void find_by_func(struct probe_finder *pf)
+{
+ search_die_from_children(pf->cu_die, probefunc_callback, pf);
+}
+
+/* Find a probe point */
+int find_probepoint(int fd, struct probe_point *pp)
+{
+ Dwarf_Half addr_size = 0;
+ Dwarf_Unsigned next_cuh = 0;
+ int cu_number = 0, ret;
+ struct probe_finder pf = {.pp = pp};
+
+ ret = dwarf_init(fd, DW_DLC_READ, 0, 0, &__dw_debug, &__dw_error);
+ if (ret != DW_DLV_OK) {
+ pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO.\n");
+ return -ENOENT;
+ }
+
+ pp->found = 0;
+ while (++cu_number) {
+ /* Search CU (Compilation Unit) */
+ ret = dwarf_next_cu_header(__dw_debug, NULL, NULL, NULL,
+ &addr_size, &next_cuh, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (ret == DW_DLV_NO_ENTRY)
+ break;
+
+ /* Get the DIE(Debugging Information Entry) of this CU */
+ ret = dwarf_siblingof(__dw_debug, 0, &pf.cu_die, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+
+ /* Check if target file is included. */
+ if (pp->file)
+ pf.fno = cu_find_fileno(pf.cu_die, pp->file);
+
+ if (!pp->file || pf.fno) {
+ /* Save CU base address (for frame_base) */
+ ret = dwarf_lowpc(pf.cu_die, &pf.cu_base, &__dw_error);
+ DIE_IF(ret == DW_DLV_ERROR);
+ if (ret == DW_DLV_NO_ENTRY)
+ pf.cu_base = 0;
+ if (pp->function)
+ find_by_func(&pf);
+ else {
+ pf.lno = pp->line;
+ find_by_line(&pf);
+ }
+ }
+ dwarf_dealloc(__dw_debug, pf.cu_die, DW_DLA_DIE);
+ }
+ ret = dwarf_finish(__dw_debug, &__dw_error);
+ DIE_IF(ret != DW_DLV_OK);
+
+ return pp->found;
+}
+
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
new file mode 100644
index 000000000000..bdebca6697d2
--- /dev/null
+++ b/tools/perf/util/probe-finder.h
@@ -0,0 +1,57 @@
+#ifndef _PROBE_FINDER_H
+#define _PROBE_FINDER_H
+
+#define MAX_PATH_LEN 256
+#define MAX_PROBE_BUFFER 1024
+#define MAX_PROBES 128
+
+static inline int is_c_varname(const char *name)
+{
+ /* TODO */
+ return isalpha(name[0]) || name[0] == '_';
+}
+
+struct probe_point {
+ /* Inputs */
+ char *file; /* File name */
+ int line; /* Line number */
+
+ char *function; /* Function name */
+ int offset; /* Offset bytes */
+
+ int nr_args; /* Number of arguments */
+ char **args; /* Arguments */
+
+ int retprobe; /* Return probe */
+
+ /* Output */
+ int found; /* Number of found probe points */
+ char *probes[MAX_PROBES]; /* Output buffers (will be allocated)*/
+};
+
+#ifndef NO_LIBDWARF
+extern int find_probepoint(int fd, struct probe_point *pp);
+
+#include <libdwarf/dwarf.h>
+#include <libdwarf/libdwarf.h>
+
+struct probe_finder {
+ struct probe_point *pp; /* Target probe point */
+
+ /* For function searching */
+ Dwarf_Addr addr; /* Address */
+ Dwarf_Unsigned fno; /* File number */
+ Dwarf_Unsigned lno; /* Line number */
+ Dwarf_Off inl_offs; /* Inline offset */
+ Dwarf_Die cu_die; /* Current CU */
+
+ /* For variable searching */
+ Dwarf_Addr cu_base; /* Current CU base address */
+ Dwarf_Locdesc fbloc; /* Location of Current Frame Base */
+ const char *var; /* Current variable name */
+ char *buf; /* Current output buffer */
+ int len; /* Length of output buffer */
+};
+#endif /* NO_LIBDWARF */
+
+#endif /*_PROBE_FINDER_H */
diff --git a/tools/perf/util/quote.h b/tools/perf/util/quote.h
index a5454a1d1c13..b6a019733919 100644
--- a/tools/perf/util/quote.h
+++ b/tools/perf/util/quote.h
@@ -1,5 +1,5 @@
-#ifndef QUOTE_H
-#define QUOTE_H
+#ifndef __PERF_QUOTE_H
+#define __PERF_QUOTE_H
#include <stddef.h>
#include <stdio.h>
@@ -65,4 +65,4 @@ extern void perl_quote_print(FILE *stream, const char *src);
extern void python_quote_print(FILE *stream, const char *src);
extern void tcl_quote_print(FILE *stream, const char *src);
-#endif
+#endif /* __PERF_QUOTE_H */
diff --git a/tools/perf/util/run-command.h b/tools/perf/util/run-command.h
index cc1837deba88..d79028727ce2 100644
--- a/tools/perf/util/run-command.h
+++ b/tools/perf/util/run-command.h
@@ -1,5 +1,5 @@
-#ifndef RUN_COMMAND_H
-#define RUN_COMMAND_H
+#ifndef __PERF_RUN_COMMAND_H
+#define __PERF_RUN_COMMAND_H
enum {
ERR_RUN_COMMAND_FORK = 10000,
@@ -85,4 +85,4 @@ struct async {
int start_async(struct async *async);
int finish_async(struct async *async);
-#endif
+#endif /* __PERF_RUN_COMMAND_H */
diff --git a/tools/perf/util/sigchain.h b/tools/perf/util/sigchain.h
index 618083bce0c6..1a53c11265fd 100644
--- a/tools/perf/util/sigchain.h
+++ b/tools/perf/util/sigchain.h
@@ -1,5 +1,5 @@
-#ifndef SIGCHAIN_H
-#define SIGCHAIN_H
+#ifndef __PERF_SIGCHAIN_H
+#define __PERF_SIGCHAIN_H
typedef void (*sigchain_fun)(int);
@@ -8,4 +8,4 @@ int sigchain_pop(int sig);
void sigchain_push_common(sigchain_fun f);
-#endif /* SIGCHAIN_H */
+#endif /* __PERF_SIGCHAIN_H */
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
new file mode 100644
index 000000000000..b490354d1b23
--- /dev/null
+++ b/tools/perf/util/sort.c
@@ -0,0 +1,290 @@
+#include "sort.h"
+
+regex_t parent_regex;
+char default_parent_pattern[] = "^sys_|^do_page_fault";
+char *parent_pattern = default_parent_pattern;
+char default_sort_order[] = "comm,dso,symbol";
+char *sort_order = default_sort_order;
+int sort__need_collapse = 0;
+int sort__has_parent = 0;
+
+enum sort_type sort__first_dimension;
+
+unsigned int dsos__col_width;
+unsigned int comms__col_width;
+unsigned int threads__col_width;
+static unsigned int parent_symbol__col_width;
+char * field_sep;
+
+LIST_HEAD(hist_entry__sort_list);
+
+struct sort_entry sort_thread = {
+ .header = "Command: Pid",
+ .cmp = sort__thread_cmp,
+ .print = sort__thread_print,
+ .width = &threads__col_width,
+};
+
+struct sort_entry sort_comm = {
+ .header = "Command",
+ .cmp = sort__comm_cmp,
+ .collapse = sort__comm_collapse,
+ .print = sort__comm_print,
+ .width = &comms__col_width,
+};
+
+struct sort_entry sort_dso = {
+ .header = "Shared Object",
+ .cmp = sort__dso_cmp,
+ .print = sort__dso_print,
+ .width = &dsos__col_width,
+};
+
+struct sort_entry sort_sym = {
+ .header = "Symbol",
+ .cmp = sort__sym_cmp,
+ .print = sort__sym_print,
+};
+
+struct sort_entry sort_parent = {
+ .header = "Parent symbol",
+ .cmp = sort__parent_cmp,
+ .print = sort__parent_print,
+ .width = &parent_symbol__col_width,
+};
+
+struct sort_dimension {
+ const char *name;
+ struct sort_entry *entry;
+ int taken;
+};
+
+static struct sort_dimension sort_dimensions[] = {
+ { .name = "pid", .entry = &sort_thread, },
+ { .name = "comm", .entry = &sort_comm, },
+ { .name = "dso", .entry = &sort_dso, },
+ { .name = "symbol", .entry = &sort_sym, },
+ { .name = "parent", .entry = &sort_parent, },
+};
+
+int64_t cmp_null(void *l, void *r)
+{
+ if (!l && !r)
+ return 0;
+ else if (!l)
+ return -1;
+ else
+ return 1;
+}
+
+/* --sort pid */
+
+int64_t
+sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ return right->thread->pid - left->thread->pid;
+}
+
+int repsep_fprintf(FILE *fp, const char *fmt, ...)
+{
+ int n;
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (!field_sep)
+ n = vfprintf(fp, fmt, ap);
+ else {
+ char *bf = NULL;
+ n = vasprintf(&bf, fmt, ap);
+ if (n > 0) {
+ char *sep = bf;
+
+ while (1) {
+ sep = strchr(sep, *field_sep);
+ if (sep == NULL)
+ break;
+ *sep = '.';
+ }
+ }
+ fputs(bf, fp);
+ free(bf);
+ }
+ va_end(ap);
+ return n;
+}
+
+size_t
+sort__thread_print(FILE *fp, struct hist_entry *self, unsigned int width)
+{
+ return repsep_fprintf(fp, "%*s:%5d", width - 6,
+ self->thread->comm ?: "", self->thread->pid);
+}
+
+size_t
+sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
+{
+ return repsep_fprintf(fp, "%*s", width, self->thread->comm);
+}
+
+/* --sort dso */
+
+int64_t
+sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ struct dso *dso_l = left->map ? left->map->dso : NULL;
+ struct dso *dso_r = right->map ? right->map->dso : NULL;
+ const char *dso_name_l, *dso_name_r;
+
+ if (!dso_l || !dso_r)
+ return cmp_null(dso_l, dso_r);
+
+ if (verbose) {
+ dso_name_l = dso_l->long_name;
+ dso_name_r = dso_r->long_name;
+ } else {
+ dso_name_l = dso_l->short_name;
+ dso_name_r = dso_r->short_name;
+ }
+
+ return strcmp(dso_name_l, dso_name_r);
+}
+
+size_t
+sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width)
+{
+ if (self->map && self->map->dso) {
+ const char *dso_name = !verbose ? self->map->dso->short_name :
+ self->map->dso->long_name;
+ return repsep_fprintf(fp, "%-*s", width, dso_name);
+ }
+
+ return repsep_fprintf(fp, "%*llx", width, (u64)self->ip);
+}
+
+/* --sort symbol */
+
+int64_t
+sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ u64 ip_l, ip_r;
+
+ if (left->sym == right->sym)
+ return 0;
+
+ ip_l = left->sym ? left->sym->start : left->ip;
+ ip_r = right->sym ? right->sym->start : right->ip;
+
+ return (int64_t)(ip_r - ip_l);
+}
+
+
+size_t
+sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used)
+{
+ size_t ret = 0;
+
+ if (verbose) {
+ char o = self->map ? dso__symtab_origin(self->map->dso) : '!';
+ ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip, o);
+ }
+
+ ret += repsep_fprintf(fp, "[%c] ", self->level);
+ if (self->sym)
+ ret += repsep_fprintf(fp, "%s", self->sym->name);
+ else
+ ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip);
+
+ return ret;
+}
+
+/* --sort comm */
+
+int64_t
+sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ return right->thread->pid - left->thread->pid;
+}
+
+int64_t
+sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
+{
+ char *comm_l = left->thread->comm;
+ char *comm_r = right->thread->comm;
+
+ if (!comm_l || !comm_r)
+ return cmp_null(comm_l, comm_r);
+
+ return strcmp(comm_l, comm_r);
+}
+
+/* --sort parent */
+
+int64_t
+sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ struct symbol *sym_l = left->parent;
+ struct symbol *sym_r = right->parent;
+
+ if (!sym_l || !sym_r)
+ return cmp_null(sym_l, sym_r);
+
+ return strcmp(sym_l->name, sym_r->name);
+}
+
+size_t
+sort__parent_print(FILE *fp, struct hist_entry *self, unsigned int width)
+{
+ return repsep_fprintf(fp, "%-*s", width,
+ self->parent ? self->parent->name : "[other]");
+}
+
+int sort_dimension__add(const char *tok)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
+ struct sort_dimension *sd = &sort_dimensions[i];
+
+ if (sd->taken)
+ continue;
+
+ if (strncasecmp(tok, sd->name, strlen(tok)))
+ continue;
+
+ if (sd->entry->collapse)
+ sort__need_collapse = 1;
+
+ if (sd->entry == &sort_parent) {
+ int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
+ if (ret) {
+ char err[BUFSIZ];
+
+ regerror(ret, &parent_regex, err, sizeof(err));
+ fprintf(stderr, "Invalid regex: %s\n%s",
+ parent_pattern, err);
+ exit(-1);
+ }
+ sort__has_parent = 1;
+ }
+
+ if (list_empty(&hist_entry__sort_list)) {
+ if (!strcmp(sd->name, "pid"))
+ sort__first_dimension = SORT_PID;
+ else if (!strcmp(sd->name, "comm"))
+ sort__first_dimension = SORT_COMM;
+ else if (!strcmp(sd->name, "dso"))
+ sort__first_dimension = SORT_DSO;
+ else if (!strcmp(sd->name, "symbol"))
+ sort__first_dimension = SORT_SYM;
+ else if (!strcmp(sd->name, "parent"))
+ sort__first_dimension = SORT_PARENT;
+ }
+
+ list_add_tail(&sd->entry->list, &hist_entry__sort_list);
+ sd->taken = 1;
+
+ return 0;
+ }
+
+ return -ESRCH;
+}
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
new file mode 100644
index 000000000000..333e664ff45f
--- /dev/null
+++ b/tools/perf/util/sort.h
@@ -0,0 +1,99 @@
+#ifndef __PERF_SORT_H
+#define __PERF_SORT_H
+#include "../builtin.h"
+
+#include "util.h"
+
+#include "color.h"
+#include <linux/list.h>
+#include "cache.h"
+#include <linux/rbtree.h>
+#include "symbol.h"
+#include "string.h"
+#include "callchain.h"
+#include "strlist.h"
+#include "values.h"
+
+#include "../perf.h"
+#include "debug.h"
+#include "header.h"
+
+#include "parse-options.h"
+#include "parse-events.h"
+
+#include "thread.h"
+#include "sort.h"
+
+extern regex_t parent_regex;
+extern char *sort_order;
+extern char default_parent_pattern[];
+extern char *parent_pattern;
+extern char default_sort_order[];
+extern int sort__need_collapse;
+extern int sort__has_parent;
+extern char *field_sep;
+extern struct sort_entry sort_comm;
+extern struct sort_entry sort_dso;
+extern struct sort_entry sort_sym;
+extern struct sort_entry sort_parent;
+extern unsigned int dsos__col_width;
+extern unsigned int comms__col_width;
+extern unsigned int threads__col_width;
+extern enum sort_type sort__first_dimension;
+
+struct hist_entry {
+ struct rb_node rb_node;
+ u64 count;
+ struct thread *thread;
+ struct map *map;
+ struct symbol *sym;
+ u64 ip;
+ char level;
+ struct symbol *parent;
+ struct callchain_node callchain;
+ struct rb_root sorted_chain;
+};
+
+enum sort_type {
+ SORT_PID,
+ SORT_COMM,
+ SORT_DSO,
+ SORT_SYM,
+ SORT_PARENT
+};
+
+/*
+ * configurable sorting bits
+ */
+
+struct sort_entry {
+ struct list_head list;
+
+ const char *header;
+
+ int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
+ int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
+ size_t (*print)(FILE *fp, struct hist_entry *, unsigned int width);
+ unsigned int *width;
+ bool elide;
+};
+
+extern struct sort_entry sort_thread;
+extern struct list_head hist_entry__sort_list;
+
+extern int repsep_fprintf(FILE *fp, const char *fmt, ...);
+extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int);
+extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int);
+extern size_t sort__dso_print(FILE *, struct hist_entry *, unsigned int);
+extern size_t sort__sym_print(FILE *, struct hist_entry *, unsigned int __used);
+extern int64_t cmp_null(void *, void *);
+extern int64_t sort__thread_cmp(struct hist_entry *, struct hist_entry *);
+extern int64_t sort__comm_cmp(struct hist_entry *, struct hist_entry *);
+extern int64_t sort__comm_collapse(struct hist_entry *, struct hist_entry *);
+extern int64_t sort__dso_cmp(struct hist_entry *, struct hist_entry *);
+extern int64_t sort__sym_cmp(struct hist_entry *, struct hist_entry *);
+extern int64_t sort__parent_cmp(struct hist_entry *, struct hist_entry *);
+extern size_t sort__parent_print(FILE *, struct hist_entry *, unsigned int);
+extern int sort_dimension__add(const char *);
+
+#endif /* __PERF_SORT_H */
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h
index d2aa86c014c1..a3d121d6c83e 100644
--- a/tools/perf/util/strbuf.h
+++ b/tools/perf/util/strbuf.h
@@ -1,5 +1,5 @@
-#ifndef STRBUF_H
-#define STRBUF_H
+#ifndef __PERF_STRBUF_H
+#define __PERF_STRBUF_H
/*
* Strbuf's can be use in many ways: as a byte array, or to store arbitrary
@@ -134,4 +134,4 @@ extern int launch_editor(const char *path, struct strbuf *buffer, const char *co
extern int strbuf_branchname(struct strbuf *sb, const char *name);
extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name);
-#endif /* STRBUF_H */
+#endif /* __PERF_STRBUF_H */
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index c93eca9a7be3..f24a8cc933d5 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -1,4 +1,5 @@
#include "string.h"
+#include "util.h"
static int hex(char ch)
{
@@ -32,3 +33,196 @@ int hex2u64(const char *ptr, u64 *long_val)
return p - ptr;
}
+
+char *strxfrchar(char *s, char from, char to)
+{
+ char *p = s;
+
+ while ((p = strchr(p, from)) != NULL)
+ *p++ = to;
+
+ return s;
+}
+
+#define K 1024LL
+/*
+ * perf_atoll()
+ * Parse (\d+)(b|B|kb|KB|mb|MB|gb|GB|tb|TB) (e.g. "256MB")
+ * and return its numeric value
+ */
+s64 perf_atoll(const char *str)
+{
+ unsigned int i;
+ s64 length = -1, unit = 1;
+
+ if (!isdigit(str[0]))
+ goto out_err;
+
+ for (i = 1; i < strlen(str); i++) {
+ switch (str[i]) {
+ case 'B':
+ case 'b':
+ break;
+ case 'K':
+ if (str[i + 1] != 'B')
+ goto out_err;
+ else
+ goto kilo;
+ case 'k':
+ if (str[i + 1] != 'b')
+ goto out_err;
+kilo:
+ unit = K;
+ break;
+ case 'M':
+ if (str[i + 1] != 'B')
+ goto out_err;
+ else
+ goto mega;
+ case 'm':
+ if (str[i + 1] != 'b')
+ goto out_err;
+mega:
+ unit = K * K;
+ break;
+ case 'G':
+ if (str[i + 1] != 'B')
+ goto out_err;
+ else
+ goto giga;
+ case 'g':
+ if (str[i + 1] != 'b')
+ goto out_err;
+giga:
+ unit = K * K * K;
+ break;
+ case 'T':
+ if (str[i + 1] != 'B')
+ goto out_err;
+ else
+ goto tera;
+ case 't':
+ if (str[i + 1] != 'b')
+ goto out_err;
+tera:
+ unit = K * K * K * K;
+ break;
+ case '\0': /* only specified figures */
+ unit = 1;
+ break;
+ default:
+ if (!isdigit(str[i]))
+ goto out_err;
+ break;
+ }
+ }
+
+ length = atoll(str) * unit;
+ goto out;
+
+out_err:
+ length = -1;
+out:
+ return length;
+}
+
+/*
+ * Helper function for splitting a string into an argv-like array.
+ * originaly copied from lib/argv_split.c
+ */
+static const char *skip_sep(const char *cp)
+{
+ while (*cp && isspace(*cp))
+ cp++;
+
+ return cp;
+}
+
+static const char *skip_arg(const char *cp)
+{
+ while (*cp && !isspace(*cp))
+ cp++;
+
+ return cp;
+}
+
+static int count_argc(const char *str)
+{
+ int count = 0;
+
+ while (*str) {
+ str = skip_sep(str);
+ if (*str) {
+ count++;
+ str = skip_arg(str);
+ }
+ }
+
+ return count;
+}
+
+/**
+ * argv_free - free an argv
+ * @argv - the argument vector to be freed
+ *
+ * Frees an argv and the strings it points to.
+ */
+void argv_free(char **argv)
+{
+ char **p;
+ for (p = argv; *p; p++)
+ free(*p);
+
+ free(argv);
+}
+
+/**
+ * argv_split - split a string at whitespace, returning an argv
+ * @str: the string to be split
+ * @argcp: returned argument count
+ *
+ * Returns an array of pointers to strings which are split out from
+ * @str. This is performed by strictly splitting on white-space; no
+ * quote processing is performed. Multiple whitespace characters are
+ * considered to be a single argument separator. The returned array
+ * is always NULL-terminated. Returns NULL on memory allocation
+ * failure.
+ */
+char **argv_split(const char *str, int *argcp)
+{
+ int argc = count_argc(str);
+ char **argv = zalloc(sizeof(*argv) * (argc+1));
+ char **argvp;
+
+ if (argv == NULL)
+ goto out;
+
+ if (argcp)
+ *argcp = argc;
+
+ argvp = argv;
+
+ while (*str) {
+ str = skip_sep(str);
+
+ if (*str) {
+ const char *p = str;
+ char *t;
+
+ str = skip_arg(str);
+
+ t = strndup(p, str-p);
+ if (t == NULL)
+ goto fail;
+ *argvp++ = t;
+ }
+ }
+ *argvp = NULL;
+
+out:
+ return argv;
+
+fail:
+ argv_free(argv);
+ return NULL;
+}
diff --git a/tools/perf/util/string.h b/tools/perf/util/string.h
index bf39dfadfd24..bfecec265a1a 100644
--- a/tools/perf/util/string.h
+++ b/tools/perf/util/string.h
@@ -1,11 +1,15 @@
-#ifndef _PERF_STRING_H_
-#define _PERF_STRING_H_
+#ifndef __PERF_STRING_H_
+#define __PERF_STRING_H_
#include "types.h"
int hex2u64(const char *ptr, u64 *val);
+char *strxfrchar(char *s, char from, char to);
+s64 perf_atoll(const char *str);
+char **argv_split(const char *str, int *argcp);
+void argv_free(char **argv);
#define _STR(x) #x
#define STR(x) _STR(x)
-#endif
+#endif /* __PERF_STRING_H */
diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h
index 921818e44a54..cb4659306d7b 100644
--- a/tools/perf/util/strlist.h
+++ b/tools/perf/util/strlist.h
@@ -1,5 +1,5 @@
-#ifndef STRLIST_H_
-#define STRLIST_H_
+#ifndef __PERF_STRLIST_H
+#define __PERF_STRLIST_H
#include <linux/rbtree.h>
#include <stdbool.h>
@@ -36,4 +36,4 @@ static inline unsigned int strlist__nr_entries(const struct strlist *self)
}
int strlist__parse_list(struct strlist *self, const char *s);
-#endif /* STRLIST_H_ */
+#endif /* __PERF_STRLIST_H */
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index 856655d8b0b8..b3637db025a2 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -103,7 +103,7 @@ void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end)
fprintf(svgfile, " rect.process2 { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.sample { fill:rgb( 0, 0,255); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.blocked { fill:rgb(255, 0, 0); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
- fprintf(svgfile, " rect.waiting { fill:rgb(214,214, 0); fill-opacity:0.3; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
+ fprintf(svgfile, " rect.waiting { fill:rgb(224,214, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.WAITING { fill:rgb(255,214, 48); fill-opacity:0.6; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.cpu { fill:rgb(192,192,192); fill-opacity:0.2; stroke-width:0.5; stroke:rgb(128,128,128); } \n");
fprintf(svgfile, " rect.pstate { fill:rgb(128,128,128); fill-opacity:0.8; stroke-width:0; } \n");
diff --git a/tools/perf/util/svghelper.h b/tools/perf/util/svghelper.h
index cd93195aedb3..e0781989cc31 100644
--- a/tools/perf/util/svghelper.h
+++ b/tools/perf/util/svghelper.h
@@ -1,5 +1,5 @@
-#ifndef _INCLUDE_GUARD_SVG_HELPER_
-#define _INCLUDE_GUARD_SVG_HELPER_
+#ifndef __PERF_SVGHELPER_H
+#define __PERF_SVGHELPER_H
#include "types.h"
@@ -25,4 +25,4 @@ extern void svg_close(void);
extern int svg_page_width;
-#endif
+#endif /* __PERF_SVGHELPER_H */
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 47ea0609a760..fffcb937cdcb 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2,14 +2,20 @@
#include "../perf.h"
#include "string.h"
#include "symbol.h"
+#include "thread.h"
#include "debug.h"
+#include <asm/bug.h>
#include <libelf.h>
#include <gelf.h>
#include <elf.h>
+#include <limits.h>
+#include <sys/utsname.h>
-const char *sym_hist_filter;
+#ifndef NT_GNU_BUILD_ID
+#define NT_GNU_BUILD_ID 3
+#endif
enum dso_origin {
DSO__ORIG_KERNEL = 0,
@@ -18,94 +24,189 @@ enum dso_origin {
DSO__ORIG_UBUNTU,
DSO__ORIG_BUILDID,
DSO__ORIG_DSO,
+ DSO__ORIG_KMODULE,
DSO__ORIG_NOT_FOUND,
};
-static struct symbol *symbol__new(u64 start, u64 len,
- const char *name, unsigned int priv_size,
- u64 obj_start, int v)
+static void dsos__add(struct list_head *head, struct dso *dso);
+static struct map *thread__find_map_by_name(struct thread *self, char *name);
+static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
+struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
+static int dso__load_kernel_sym(struct dso *self, struct map *map,
+ struct thread *thread, symbol_filter_t filter);
+unsigned int symbol__priv_size;
+static int vmlinux_path__nr_entries;
+static char **vmlinux_path;
+
+static struct symbol_conf symbol_conf__defaults = {
+ .use_modules = true,
+ .try_vmlinux_path = true,
+};
+
+static struct thread kthread_mem;
+struct thread *kthread = &kthread_mem;
+
+bool dso__loaded(const struct dso *self, enum map_type type)
{
- size_t namelen = strlen(name) + 1;
- struct symbol *self = calloc(1, priv_size + sizeof(*self) + namelen);
+ return self->loaded & (1 << type);
+}
- if (!self)
- return NULL;
+static void dso__set_loaded(struct dso *self, enum map_type type)
+{
+ self->loaded |= (1 << type);
+}
- if (v >= 2)
- printf("new symbol: %016Lx [%08lx]: %s, hist: %p, obj_start: %p\n",
- (u64)start, (unsigned long)len, name, self->hist, (void *)(unsigned long)obj_start);
+static void symbols__fixup_end(struct rb_root *self)
+{
+ struct rb_node *nd, *prevnd = rb_first(self);
+ struct symbol *curr, *prev;
+
+ if (prevnd == NULL)
+ return;
- self->obj_start= obj_start;
- self->hist = NULL;
- self->hist_sum = 0;
+ curr = rb_entry(prevnd, struct symbol, rb_node);
- if (sym_hist_filter && !strcmp(name, sym_hist_filter))
- self->hist = calloc(sizeof(u64), len);
+ for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
+ prev = curr;
+ curr = rb_entry(nd, struct symbol, rb_node);
- if (priv_size) {
- memset(self, 0, priv_size);
- self = ((void *)self) + priv_size;
+ if (prev->end == prev->start)
+ prev->end = curr->start - 1;
}
+
+ /* Last entry */
+ if (curr->end == curr->start)
+ curr->end = roundup(curr->start, 4096);
+}
+
+static void __thread__fixup_maps_end(struct thread *self, enum map_type type)
+{
+ struct map *prev, *curr;
+ struct rb_node *nd, *prevnd = rb_first(&self->maps[type]);
+
+ if (prevnd == NULL)
+ return;
+
+ curr = rb_entry(prevnd, struct map, rb_node);
+
+ for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
+ prev = curr;
+ curr = rb_entry(nd, struct map, rb_node);
+ prev->end = curr->start - 1;
+ }
+
+ /*
+ * We still haven't the actual symbols, so guess the
+ * last map final address.
+ */
+ curr->end = ~0UL;
+}
+
+static void thread__fixup_maps_end(struct thread *self)
+{
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ __thread__fixup_maps_end(self, i);
+}
+
+static struct symbol *symbol__new(u64 start, u64 len, const char *name)
+{
+ size_t namelen = strlen(name) + 1;
+ struct symbol *self = zalloc(symbol__priv_size +
+ sizeof(*self) + namelen);
+ if (self == NULL)
+ return NULL;
+
+ if (symbol__priv_size)
+ self = ((void *)self) + symbol__priv_size;
+
self->start = start;
self->end = len ? start + len - 1 : start;
+
+ pr_debug3("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
+
memcpy(self->name, name, namelen);
return self;
}
-static void symbol__delete(struct symbol *self, unsigned int priv_size)
+static void symbol__delete(struct symbol *self)
{
- free(((void *)self) - priv_size);
+ free(((void *)self) - symbol__priv_size);
}
static size_t symbol__fprintf(struct symbol *self, FILE *fp)
{
- if (!self->module)
- return fprintf(fp, " %llx-%llx %s\n",
+ return fprintf(fp, " %llx-%llx %s\n",
self->start, self->end, self->name);
- else
- return fprintf(fp, " %llx-%llx %s \t[%s]\n",
- self->start, self->end, self->name, self->module->name);
}
-struct dso *dso__new(const char *name, unsigned int sym_priv_size)
+static void dso__set_long_name(struct dso *self, char *name)
+{
+ if (name == NULL)
+ return;
+ self->long_name = name;
+ self->long_name_len = strlen(name);
+}
+
+static void dso__set_basename(struct dso *self)
+{
+ self->short_name = basename(self->long_name);
+}
+
+struct dso *dso__new(const char *name)
{
struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);
if (self != NULL) {
+ int i;
strcpy(self->name, name);
- self->syms = RB_ROOT;
- self->sym_priv_size = sym_priv_size;
+ dso__set_long_name(self, self->name);
+ self->short_name = self->name;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ self->symbols[i] = RB_ROOT;
self->find_symbol = dso__find_symbol;
self->slen_calculated = 0;
self->origin = DSO__ORIG_NOT_FOUND;
+ self->loaded = 0;
+ self->has_build_id = 0;
}
return self;
}
-static void dso__delete_symbols(struct dso *self)
+static void symbols__delete(struct rb_root *self)
{
struct symbol *pos;
- struct rb_node *next = rb_first(&self->syms);
+ struct rb_node *next = rb_first(self);
while (next) {
pos = rb_entry(next, struct symbol, rb_node);
next = rb_next(&pos->rb_node);
- rb_erase(&pos->rb_node, &self->syms);
- symbol__delete(pos, self->sym_priv_size);
+ rb_erase(&pos->rb_node, self);
+ symbol__delete(pos);
}
}
void dso__delete(struct dso *self)
{
- dso__delete_symbols(self);
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ symbols__delete(&self->symbols[i]);
+ if (self->long_name != self->name)
+ free(self->long_name);
free(self);
}
-static void dso__insert_symbol(struct dso *self, struct symbol *sym)
+void dso__set_build_id(struct dso *self, void *build_id)
{
- struct rb_node **p = &self->syms.rb_node;
+ memcpy(self->build_id, build_id, sizeof(self->build_id));
+ self->has_build_id = 1;
+}
+
+static void symbols__insert(struct rb_root *self, struct symbol *sym)
+{
+ struct rb_node **p = &self->rb_node;
struct rb_node *parent = NULL;
const u64 ip = sym->start;
struct symbol *s;
@@ -119,17 +220,17 @@ static void dso__insert_symbol(struct dso *self, struct symbol *sym)
p = &(*p)->rb_right;
}
rb_link_node(&sym->rb_node, parent, p);
- rb_insert_color(&sym->rb_node, &self->syms);
+ rb_insert_color(&sym->rb_node, self);
}
-struct symbol *dso__find_symbol(struct dso *self, u64 ip)
+static struct symbol *symbols__find(struct rb_root *self, u64 ip)
{
struct rb_node *n;
if (self == NULL)
return NULL;
- n = self->syms.rb_node;
+ n = self->rb_node;
while (n) {
struct symbol *s = rb_entry(n, struct symbol, rb_node);
@@ -145,12 +246,42 @@ struct symbol *dso__find_symbol(struct dso *self, u64 ip)
return NULL;
}
-size_t dso__fprintf(struct dso *self, FILE *fp)
+struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr)
{
- size_t ret = fprintf(fp, "dso: %s\n", self->name);
+ return symbols__find(&self->symbols[type], addr);
+}
+
+int build_id__sprintf(u8 *self, int len, char *bf)
+{
+ char *bid = bf;
+ u8 *raw = self;
+ int i;
+
+ for (i = 0; i < len; ++i) {
+ sprintf(bid, "%02x", *raw);
+ ++raw;
+ bid += 2;
+ }
+
+ return raw - self;
+}
+
+size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
+{
+ char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+ build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
+ return fprintf(fp, "%s", sbuild_id);
+}
+size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp)
+{
struct rb_node *nd;
- for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) {
+ size_t ret = fprintf(fp, "dso: %s (", self->short_name);
+
+ ret += dso__fprintf_buildid(self, fp);
+ ret += fprintf(fp, ")\n");
+ for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) {
struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
ret += symbol__fprintf(pos, fp);
}
@@ -158,13 +289,17 @@ size_t dso__fprintf(struct dso *self, FILE *fp)
return ret;
}
-static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int v)
+/*
+ * Loads the function entries in /proc/kallsyms into kernel_map->dso,
+ * so that we can in the next step set the symbol ->end address and then
+ * call kernel_maps__split_kallsyms.
+ */
+static int dso__load_all_kallsyms(struct dso *self, struct map *map)
{
- struct rb_node *nd, *prevnd;
char *line = NULL;
size_t n;
+ struct rb_root *root = &self->symbols[map->type];
FILE *file = fopen("/proc/kallsyms", "r");
- int count = 0;
if (file == NULL)
goto out_failure;
@@ -174,6 +309,7 @@ static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int v)
struct symbol *sym;
int line_len, len;
char symbol_type;
+ char *symbol_name;
line_len = getline(&line, &n, file);
if (line_len < 0)
@@ -196,44 +332,26 @@ static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int v)
*/
if (symbol_type != 'T' && symbol_type != 'W')
continue;
+
+ symbol_name = line + len + 2;
/*
- * Well fix up the end later, when we have all sorted.
+ * Will fix up the end later, when we have all symbols sorted.
*/
- sym = symbol__new(start, 0xdead, line + len + 2,
- self->sym_priv_size, 0, v);
+ sym = symbol__new(start, 0, symbol_name);
if (sym == NULL)
goto out_delete_line;
-
- if (filter && filter(self, sym))
- symbol__delete(sym, self->sym_priv_size);
- else {
- dso__insert_symbol(self, sym);
- count++;
- }
- }
-
- /*
- * Now that we have all sorted out, just set the ->end of all
- * symbols
- */
- prevnd = rb_first(&self->syms);
-
- if (prevnd == NULL)
- goto out_delete_line;
-
- for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
- struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node),
- *curr = rb_entry(nd, struct symbol, rb_node);
-
- prev->end = curr->start - 1;
- prevnd = nd;
+ /*
+ * We will pass the symbols to the filter later, in
+ * map__split_kallsyms, when we have split the maps per module
+ */
+ symbols__insert(root, sym);
}
free(line);
fclose(file);
- return count;
+ return 0;
out_delete_line:
free(line);
@@ -241,14 +359,114 @@ out_failure:
return -1;
}
-static int dso__load_perf_map(struct dso *self, symbol_filter_t filter, int v)
+/*
+ * Split the symbols into maps, making sure there are no overlaps, i.e. the
+ * kernel range is broken in several maps, named [kernel].N, as we don't have
+ * the original ELF section names vmlinux have.
+ */
+static int dso__split_kallsyms(struct dso *self, struct map *map, struct thread *thread,
+ symbol_filter_t filter)
+{
+ struct map *curr_map = map;
+ struct symbol *pos;
+ int count = 0;
+ struct rb_root *root = &self->symbols[map->type];
+ struct rb_node *next = rb_first(root);
+ int kernel_range = 0;
+
+ while (next) {
+ char *module;
+
+ pos = rb_entry(next, struct symbol, rb_node);
+ next = rb_next(&pos->rb_node);
+
+ module = strchr(pos->name, '\t');
+ if (module) {
+ if (!thread->use_modules)
+ goto discard_symbol;
+
+ *module++ = '\0';
+
+ if (strcmp(self->name, module)) {
+ curr_map = thread__find_map_by_name(thread, module);
+ if (curr_map == NULL) {
+ pr_debug("/proc/{kallsyms,modules} "
+ "inconsistency!\n");
+ return -1;
+ }
+ }
+ /*
+ * So that we look just like we get from .ko files,
+ * i.e. not prelinked, relative to map->start.
+ */
+ pos->start = curr_map->map_ip(curr_map, pos->start);
+ pos->end = curr_map->map_ip(curr_map, pos->end);
+ } else if (curr_map != map) {
+ char dso_name[PATH_MAX];
+ struct dso *dso;
+
+ snprintf(dso_name, sizeof(dso_name), "[kernel].%d",
+ kernel_range++);
+
+ dso = dso__new(dso_name);
+ if (dso == NULL)
+ return -1;
+
+ curr_map = map__new2(pos->start, dso, map->type);
+ if (map == NULL) {
+ dso__delete(dso);
+ return -1;
+ }
+
+ curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
+ __thread__insert_map(thread, curr_map);
+ ++kernel_range;
+ }
+
+ if (filter && filter(curr_map, pos)) {
+discard_symbol: rb_erase(&pos->rb_node, root);
+ symbol__delete(pos);
+ } else {
+ if (curr_map != map) {
+ rb_erase(&pos->rb_node, root);
+ symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
+ }
+ count++;
+ }
+ }
+
+ return count;
+}
+
+
+static int dso__load_kallsyms(struct dso *self, struct map *map,
+ struct thread *thread, symbol_filter_t filter)
+{
+ if (dso__load_all_kallsyms(self, map) < 0)
+ return -1;
+
+ symbols__fixup_end(&self->symbols[map->type]);
+ self->origin = DSO__ORIG_KERNEL;
+
+ return dso__split_kallsyms(self, map, thread, filter);
+}
+
+size_t kernel_maps__fprintf(FILE *fp)
+{
+ size_t printed = fprintf(fp, "Kernel maps:\n");
+ printed += thread__fprintf_maps(kthread, fp);
+ return printed + fprintf(fp, "END kernel maps\n");
+}
+
+static int dso__load_perf_map(struct dso *self, struct map *map,
+ symbol_filter_t filter)
{
char *line = NULL;
size_t n;
FILE *file;
int nr_syms = 0;
- file = fopen(self->name, "r");
+ file = fopen(self->long_name, "r");
if (file == NULL)
goto out_failure;
@@ -278,16 +496,15 @@ static int dso__load_perf_map(struct dso *self, symbol_filter_t filter, int v)
if (len + 2 >= line_len)
continue;
- sym = symbol__new(start, size, line + len,
- self->sym_priv_size, start, v);
+ sym = symbol__new(start, size, line + len);
if (sym == NULL)
goto out_delete_line;
- if (filter && filter(self, sym))
- symbol__delete(sym, self->sym_priv_size);
+ if (filter && filter(map, sym))
+ symbol__delete(sym);
else {
- dso__insert_symbol(self, sym);
+ symbols__insert(&self->symbols[map->type], sym);
nr_syms++;
}
}
@@ -393,7 +610,8 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
* And always look at the original dso, not at debuginfo packages, that
* have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
*/
-static int dso__synthesize_plt_symbols(struct dso *self, int v)
+static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
+ symbol_filter_t filter)
{
uint32_t nr_rel_entries, idx;
GElf_Sym sym;
@@ -409,11 +627,11 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
Elf *elf;
int nr = 0, symidx, fd, err = 0;
- fd = open(self->name, O_RDONLY);
+ fd = open(self->long_name, O_RDONLY);
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL)
goto out_close;
@@ -477,12 +695,16 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
"%s@plt", elf_sym__name(&sym, symstrs));
f = symbol__new(plt_offset, shdr_plt.sh_entsize,
- sympltname, self->sym_priv_size, 0, v);
+ sympltname);
if (!f)
goto out_elf_end;
- dso__insert_symbol(self, f);
- ++nr;
+ if (filter && filter(map, f))
+ symbol__delete(f);
+ else {
+ symbols__insert(&self->symbols[map->type], f);
+ ++nr;
+ }
}
} else if (shdr_rel_plt.sh_type == SHT_REL) {
GElf_Rel pos_mem, *pos;
@@ -495,12 +717,16 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
"%s@plt", elf_sym__name(&sym, symstrs));
f = symbol__new(plt_offset, shdr_plt.sh_entsize,
- sympltname, self->sym_priv_size, 0, v);
+ sympltname);
if (!f)
goto out_elf_end;
- dso__insert_symbol(self, f);
- ++nr;
+ if (filter && filter(map, f))
+ symbol__delete(f);
+ else {
+ symbols__insert(&self->symbols[map->type], f);
+ ++nr;
+ }
}
}
@@ -513,14 +739,18 @@ out_close:
if (err == 0)
return nr;
out:
- fprintf(stderr, "%s: problems reading %s PLT info.\n",
- __func__, self->name);
+ pr_warning("%s: problems reading %s PLT info.\n",
+ __func__, self->long_name);
return 0;
}
-static int dso__load_sym(struct dso *self, int fd, const char *name,
- symbol_filter_t filter, int v, struct module *mod)
+static int dso__load_sym(struct dso *self, struct map *map,
+ struct thread *thread, const char *name, int fd,
+ symbol_filter_t filter, int kernel, int kmodule)
{
+ struct map *curr_map = map;
+ struct dso *curr_dso = self;
+ size_t dso_name_len = strlen(self->short_name);
Elf_Data *symstrs, *secstrs;
uint32_t nr_syms;
int err = -1;
@@ -531,19 +761,16 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
GElf_Sym sym;
Elf_Scn *sec, *sec_strndx;
Elf *elf;
- int nr = 0, kernel = !strcmp("[kernel]", self->name);
+ int nr = 0;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL) {
- if (v)
- fprintf(stderr, "%s: cannot read %s ELF file.\n",
- __func__, name);
+ pr_err("%s: cannot read %s ELF file.\n", __func__, name);
goto out_close;
}
if (gelf_getehdr(elf, &ehdr) == NULL) {
- if (v)
- fprintf(stderr, "%s: cannot get elf header.\n", __func__);
+ pr_err("%s: cannot get elf header.\n", __func__);
goto out_elf_end;
}
@@ -587,9 +814,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
struct symbol *f;
const char *elf_name;
- char *demangled;
- u64 obj_start;
- struct section *section = NULL;
+ char *demangled = NULL;
int is_label = elf_sym__is_label(&sym);
const char *section_name;
@@ -605,52 +830,85 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
if (is_label && !elf_sec__is_text(&shdr, secstrs))
continue;
+ elf_name = elf_sym__name(&sym, symstrs);
section_name = elf_sec__name(&shdr, secstrs);
- obj_start = sym.st_value;
- if (self->adjust_symbols) {
- if (v >= 2)
- printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
- (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
+ if (kernel || kmodule) {
+ char dso_name[PATH_MAX];
- sym.st_value -= shdr.sh_addr - shdr.sh_offset;
- }
+ if (strcmp(section_name,
+ curr_dso->short_name + dso_name_len) == 0)
+ goto new_symbol;
- if (mod) {
- section = mod->sections->find_section(mod->sections, section_name);
- if (section)
- sym.st_value += section->vma;
- else {
- fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n",
- mod->name, section_name);
- goto out_elf_end;
+ if (strcmp(section_name, ".text") == 0) {
+ curr_map = map;
+ curr_dso = self;
+ goto new_symbol;
}
+
+ snprintf(dso_name, sizeof(dso_name),
+ "%s%s", self->short_name, section_name);
+
+ curr_map = thread__find_map_by_name(thread, dso_name);
+ if (curr_map == NULL) {
+ u64 start = sym.st_value;
+
+ if (kmodule)
+ start += map->start + shdr.sh_offset;
+
+ curr_dso = dso__new(dso_name);
+ if (curr_dso == NULL)
+ goto out_elf_end;
+ curr_map = map__new2(start, curr_dso,
+ MAP__FUNCTION);
+ if (curr_map == NULL) {
+ dso__delete(curr_dso);
+ goto out_elf_end;
+ }
+ curr_map->map_ip = identity__map_ip;
+ curr_map->unmap_ip = identity__map_ip;
+ curr_dso->origin = DSO__ORIG_KERNEL;
+ __thread__insert_map(kthread, curr_map);
+ dsos__add(&dsos__kernel, curr_dso);
+ } else
+ curr_dso = curr_map->dso;
+
+ goto new_symbol;
+ }
+
+ if (curr_dso->adjust_symbols) {
+ pr_debug2("adjusting symbol: st_value: %Lx sh_addr: "
+ "%Lx sh_offset: %Lx\n", (u64)sym.st_value,
+ (u64)shdr.sh_addr, (u64)shdr.sh_offset);
+ sym.st_value -= shdr.sh_addr - shdr.sh_offset;
}
/*
* We need to figure out if the object was created from C++ sources
* DWARF DW_compile_unit has this, but we don't always have access
* to it...
*/
- elf_name = elf_sym__name(&sym, symstrs);
demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
if (demangled != NULL)
elf_name = demangled;
-
- f = symbol__new(sym.st_value, sym.st_size, elf_name,
- self->sym_priv_size, obj_start, v);
+new_symbol:
+ f = symbol__new(sym.st_value, sym.st_size, elf_name);
free(demangled);
if (!f)
goto out_elf_end;
- if (filter && filter(self, f))
- symbol__delete(f, self->sym_priv_size);
+ if (filter && filter(curr_map, f))
+ symbol__delete(f);
else {
- f->module = mod;
- dso__insert_symbol(self, f);
+ symbols__insert(&curr_dso->symbols[curr_map->type], f);
nr++;
}
}
+ /*
+ * For misannotated, zeroed, ASM function sizes.
+ */
+ if (nr > 0)
+ symbols__fixup_end(&self->symbols[map->type]);
err = nr;
out_elf_end:
elf_end(elf);
@@ -658,63 +916,153 @@ out_close:
return err;
}
-#define BUILD_ID_SIZE 128
+static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
+{
+ return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
+}
-static char *dso__read_build_id(struct dso *self, int v)
+static bool __dsos__read_build_ids(struct list_head *head)
{
- int i;
+ bool have_build_id = false;
+ struct dso *pos;
+
+ list_for_each_entry(pos, head, node)
+ if (filename__read_build_id(pos->long_name, pos->build_id,
+ sizeof(pos->build_id)) > 0) {
+ have_build_id = true;
+ pos->has_build_id = true;
+ }
+
+ return have_build_id;
+}
+
+bool dsos__read_build_ids(void)
+{
+ return __dsos__read_build_ids(&dsos__kernel) ||
+ __dsos__read_build_ids(&dsos__user);
+}
+
+/*
+ * Align offset to 4 bytes as needed for note name and descriptor data.
+ */
+#define NOTE_ALIGN(n) (((n) + 3) & -4U)
+
+int filename__read_build_id(const char *filename, void *bf, size_t size)
+{
+ int fd, err = -1;
GElf_Ehdr ehdr;
GElf_Shdr shdr;
- Elf_Data *build_id_data;
+ Elf_Data *data;
Elf_Scn *sec;
- char *build_id = NULL, *bid;
- unsigned char *raw;
+ Elf_Kind ek;
+ void *ptr;
Elf *elf;
- int fd = open(self->name, O_RDONLY);
+ if (size < BUILD_ID_SIZE)
+ goto out;
+
+ fd = open(filename, O_RDONLY);
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL) {
- if (v)
- fprintf(stderr, "%s: cannot read %s ELF file.\n",
- __func__, self->name);
+ pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
goto out_close;
}
+ ek = elf_kind(elf);
+ if (ek != ELF_K_ELF)
+ goto out_elf_end;
+
if (gelf_getehdr(elf, &ehdr) == NULL) {
- if (v)
- fprintf(stderr, "%s: cannot get elf header.\n", __func__);
+ pr_err("%s: cannot get elf header.\n", __func__);
goto out_elf_end;
}
- sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL);
- if (sec == NULL)
- goto out_elf_end;
+ sec = elf_section_by_name(elf, &ehdr, &shdr,
+ ".note.gnu.build-id", NULL);
+ if (sec == NULL) {
+ sec = elf_section_by_name(elf, &ehdr, &shdr,
+ ".notes", NULL);
+ if (sec == NULL)
+ goto out_elf_end;
+ }
- build_id_data = elf_getdata(sec, NULL);
- if (build_id_data == NULL)
- goto out_elf_end;
- build_id = malloc(BUILD_ID_SIZE);
- if (build_id == NULL)
+ data = elf_getdata(sec, NULL);
+ if (data == NULL)
goto out_elf_end;
- raw = build_id_data->d_buf + 16;
- bid = build_id;
- for (i = 0; i < 20; ++i) {
- sprintf(bid, "%02x", *raw);
- ++raw;
- bid += 2;
+ ptr = data->d_buf;
+ while (ptr < (data->d_buf + data->d_size)) {
+ GElf_Nhdr *nhdr = ptr;
+ int namesz = NOTE_ALIGN(nhdr->n_namesz),
+ descsz = NOTE_ALIGN(nhdr->n_descsz);
+ const char *name;
+
+ ptr += sizeof(*nhdr);
+ name = ptr;
+ ptr += namesz;
+ if (nhdr->n_type == NT_GNU_BUILD_ID &&
+ nhdr->n_namesz == sizeof("GNU")) {
+ if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
+ memcpy(bf, ptr, BUILD_ID_SIZE);
+ err = BUILD_ID_SIZE;
+ break;
+ }
+ }
+ ptr += descsz;
}
- if (v >= 2)
- printf("%s(%s): %s\n", __func__, self->name, build_id);
out_elf_end:
elf_end(elf);
out_close:
close(fd);
out:
- return build_id;
+ return err;
+}
+
+int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
+{
+ int fd, err = -1;
+
+ if (size < BUILD_ID_SIZE)
+ goto out;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ goto out;
+
+ while (1) {
+ char bf[BUFSIZ];
+ GElf_Nhdr nhdr;
+ int namesz, descsz;
+
+ if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
+ break;
+
+ namesz = NOTE_ALIGN(nhdr.n_namesz);
+ descsz = NOTE_ALIGN(nhdr.n_descsz);
+ if (nhdr.n_type == NT_GNU_BUILD_ID &&
+ nhdr.n_namesz == sizeof("GNU")) {
+ if (read(fd, bf, namesz) != namesz)
+ break;
+ if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
+ if (read(fd, build_id,
+ BUILD_ID_SIZE) == BUILD_ID_SIZE) {
+ err = 0;
+ break;
+ }
+ } else if (read(fd, bf, descsz) != descsz)
+ break;
+ } else {
+ int n = namesz + descsz;
+ if (read(fd, bf, n) != n)
+ break;
+ }
+ }
+ close(fd);
+out:
+ return err;
}
char dso__symtab_origin(const struct dso *self)
@@ -726,6 +1074,7 @@ char dso__symtab_origin(const struct dso *self)
[DSO__ORIG_UBUNTU] = 'u',
[DSO__ORIG_BUILDID] = 'b',
[DSO__ORIG_DSO] = 'd',
+ [DSO__ORIG_KMODULE] = 'K',
};
if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
@@ -733,20 +1082,27 @@ char dso__symtab_origin(const struct dso *self)
return origin[self->origin];
}
-int dso__load(struct dso *self, symbol_filter_t filter, int v)
+int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
{
int size = PATH_MAX;
- char *name = malloc(size), *build_id = NULL;
+ char *name;
+ u8 build_id[BUILD_ID_SIZE];
int ret = -1;
int fd;
+ dso__set_loaded(self, map->type);
+
+ if (self->kernel)
+ return dso__load_kernel_sym(self, map, kthread, filter);
+
+ name = malloc(size);
if (!name)
return -1;
self->adjust_symbols = 0;
if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
- ret = dso__load_perf_map(self, filter, v);
+ ret = dso__load_perf_map(self, map, filter);
self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
DSO__ORIG_NOT_FOUND;
return ret;
@@ -759,34 +1115,50 @@ more:
self->origin++;
switch (self->origin) {
case DSO__ORIG_FEDORA:
- snprintf(name, size, "/usr/lib/debug%s.debug", self->name);
+ snprintf(name, size, "/usr/lib/debug%s.debug",
+ self->long_name);
break;
case DSO__ORIG_UBUNTU:
- snprintf(name, size, "/usr/lib/debug%s", self->name);
+ snprintf(name, size, "/usr/lib/debug%s",
+ self->long_name);
break;
case DSO__ORIG_BUILDID:
- build_id = dso__read_build_id(self, v);
- if (build_id != NULL) {
+ if (filename__read_build_id(self->long_name, build_id,
+ sizeof(build_id))) {
+ char build_id_hex[BUILD_ID_SIZE * 2 + 1];
+
+ build_id__sprintf(build_id, sizeof(build_id),
+ build_id_hex);
snprintf(name, size,
"/usr/lib/debug/.build-id/%.2s/%s.debug",
- build_id, build_id + 2);
- free(build_id);
+ build_id_hex, build_id_hex + 2);
+ if (self->has_build_id)
+ goto compare_build_id;
break;
}
self->origin++;
/* Fall thru */
case DSO__ORIG_DSO:
- snprintf(name, size, "%s", self->name);
+ snprintf(name, size, "%s", self->long_name);
break;
default:
goto out;
}
+ if (self->has_build_id) {
+ if (filename__read_build_id(name, build_id,
+ sizeof(build_id)) < 0)
+ goto more;
+compare_build_id:
+ if (!dso__build_id_equal(self, build_id))
+ goto more;
+ }
+
fd = open(name, O_RDONLY);
} while (fd < 0);
- ret = dso__load_sym(self, fd, name, filter, v, NULL);
+ ret = dso__load_sym(self, map, NULL, name, fd, filter, 0, 0);
close(fd);
/*
@@ -796,7 +1168,7 @@ more:
goto more;
if (ret > 0) {
- int nr_plt = dso__synthesize_plt_symbols(self, v);
+ int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
if (nr_plt > 0)
ret += nr_plt;
}
@@ -807,151 +1179,279 @@ out:
return ret;
}
-static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name,
- symbol_filter_t filter, int v)
+static struct map *thread__find_map_by_name(struct thread *self, char *name)
{
- struct module *mod = mod_dso__find_module(mods, name);
- int err = 0, fd;
+ struct rb_node *nd;
- if (mod == NULL || !mod->active)
- return err;
+ for (nd = rb_first(&self->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) {
+ struct map *map = rb_entry(nd, struct map, rb_node);
- fd = open(mod->path, O_RDONLY);
+ if (map->dso && strcmp(map->dso->name, name) == 0)
+ return map;
+ }
- if (fd < 0)
- return err;
+ return NULL;
+}
- err = dso__load_sym(self, fd, name, filter, v, mod);
- close(fd);
+static int dsos__set_modules_path_dir(char *dirname)
+{
+ struct dirent *dent;
+ DIR *dir = opendir(dirname);
- return err;
+ if (!dir) {
+ pr_debug("%s: cannot open %s dir\n", __func__, dirname);
+ return -1;
+ }
+
+ while ((dent = readdir(dir)) != NULL) {
+ char path[PATH_MAX];
+
+ if (dent->d_type == DT_DIR) {
+ if (!strcmp(dent->d_name, ".") ||
+ !strcmp(dent->d_name, ".."))
+ continue;
+
+ snprintf(path, sizeof(path), "%s/%s",
+ dirname, dent->d_name);
+ if (dsos__set_modules_path_dir(path) < 0)
+ goto failure;
+ } else {
+ char *dot = strrchr(dent->d_name, '.'),
+ dso_name[PATH_MAX];
+ struct map *map;
+ char *long_name;
+
+ if (dot == NULL || strcmp(dot, ".ko"))
+ continue;
+ snprintf(dso_name, sizeof(dso_name), "[%.*s]",
+ (int)(dot - dent->d_name), dent->d_name);
+
+ strxfrchar(dso_name, '-', '_');
+ map = thread__find_map_by_name(kthread, dso_name);
+ if (map == NULL)
+ continue;
+
+ snprintf(path, sizeof(path), "%s/%s",
+ dirname, dent->d_name);
+
+ long_name = strdup(path);
+ if (long_name == NULL)
+ goto failure;
+ dso__set_long_name(map->dso, long_name);
+ }
+ }
+
+ return 0;
+failure:
+ closedir(dir);
+ return -1;
}
-int dso__load_modules(struct dso *self, symbol_filter_t filter, int v)
+static int dsos__set_modules_path(void)
{
- struct mod_dso *mods = mod_dso__new_dso("modules");
- struct module *pos;
- struct rb_node *next;
- int err, count = 0;
+ struct utsname uts;
+ char modules_path[PATH_MAX];
- err = mod_dso__load_modules(mods);
-
- if (err <= 0)
- return err;
+ if (uname(&uts) < 0)
+ return -1;
- /*
- * Iterate over modules, and load active symbols.
- */
- next = rb_first(&mods->mods);
- while (next) {
- pos = rb_entry(next, struct module, rb_node);
- err = dso__load_module(self, mods, pos->name, filter, v);
+ snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
+ uts.release);
- if (err < 0)
- break;
+ return dsos__set_modules_path_dir(modules_path);
+}
- next = rb_next(&pos->rb_node);
- count += err;
- }
+/*
+ * Constructor variant for modules (where we know from /proc/modules where
+ * they are loaded) and for vmlinux, where only after we load all the
+ * symbols we'll know where it starts and ends.
+ */
+static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
+{
+ struct map *self = malloc(sizeof(*self));
- if (err < 0) {
- mod_dso__delete_modules(mods);
- mod_dso__delete_self(mods);
- return err;
+ if (self != NULL) {
+ /*
+ * ->end will be filled after we load all the symbols
+ */
+ map__init(self, type, start, 0, 0, dso);
}
- return count;
+ return self;
}
-static inline void dso__fill_symbol_holes(struct dso *self)
+static int thread__create_module_maps(struct thread *self)
{
- struct symbol *prev = NULL;
- struct rb_node *nd;
+ char *line = NULL;
+ size_t n;
+ FILE *file = fopen("/proc/modules", "r");
+ struct map *map;
- for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) {
- struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
+ if (file == NULL)
+ return -1;
- if (prev) {
- u64 hole = 0;
- int alias = pos->start == prev->start;
+ while (!feof(file)) {
+ char name[PATH_MAX];
+ u64 start;
+ struct dso *dso;
+ char *sep;
+ int line_len;
- if (!alias)
- hole = prev->start - pos->end - 1;
+ line_len = getline(&line, &n, file);
+ if (line_len < 0)
+ break;
- if (hole || alias) {
- if (alias)
- pos->end = prev->end;
- else if (hole)
- pos->end = prev->start - 1;
- }
+ if (!line)
+ goto out_failure;
+
+ line[--line_len] = '\0'; /* \n */
+
+ sep = strrchr(line, 'x');
+ if (sep == NULL)
+ continue;
+
+ hex2u64(sep + 1, &start);
+
+ sep = strchr(line, ' ');
+ if (sep == NULL)
+ continue;
+
+ *sep = '\0';
+
+ snprintf(name, sizeof(name), "[%s]", line);
+ dso = dso__new(name);
+
+ if (dso == NULL)
+ goto out_delete_line;
+
+ map = map__new2(start, dso, MAP__FUNCTION);
+ if (map == NULL) {
+ dso__delete(dso);
+ goto out_delete_line;
}
- prev = pos;
+
+ snprintf(name, sizeof(name),
+ "/sys/module/%s/notes/.note.gnu.build-id", line);
+ if (sysfs__read_build_id(name, dso->build_id,
+ sizeof(dso->build_id)) == 0)
+ dso->has_build_id = true;
+
+ dso->origin = DSO__ORIG_KMODULE;
+ __thread__insert_map(self, map);
+ dsos__add(&dsos__kernel, dso);
}
+
+ free(line);
+ fclose(file);
+
+ return dsos__set_modules_path();
+
+out_delete_line:
+ free(line);
+out_failure:
+ return -1;
}
-static int dso__load_vmlinux(struct dso *self, const char *vmlinux,
- symbol_filter_t filter, int v)
+static int dso__load_vmlinux(struct dso *self, struct map *map, struct thread *thread,
+ const char *vmlinux, symbol_filter_t filter)
{
- int err, fd = open(vmlinux, O_RDONLY);
+ int err = -1, fd;
- if (fd < 0)
- return -1;
+ if (self->has_build_id) {
+ u8 build_id[BUILD_ID_SIZE];
- err = dso__load_sym(self, fd, vmlinux, filter, v, NULL);
+ if (filename__read_build_id(vmlinux, build_id,
+ sizeof(build_id)) < 0) {
+ pr_debug("No build_id in %s, ignoring it\n", vmlinux);
+ return -1;
+ }
+ if (!dso__build_id_equal(self, build_id)) {
+ char expected_build_id[BUILD_ID_SIZE * 2 + 1],
+ vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
+
+ build_id__sprintf(self->build_id,
+ sizeof(self->build_id),
+ expected_build_id);
+ build_id__sprintf(build_id, sizeof(build_id),
+ vmlinux_build_id);
+ pr_debug("build_id in %s is %s while expected is %s, "
+ "ignoring it\n", vmlinux, vmlinux_build_id,
+ expected_build_id);
+ return -1;
+ }
+ }
- if (err > 0)
- dso__fill_symbol_holes(self);
+ fd = open(vmlinux, O_RDONLY);
+ if (fd < 0)
+ return -1;
+ dso__set_loaded(self, map->type);
+ err = dso__load_sym(self, map, thread, self->long_name, fd, filter, 1, 0);
close(fd);
return err;
}
-int dso__load_kernel(struct dso *self, const char *vmlinux,
- symbol_filter_t filter, int v, int use_modules)
+static int dso__load_kernel_sym(struct dso *self, struct map *map,
+ struct thread *thread, symbol_filter_t filter)
{
- int err = -1;
-
- if (vmlinux) {
- err = dso__load_vmlinux(self, vmlinux, filter, v);
- if (err > 0 && use_modules) {
- int syms = dso__load_modules(self, filter, v);
-
- if (syms < 0) {
- fprintf(stderr, "dso__load_modules failed!\n");
- return syms;
+ int err;
+ bool is_kallsyms;
+
+ if (vmlinux_path != NULL) {
+ int i;
+ pr_debug("Looking at the vmlinux_path (%d entries long)\n",
+ vmlinux_path__nr_entries);
+ for (i = 0; i < vmlinux_path__nr_entries; ++i) {
+ err = dso__load_vmlinux(self, map, thread,
+ vmlinux_path[i], filter);
+ if (err > 0) {
+ pr_debug("Using %s for symbols\n",
+ vmlinux_path[i]);
+ dso__set_long_name(self,
+ strdup(vmlinux_path[i]));
+ goto out_fixup;
}
- err += syms;
}
}
- if (err <= 0)
- err = dso__load_kallsyms(self, filter, v);
+ is_kallsyms = self->long_name[0] == '[';
+ if (is_kallsyms)
+ goto do_kallsyms;
- if (err > 0)
- self->origin = DSO__ORIG_KERNEL;
+ err = dso__load_vmlinux(self, map, thread, self->long_name, filter);
+ if (err <= 0) {
+ pr_info("The file %s cannot be used, "
+ "trying to use /proc/kallsyms...", self->long_name);
+do_kallsyms:
+ err = dso__load_kallsyms(self, map, thread, filter);
+ if (err > 0 && !is_kallsyms)
+ dso__set_long_name(self, strdup("[kernel.kallsyms]"));
+ }
+
+ if (err > 0) {
+out_fixup:
+ map__fixup_start(map);
+ map__fixup_end(map);
+ }
return err;
}
-LIST_HEAD(dsos);
-struct dso *kernel_dso;
-struct dso *vdso;
-struct dso *hypervisor_dso;
-
-const char *vmlinux_name = "vmlinux";
-int modules;
+LIST_HEAD(dsos__user);
+LIST_HEAD(dsos__kernel);
+struct dso *vdso;
-static void dsos__add(struct dso *dso)
+static void dsos__add(struct list_head *head, struct dso *dso)
{
- list_add_tail(&dso->node, &dsos);
+ list_add_tail(&dso->node, head);
}
-static struct dso *dsos__find(const char *name)
+static struct dso *dsos__find(struct list_head *head, const char *name)
{
struct dso *pos;
- list_for_each_entry(pos, &dsos, node)
+ list_for_each_entry(pos, head, node)
if (strcmp(pos->name, name) == 0)
return pos;
return NULL;
@@ -959,79 +1459,170 @@ static struct dso *dsos__find(const char *name)
struct dso *dsos__findnew(const char *name)
{
- struct dso *dso = dsos__find(name);
- int nr;
-
- if (dso)
- return dso;
-
- dso = dso__new(name, 0);
- if (!dso)
- goto out_delete_dso;
+ struct dso *dso = dsos__find(&dsos__user, name);
- nr = dso__load(dso, NULL, verbose);
- if (nr < 0) {
- eprintf("Failed to open: %s\n", name);
- goto out_delete_dso;
+ if (!dso) {
+ dso = dso__new(name);
+ if (dso != NULL) {
+ dsos__add(&dsos__user, dso);
+ dso__set_basename(dso);
+ }
}
- if (!nr)
- eprintf("No symbols found in: %s, maybe install a debug package?\n", name);
-
- dsos__add(dso);
return dso;
+}
-out_delete_dso:
- dso__delete(dso);
- return NULL;
+static void __dsos__fprintf(struct list_head *head, FILE *fp)
+{
+ struct dso *pos;
+
+ list_for_each_entry(pos, head, node) {
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ dso__fprintf(pos, i, fp);
+ }
}
void dsos__fprintf(FILE *fp)
{
+ __dsos__fprintf(&dsos__kernel, fp);
+ __dsos__fprintf(&dsos__user, fp);
+}
+
+static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp)
+{
struct dso *pos;
+ size_t ret = 0;
- list_for_each_entry(pos, &dsos, node)
- dso__fprintf(pos, fp);
+ list_for_each_entry(pos, head, node) {
+ ret += dso__fprintf_buildid(pos, fp);
+ ret += fprintf(fp, " %s\n", pos->long_name);
+ }
+ return ret;
}
-static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip)
+size_t dsos__fprintf_buildid(FILE *fp)
{
- return dso__find_symbol(dso, ip);
+ return (__dsos__fprintf_buildid(&dsos__kernel, fp) +
+ __dsos__fprintf_buildid(&dsos__user, fp));
}
-int load_kernel(void)
+static int thread__create_kernel_map(struct thread *self, const char *vmlinux)
{
- int err;
+ struct map *kmap;
+ struct dso *kernel = dso__new(vmlinux ?: "[kernel.kallsyms]");
- kernel_dso = dso__new("[kernel]", 0);
- if (!kernel_dso)
+ if (kernel == NULL)
return -1;
- err = dso__load_kernel(kernel_dso, vmlinux_name, NULL, verbose, modules);
- if (err <= 0) {
- dso__delete(kernel_dso);
- kernel_dso = NULL;
- } else
- dsos__add(kernel_dso);
+ kmap = map__new2(0, kernel, MAP__FUNCTION);
+ if (kmap == NULL)
+ goto out_delete_kernel_dso;
- vdso = dso__new("[vdso]", 0);
- if (!vdso)
- return -1;
+ kmap->map_ip = kmap->unmap_ip = identity__map_ip;
+ kernel->short_name = "[kernel]";
+ kernel->kernel = 1;
- vdso->find_symbol = vdso__find_symbol;
+ vdso = dso__new("[vdso]");
+ if (vdso == NULL)
+ goto out_delete_kernel_map;
+ dso__set_loaded(vdso, MAP__FUNCTION);
- dsos__add(vdso);
+ if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id,
+ sizeof(kernel->build_id)) == 0)
+ kernel->has_build_id = true;
- hypervisor_dso = dso__new("[hypervisor]", 0);
- if (!hypervisor_dso)
- return -1;
- dsos__add(hypervisor_dso);
+ __thread__insert_map(self, kmap);
+ dsos__add(&dsos__kernel, kernel);
+ dsos__add(&dsos__user, vdso);
- return err;
+ return 0;
+
+out_delete_kernel_map:
+ map__delete(kmap);
+out_delete_kernel_dso:
+ dso__delete(kernel);
+ return -1;
+}
+
+static void vmlinux_path__exit(void)
+{
+ while (--vmlinux_path__nr_entries >= 0) {
+ free(vmlinux_path[vmlinux_path__nr_entries]);
+ vmlinux_path[vmlinux_path__nr_entries] = NULL;
+ }
+
+ free(vmlinux_path);
+ vmlinux_path = NULL;
}
+static int vmlinux_path__init(void)
+{
+ struct utsname uts;
+ char bf[PATH_MAX];
+
+ if (uname(&uts) < 0)
+ return -1;
+
+ vmlinux_path = malloc(sizeof(char *) * 5);
+ if (vmlinux_path == NULL)
+ return -1;
+
+ vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
+ if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+ goto out_fail;
+ ++vmlinux_path__nr_entries;
+ vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
+ if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+ goto out_fail;
+ ++vmlinux_path__nr_entries;
+ snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
+ vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
+ if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+ goto out_fail;
+ ++vmlinux_path__nr_entries;
+ snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
+ vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
+ if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+ goto out_fail;
+ ++vmlinux_path__nr_entries;
+ snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
+ uts.release);
+ vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
+ if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+ goto out_fail;
+ ++vmlinux_path__nr_entries;
+
+ return 0;
+
+out_fail:
+ vmlinux_path__exit();
+ return -1;
+}
-void symbol__init(void)
+int symbol__init(struct symbol_conf *conf)
{
+ const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
+
elf_version(EV_CURRENT);
+ symbol__priv_size = pconf->priv_size;
+ thread__init(kthread, 0);
+
+ if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
+ return -1;
+
+ if (thread__create_kernel_map(kthread, pconf->vmlinux_name) < 0) {
+ vmlinux_path__exit();
+ return -1;
+ }
+
+ kthread->use_modules = pconf->use_modules;
+ if (pconf->use_modules && thread__create_module_maps(kthread) < 0)
+ pr_debug("Failed to load list of modules in use, "
+ "continuing...\n");
+ /*
+ * Now that we have all the maps created, just set the ->end of them:
+ */
+ thread__fixup_maps_end(kthread);
+ return 0;
}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6e8490716408..17003efa0b39 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -1,11 +1,11 @@
-#ifndef _PERF_SYMBOL_
-#define _PERF_SYMBOL_ 1
+#ifndef __PERF_SYMBOL
+#define __PERF_SYMBOL 1
#include <linux/types.h>
+#include <stdbool.h>
#include "types.h"
#include <linux/list.h>
#include <linux/rbtree.h>
-#include "module.h"
#include "event.h"
#ifdef HAVE_CPLUS_DEMANGLE
@@ -27,6 +27,16 @@ static inline char *bfd_demangle(void __used *v, const char __used *c,
#endif
#endif
+/*
+ * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
+ * for newer versions we can use mmap to reduce memory usage:
+ */
+#ifdef LIBELF_NO_MMAP
+# define PERF_ELF_C_READ_MMAP ELF_C_READ
+#else
+# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
+#endif
+
#ifndef DMGL_PARAMS
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
@@ -36,57 +46,75 @@ struct symbol {
struct rb_node rb_node;
u64 start;
u64 end;
- u64 obj_start;
- u64 hist_sum;
- u64 *hist;
- struct module *module;
- void *priv;
char name[0];
};
+struct symbol_conf {
+ unsigned short priv_size;
+ bool try_vmlinux_path,
+ use_modules;
+ const char *vmlinux_name;
+};
+
+extern unsigned int symbol__priv_size;
+
+static inline void *symbol__priv(struct symbol *self)
+{
+ return ((void *)self) - symbol__priv_size;
+}
+
+struct addr_location {
+ struct thread *thread;
+ struct map *map;
+ struct symbol *sym;
+ u64 addr;
+ char level;
+};
+
struct dso {
struct list_head node;
- struct rb_root syms;
- struct symbol *(*find_symbol)(struct dso *, u64 ip);
- unsigned int sym_priv_size;
- unsigned char adjust_symbols;
- unsigned char slen_calculated;
+ struct rb_root symbols[MAP__NR_TYPES];
+ struct symbol *(*find_symbol)(struct dso *self,
+ enum map_type type, u64 addr);
+ u8 adjust_symbols:1;
+ u8 slen_calculated:1;
+ u8 has_build_id:1;
+ u8 kernel:1;
unsigned char origin;
+ u8 loaded;
+ u8 build_id[BUILD_ID_SIZE];
+ u16 long_name_len;
+ const char *short_name;
+ char *long_name;
char name[0];
};
-extern const char *sym_hist_filter;
-
-typedef int (*symbol_filter_t)(struct dso *self, struct symbol *sym);
-
-struct dso *dso__new(const char *name, unsigned int sym_priv_size);
+struct dso *dso__new(const char *name);
void dso__delete(struct dso *self);
-static inline void *dso__sym_priv(struct dso *self, struct symbol *sym)
-{
- return ((void *)sym) - self->sym_priv_size;
-}
+bool dso__loaded(const struct dso *self, enum map_type type);
-struct symbol *dso__find_symbol(struct dso *self, u64 ip);
-
-int dso__load_kernel(struct dso *self, const char *vmlinux,
- symbol_filter_t filter, int verbose, int modules);
-int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose);
-int dso__load(struct dso *self, symbol_filter_t filter, int verbose);
struct dso *dsos__findnew(const char *name);
+int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
void dsos__fprintf(FILE *fp);
+size_t dsos__fprintf_buildid(FILE *fp);
-size_t dso__fprintf(struct dso *self, FILE *fp);
+size_t dso__fprintf_buildid(struct dso *self, FILE *fp);
+size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp);
char dso__symtab_origin(const struct dso *self);
+void dso__set_build_id(struct dso *self, void *build_id);
+
+int filename__read_build_id(const char *filename, void *bf, size_t size);
+int sysfs__read_build_id(const char *filename, void *bf, size_t size);
+bool dsos__read_build_ids(void);
+int build_id__sprintf(u8 *self, int len, char *bf);
-int load_kernel(void);
+size_t kernel_maps__fprintf(FILE *fp);
-void symbol__init(void);
+int symbol__init(struct symbol_conf *conf);
-extern struct list_head dsos;
-extern struct dso *kernel_dso;
+struct thread;
+struct thread *kthread;
+extern struct list_head dsos__user, dsos__kernel;
extern struct dso *vdso;
-extern struct dso *hypervisor_dso;
-extern const char *vmlinux_name;
-extern int modules;
-#endif /* _PERF_SYMBOL_ */
+#endif /* __PERF_SYMBOL */
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 45efb5db0d19..603f5610861b 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -6,16 +6,29 @@
#include "util.h"
#include "debug.h"
+static struct rb_root threads;
+static struct thread *last_match;
+
+void thread__init(struct thread *self, pid_t pid)
+{
+ int i;
+ self->pid = pid;
+ self->comm = NULL;
+ for (i = 0; i < MAP__NR_TYPES; ++i) {
+ self->maps[i] = RB_ROOT;
+ INIT_LIST_HEAD(&self->removed_maps[i]);
+ }
+}
+
static struct thread *thread__new(pid_t pid)
{
- struct thread *self = calloc(1, sizeof(*self));
+ struct thread *self = zalloc(sizeof(*self));
if (self != NULL) {
- self->pid = pid;
+ thread__init(self, pid);
self->comm = malloc(32);
if (self->comm)
snprintf(self->comm, 32, ":%d", self->pid);
- INIT_LIST_HEAD(&self->maps);
}
return self;
@@ -29,21 +42,84 @@ int thread__set_comm(struct thread *self, const char *comm)
return self->comm ? 0 : -ENOMEM;
}
-static size_t thread__fprintf(struct thread *self, FILE *fp)
+int thread__comm_len(struct thread *self)
+{
+ if (!self->comm_len) {
+ if (!self->comm)
+ return 0;
+ self->comm_len = strlen(self->comm);
+ }
+
+ return self->comm_len;
+}
+
+static const char *map_type__name[MAP__NR_TYPES] = {
+ [MAP__FUNCTION] = "Functions",
+};
+
+static size_t __thread__fprintf_maps(struct thread *self,
+ enum map_type type, FILE *fp)
+{
+ size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
+ struct rb_node *nd;
+
+ for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
+ struct map *pos = rb_entry(nd, struct map, rb_node);
+ printed += fprintf(fp, "Map:");
+ printed += map__fprintf(pos, fp);
+ if (verbose > 1) {
+ printed += dso__fprintf(pos->dso, type, fp);
+ printed += fprintf(fp, "--\n");
+ }
+ }
+
+ return printed;
+}
+
+size_t thread__fprintf_maps(struct thread *self, FILE *fp)
+{
+ size_t printed = 0, i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ printed += __thread__fprintf_maps(self, i, fp);
+ return printed;
+}
+
+static size_t __thread__fprintf_removed_maps(struct thread *self,
+ enum map_type type, FILE *fp)
{
struct map *pos;
- size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
+ size_t printed = 0;
+
+ list_for_each_entry(pos, &self->removed_maps[type], node) {
+ printed += fprintf(fp, "Map:");
+ printed += map__fprintf(pos, fp);
+ if (verbose > 1) {
+ printed += dso__fprintf(pos->dso, type, fp);
+ printed += fprintf(fp, "--\n");
+ }
+ }
+ return printed;
+}
- list_for_each_entry(pos, &self->maps, node)
- ret += map__fprintf(pos, fp);
+static size_t thread__fprintf_removed_maps(struct thread *self, FILE *fp)
+{
+ size_t printed = 0, i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ printed += __thread__fprintf_removed_maps(self, i, fp);
+ return printed;
+}
- return ret;
+static size_t thread__fprintf(struct thread *self, FILE *fp)
+{
+ size_t printed = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
+ printed += thread__fprintf_removed_maps(self, fp);
+ printed += fprintf(fp, "Removed maps:\n");
+ return printed + thread__fprintf_removed_maps(self, fp);
}
-struct thread *
-threads__findnew(pid_t pid, struct rb_root *threads, struct thread **last_match)
+struct thread *threads__findnew(pid_t pid)
{
- struct rb_node **p = &threads->rb_node;
+ struct rb_node **p = &threads.rb_node;
struct rb_node *parent = NULL;
struct thread *th;
@@ -52,15 +128,15 @@ threads__findnew(pid_t pid, struct rb_root *threads, struct thread **last_match)
* so most of the time we dont have to look up
* the full rbtree:
*/
- if (*last_match && (*last_match)->pid == pid)
- return *last_match;
+ if (last_match && last_match->pid == pid)
+ return last_match;
while (*p != NULL) {
parent = *p;
th = rb_entry(parent, struct thread, rb_node);
if (th->pid == pid) {
- *last_match = th;
+ last_match = th;
return th;
}
@@ -73,17 +149,16 @@ threads__findnew(pid_t pid, struct rb_root *threads, struct thread **last_match)
th = thread__new(pid);
if (th != NULL) {
rb_link_node(&th->rb_node, parent, p);
- rb_insert_color(&th->rb_node, threads);
- *last_match = th;
+ rb_insert_color(&th->rb_node, &threads);
+ last_match = th;
}
return th;
}
-struct thread *
-register_idle_thread(struct rb_root *threads, struct thread **last_match)
+struct thread *register_idle_thread(void)
{
- struct thread *thread = threads__findnew(0, threads, last_match);
+ struct thread *thread = threads__findnew(0);
if (!thread || thread__set_comm(thread, "swapper")) {
fprintf(stderr, "problem inserting idle task.\n");
@@ -93,79 +168,116 @@ register_idle_thread(struct rb_root *threads, struct thread **last_match)
return thread;
}
-void thread__insert_map(struct thread *self, struct map *map)
+static void thread__remove_overlappings(struct thread *self, struct map *map)
{
- struct map *pos, *tmp;
+ struct rb_root *root = &self->maps[map->type];
+ struct rb_node *next = rb_first(root);
- list_for_each_entry_safe(pos, tmp, &self->maps, node) {
- if (map__overlap(pos, map)) {
- if (verbose >= 2) {
- printf("overlapping maps:\n");
- map__fprintf(map, stdout);
- map__fprintf(pos, stdout);
- }
+ while (next) {
+ struct map *pos = rb_entry(next, struct map, rb_node);
+ next = rb_next(&pos->rb_node);
- if (map->start <= pos->start && map->end > pos->start)
- pos->start = map->end;
+ if (!map__overlap(pos, map))
+ continue;
- if (map->end >= pos->end && map->start < pos->end)
- pos->end = map->start;
+ if (verbose >= 2) {
+ fputs("overlapping maps:\n", stderr);
+ map__fprintf(map, stderr);
+ map__fprintf(pos, stderr);
+ }
- if (verbose >= 2) {
- printf("after collision:\n");
- map__fprintf(pos, stdout);
- }
+ rb_erase(&pos->rb_node, root);
+ /*
+ * We may have references to this map, for instance in some
+ * hist_entry instances, so just move them to a separate
+ * list.
+ */
+ list_add_tail(&pos->node, &self->removed_maps[map->type]);
+ }
+}
- if (pos->start >= pos->end) {
- list_del_init(&pos->node);
- free(pos);
- }
- }
+void maps__insert(struct rb_root *maps, struct map *map)
+{
+ struct rb_node **p = &maps->rb_node;
+ struct rb_node *parent = NULL;
+ const u64 ip = map->start;
+ struct map *m;
+
+ while (*p != NULL) {
+ parent = *p;
+ m = rb_entry(parent, struct map, rb_node);
+ if (ip < m->start)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
}
- list_add_tail(&map->node, &self->maps);
+ rb_link_node(&map->rb_node, parent, p);
+ rb_insert_color(&map->rb_node, maps);
}
-int thread__fork(struct thread *self, struct thread *parent)
+struct map *maps__find(struct rb_root *maps, u64 ip)
{
- struct map *map;
+ struct rb_node **p = &maps->rb_node;
+ struct rb_node *parent = NULL;
+ struct map *m;
- if (self->comm)
- free(self->comm);
- self->comm = strdup(parent->comm);
- if (!self->comm)
- return -ENOMEM;
+ while (*p != NULL) {
+ parent = *p;
+ m = rb_entry(parent, struct map, rb_node);
+ if (ip < m->start)
+ p = &(*p)->rb_left;
+ else if (ip > m->end)
+ p = &(*p)->rb_right;
+ else
+ return m;
+ }
+
+ return NULL;
+}
+
+void thread__insert_map(struct thread *self, struct map *map)
+{
+ thread__remove_overlappings(self, map);
+ maps__insert(&self->maps[map->type], map);
+}
- list_for_each_entry(map, &parent->maps, node) {
+static int thread__clone_maps(struct thread *self, struct thread *parent,
+ enum map_type type)
+{
+ struct rb_node *nd;
+ for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
+ struct map *map = rb_entry(nd, struct map, rb_node);
struct map *new = map__clone(map);
- if (!new)
+ if (new == NULL)
return -ENOMEM;
thread__insert_map(self, new);
}
-
return 0;
}
-struct map *thread__find_map(struct thread *self, u64 ip)
+int thread__fork(struct thread *self, struct thread *parent)
{
- struct map *pos;
+ int i;
- if (self == NULL)
- return NULL;
-
- list_for_each_entry(pos, &self->maps, node)
- if (ip >= pos->start && ip <= pos->end)
- return pos;
+ if (self->comm)
+ free(self->comm);
+ self->comm = strdup(parent->comm);
+ if (!self->comm)
+ return -ENOMEM;
- return NULL;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ if (thread__clone_maps(self, parent, i) < 0)
+ return -ENOMEM;
+ return 0;
}
-size_t threads__fprintf(FILE *fp, struct rb_root *threads)
+size_t threads__fprintf(FILE *fp)
{
size_t ret = 0;
struct rb_node *nd;
- for (nd = rb_first(threads); nd; nd = rb_next(nd)) {
+ for (nd = rb_first(&threads); nd; nd = rb_next(nd)) {
struct thread *pos = rb_entry(nd, struct thread, rb_node);
ret += thread__fprintf(pos, fp);
@@ -173,3 +285,15 @@ size_t threads__fprintf(FILE *fp, struct rb_root *threads)
return ret;
}
+
+struct symbol *thread__find_symbol(struct thread *self,
+ enum map_type type, u64 addr,
+ symbol_filter_t filter)
+{
+ struct map *map = thread__find_map(self, type, addr);
+
+ if (map != NULL)
+ return map__find_symbol(map, map->map_ip(map, addr), filter);
+
+ return NULL;
+}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 32aea3c1c2ad..686d6e914d9e 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -1,22 +1,56 @@
+#ifndef __PERF_THREAD_H
+#define __PERF_THREAD_H
+
#include <linux/rbtree.h>
-#include <linux/list.h>
#include <unistd.h>
#include "symbol.h"
struct thread {
struct rb_node rb_node;
- struct list_head maps;
+ struct rb_root maps[MAP__NR_TYPES];
+ struct list_head removed_maps[MAP__NR_TYPES];
pid_t pid;
+ bool use_modules;
char shortname[3];
char *comm;
+ int comm_len;
};
+void thread__init(struct thread *self, pid_t pid);
int thread__set_comm(struct thread *self, const char *comm);
-struct thread *
-threads__findnew(pid_t pid, struct rb_root *threads, struct thread **last_match);
-struct thread *
-register_idle_thread(struct rb_root *threads, struct thread **last_match);
+int thread__comm_len(struct thread *self);
+struct thread *threads__findnew(pid_t pid);
+struct thread *register_idle_thread(void);
void thread__insert_map(struct thread *self, struct map *map);
int thread__fork(struct thread *self, struct thread *parent);
-struct map *thread__find_map(struct thread *self, u64 ip);
-size_t threads__fprintf(FILE *fp, struct rb_root *threads);
+size_t thread__fprintf_maps(struct thread *self, FILE *fp);
+size_t threads__fprintf(FILE *fp);
+
+void maps__insert(struct rb_root *maps, struct map *map);
+struct map *maps__find(struct rb_root *maps, u64 addr);
+
+static inline struct map *thread__find_map(struct thread *self,
+ enum map_type type, u64 addr)
+{
+ return self ? maps__find(&self->maps[type], addr) : NULL;
+}
+
+static inline void __thread__insert_map(struct thread *self, struct map *map)
+{
+ maps__insert(&self->maps[map->type], map);
+}
+
+void thread__find_addr_location(struct thread *self, u8 cpumode,
+ enum map_type type, u64 addr,
+ struct addr_location *al,
+ symbol_filter_t filter);
+struct symbol *thread__find_symbol(struct thread *self,
+ enum map_type type, u64 addr,
+ symbol_filter_t filter);
+
+static inline struct symbol *
+thread__find_function(struct thread *self, u64 addr, symbol_filter_t filter)
+{
+ return thread__find_symbol(self, MAP__FUNCTION, addr, filter);
+}
+#endif /* __PERF_THREAD_H */
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index af4b0573b37f..cace35595530 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -33,11 +33,11 @@
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
+#include <linux/kernel.h>
#include "../perf.h"
#include "trace-event.h"
-
#define VERSION "0.5"
#define _STR(x) #x
@@ -483,27 +483,33 @@ static struct tracepoint_path *
get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events)
{
struct tracepoint_path path, *ppath = &path;
- int i;
+ int i, nr_tracepoints = 0;
for (i = 0; i < nb_events; i++) {
if (pattrs[i].type != PERF_TYPE_TRACEPOINT)
continue;
+ ++nr_tracepoints;
ppath->next = tracepoint_id_to_path(pattrs[i].config);
if (!ppath->next)
die("%s\n", "No memory to alloc tracepoints list");
ppath = ppath->next;
}
- return path.next;
+ return nr_tracepoints > 0 ? path.next : NULL;
}
-void read_tracing_data(struct perf_event_attr *pattrs, int nb_events)
+
+int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events)
{
char buf[BUFSIZ];
- struct tracepoint_path *tps;
+ struct tracepoint_path *tps = get_tracepoints_path(pattrs, nb_events);
+
+ /*
+ * What? No tracepoints? No sense writing anything here, bail out.
+ */
+ if (tps == NULL)
+ return -1;
- output_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);
- if (output_fd < 0)
- die("creating file '%s'", output_file);
+ output_fd = fd;
buf[0] = 23;
buf[1] = 8;
@@ -530,11 +536,11 @@ void read_tracing_data(struct perf_event_attr *pattrs, int nb_events)
page_size = getpagesize();
write_or_die(&page_size, 4);
- tps = get_tracepoints_path(pattrs, nb_events);
-
read_header_files();
read_ftrace_files(tps);
read_event_files(tps);
read_proc_kallsyms();
read_ftrace_printk();
+
+ return 0;
}
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 55b41b9e3834..0302405aa2ca 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -40,12 +40,19 @@ int header_page_size_size;
int header_page_data_offset;
int header_page_data_size;
+int latency_format;
+
static char *input_buf;
static unsigned long long input_buf_ptr;
static unsigned long long input_buf_siz;
static int cpus;
static int long_size;
+static int is_flag_field;
+static int is_symbolic_field;
+
+static struct format_field *
+find_any_field(struct event *event, const char *name);
static void init_input_buf(char *buf, unsigned long long size)
{
@@ -284,18 +291,19 @@ void parse_ftrace_printk(char *file, unsigned int size __unused)
char *line;
char *next = NULL;
char *addr_str;
- int ret;
int i;
line = strtok_r(file, "\n", &next);
while (line) {
+ addr_str = strsep(&line, ":");
+ if (!line) {
+ warning("error parsing print strings");
+ break;
+ }
item = malloc_or_die(sizeof(*item));
- ret = sscanf(line, "%as : %as",
- (float *)(void *)&addr_str, /* workaround gcc warning */
- (float *)(void *)&item->printk);
item->addr = strtoull(addr_str, NULL, 16);
- free(addr_str);
-
+ /* fmt still has a space, skip it */
+ item->printk = strdup(line+1);
item->next = list;
list = item;
line = strtok_r(NULL, "\n", &next);
@@ -522,7 +530,10 @@ static enum event_type __read_token(char **tok)
last_ch = ch;
ch = __read_char();
buf[i++] = ch;
- } while (ch != quote_ch && last_ch != '\\');
+ /* the '\' '\' will cancel itself */
+ if (ch == '\\' && last_ch == '\\')
+ last_ch = 0;
+ } while (ch != quote_ch || last_ch == '\\');
/* remove the last quote */
i--;
goto out;
@@ -610,7 +621,7 @@ static enum event_type read_token_item(char **tok)
static int test_type(enum event_type type, enum event_type expect)
{
if (type != expect) {
- die("Error: expected type %d but read %d",
+ warning("Error: expected type %d but read %d",
expect, type);
return -1;
}
@@ -618,16 +629,16 @@ static int test_type(enum event_type type, enum event_type expect)
}
static int test_type_token(enum event_type type, char *token,
- enum event_type expect, char *expect_tok)
+ enum event_type expect, const char *expect_tok)
{
if (type != expect) {
- die("Error: expected type %d but read %d",
+ warning("Error: expected type %d but read %d",
expect, type);
return -1;
}
if (strcmp(token, expect_tok) != 0) {
- die("Error: expected '%s' but read '%s'",
+ warning("Error: expected '%s' but read '%s'",
expect_tok, token);
return -1;
}
@@ -650,7 +661,7 @@ static int read_expect_type(enum event_type expect, char **tok)
return __read_expect_type(expect, tok, 1);
}
-static int __read_expected(enum event_type expect, char *str, int newline_ok)
+static int __read_expected(enum event_type expect, const char *str, int newline_ok)
{
enum event_type type;
char *token;
@@ -665,15 +676,15 @@ static int __read_expected(enum event_type expect, char *str, int newline_ok)
free_token(token);
- return 0;
+ return ret;
}
-static int read_expected(enum event_type expect, char *str)
+static int read_expected(enum event_type expect, const char *str)
{
return __read_expected(expect, str, 1);
}
-static int read_expected_item(enum event_type expect, char *str)
+static int read_expected_item(enum event_type expect, const char *str)
{
return __read_expected(expect, str, 0);
}
@@ -682,10 +693,10 @@ static char *event_read_name(void)
{
char *token;
- if (read_expected(EVENT_ITEM, (char *)"name") < 0)
+ if (read_expected(EVENT_ITEM, "name") < 0)
return NULL;
- if (read_expected(EVENT_OP, (char *)":") < 0)
+ if (read_expected(EVENT_OP, ":") < 0)
return NULL;
if (read_expect_type(EVENT_ITEM, &token) < 0)
@@ -703,10 +714,10 @@ static int event_read_id(void)
char *token;
int id;
- if (read_expected_item(EVENT_ITEM, (char *)"ID") < 0)
+ if (read_expected_item(EVENT_ITEM, "ID") < 0)
return -1;
- if (read_expected(EVENT_OP, (char *)":") < 0)
+ if (read_expected(EVENT_OP, ":") < 0)
return -1;
if (read_expect_type(EVENT_ITEM, &token) < 0)
@@ -721,6 +732,24 @@ static int event_read_id(void)
return -1;
}
+static int field_is_string(struct format_field *field)
+{
+ if ((field->flags & FIELD_IS_ARRAY) &&
+ (!strstr(field->type, "char") || !strstr(field->type, "u8") ||
+ !strstr(field->type, "s8")))
+ return 1;
+
+ return 0;
+}
+
+static int field_is_dynamic(struct format_field *field)
+{
+ if (!strcmp(field->type, "__data_loc"))
+ return 1;
+
+ return 0;
+}
+
static int event_read_fields(struct event *event, struct format_field **fields)
{
struct format_field *field = NULL;
@@ -738,7 +767,7 @@ static int event_read_fields(struct event *event, struct format_field **fields)
count++;
- if (test_type_token(type, token, EVENT_ITEM, (char *)"field"))
+ if (test_type_token(type, token, EVENT_ITEM, "field"))
goto fail;
free_token(token);
@@ -753,7 +782,7 @@ static int event_read_fields(struct event *event, struct format_field **fields)
type = read_token(&token);
}
- if (test_type_token(type, token, EVENT_OP, (char *)":") < 0)
+ if (test_type_token(type, token, EVENT_OP, ":") < 0)
return -1;
if (read_expect_type(EVENT_ITEM, &token) < 0)
@@ -865,14 +894,20 @@ static int event_read_fields(struct event *event, struct format_field **fields)
free(brackets);
}
- if (test_type_token(type, token, EVENT_OP, (char *)";"))
+ if (field_is_string(field)) {
+ field->flags |= FIELD_IS_STRING;
+ if (field_is_dynamic(field))
+ field->flags |= FIELD_IS_DYNAMIC;
+ }
+
+ if (test_type_token(type, token, EVENT_OP, ";"))
goto fail;
free_token(token);
- if (read_expected(EVENT_ITEM, (char *)"offset") < 0)
+ if (read_expected(EVENT_ITEM, "offset") < 0)
goto fail_expect;
- if (read_expected(EVENT_OP, (char *)":") < 0)
+ if (read_expected(EVENT_OP, ":") < 0)
goto fail_expect;
if (read_expect_type(EVENT_ITEM, &token))
@@ -880,13 +915,13 @@ static int event_read_fields(struct event *event, struct format_field **fields)
field->offset = strtoul(token, NULL, 0);
free_token(token);
- if (read_expected(EVENT_OP, (char *)";") < 0)
+ if (read_expected(EVENT_OP, ";") < 0)
goto fail_expect;
- if (read_expected(EVENT_ITEM, (char *)"size") < 0)
+ if (read_expected(EVENT_ITEM, "size") < 0)
goto fail_expect;
- if (read_expected(EVENT_OP, (char *)":") < 0)
+ if (read_expected(EVENT_OP, ":") < 0)
goto fail_expect;
if (read_expect_type(EVENT_ITEM, &token))
@@ -894,11 +929,34 @@ static int event_read_fields(struct event *event, struct format_field **fields)
field->size = strtoul(token, NULL, 0);
free_token(token);
- if (read_expected(EVENT_OP, (char *)";") < 0)
+ if (read_expected(EVENT_OP, ";") < 0)
goto fail_expect;
- if (read_expect_type(EVENT_NEWLINE, &token) < 0)
- goto fail;
+ type = read_token(&token);
+ if (type != EVENT_NEWLINE) {
+ /* newer versions of the kernel have a "signed" type */
+ if (test_type_token(type, token, EVENT_ITEM, "signed"))
+ goto fail;
+
+ free_token(token);
+
+ if (read_expected(EVENT_OP, ":") < 0)
+ goto fail_expect;
+
+ if (read_expect_type(EVENT_ITEM, &token))
+ goto fail;
+
+ if (strtoul(token, NULL, 0))
+ field->flags |= FIELD_IS_SIGNED;
+
+ free_token(token);
+ if (read_expected(EVENT_OP, ";") < 0)
+ goto fail_expect;
+
+ if (read_expect_type(EVENT_NEWLINE, &token))
+ goto fail;
+ }
+
free_token(token);
*fields = field;
@@ -921,10 +979,10 @@ static int event_read_format(struct event *event)
char *token;
int ret;
- if (read_expected_item(EVENT_ITEM, (char *)"format") < 0)
+ if (read_expected_item(EVENT_ITEM, "format") < 0)
return -1;
- if (read_expected(EVENT_OP, (char *)":") < 0)
+ if (read_expected(EVENT_OP, ":") < 0)
return -1;
if (read_expect_type(EVENT_NEWLINE, &token))
@@ -984,7 +1042,7 @@ process_cond(struct event *event, struct print_arg *top, char **tok)
*tok = NULL;
type = process_arg(event, left, &token);
- if (test_type_token(type, token, EVENT_OP, (char *)":"))
+ if (test_type_token(type, token, EVENT_OP, ":"))
goto out_free;
arg->op.op = token;
@@ -1004,6 +1062,35 @@ out_free:
return EVENT_ERROR;
}
+static enum event_type
+process_array(struct event *event, struct print_arg *top, char **tok)
+{
+ struct print_arg *arg;
+ enum event_type type;
+ char *token = NULL;
+
+ arg = malloc_or_die(sizeof(*arg));
+ memset(arg, 0, sizeof(*arg));
+
+ *tok = NULL;
+ type = process_arg(event, arg, &token);
+ if (test_type_token(type, token, EVENT_OP, "]"))
+ goto out_free;
+
+ top->op.right = arg;
+
+ free_token(token);
+ type = read_token_item(&token);
+ *tok = token;
+
+ return type;
+
+out_free:
+ free_token(*tok);
+ free_arg(arg);
+ return EVENT_ERROR;
+}
+
static int get_op_prio(char *op)
{
if (!op[1]) {
@@ -1128,6 +1215,8 @@ process_op(struct event *event, struct print_arg *arg, char **tok)
strcmp(token, "*") == 0 ||
strcmp(token, "^") == 0 ||
strcmp(token, "/") == 0 ||
+ strcmp(token, "<") == 0 ||
+ strcmp(token, ">") == 0 ||
strcmp(token, "==") == 0 ||
strcmp(token, "!=") == 0) {
@@ -1144,17 +1233,46 @@ process_op(struct event *event, struct print_arg *arg, char **tok)
right = malloc_or_die(sizeof(*right));
- type = process_arg(event, right, tok);
+ type = read_token_item(&token);
+ *tok = token;
+
+ /* could just be a type pointer */
+ if ((strcmp(arg->op.op, "*") == 0) &&
+ type == EVENT_DELIM && (strcmp(token, ")") == 0)) {
+ if (left->type != PRINT_ATOM)
+ die("bad pointer type");
+ left->atom.atom = realloc(left->atom.atom,
+ sizeof(left->atom.atom) + 3);
+ strcat(left->atom.atom, " *");
+ *arg = *left;
+ free(arg);
+
+ return type;
+ }
+
+ type = process_arg_token(event, right, tok, type);
arg->op.right = right;
+ } else if (strcmp(token, "[") == 0) {
+
+ left = malloc_or_die(sizeof(*left));
+ *left = *arg;
+
+ arg->type = PRINT_OP;
+ arg->op.op = token;
+ arg->op.left = left;
+
+ arg->op.prio = 0;
+ type = process_array(event, arg, tok);
+
} else {
- die("unknown op '%s'", token);
+ warning("unknown op '%s'", token);
+ event->flags |= EVENT_FL_FAILED;
/* the arg is now the left side */
return EVENT_NONE;
}
-
if (type == EVENT_OP) {
int prio;
@@ -1178,7 +1296,7 @@ process_entry(struct event *event __unused, struct print_arg *arg,
char *field;
char *token;
- if (read_expected(EVENT_OP, (char *)"->") < 0)
+ if (read_expected(EVENT_OP, "->") < 0)
return EVENT_ERROR;
if (read_expect_type(EVENT_ITEM, &token) < 0)
@@ -1188,6 +1306,16 @@ process_entry(struct event *event __unused, struct print_arg *arg,
arg->type = PRINT_FIELD;
arg->field.name = field;
+ if (is_flag_field) {
+ arg->field.field = find_any_field(event, arg->field.name);
+ arg->field.field->flags |= FIELD_IS_FLAG;
+ is_flag_field = 0;
+ } else if (is_symbolic_field) {
+ arg->field.field = find_any_field(event, arg->field.name);
+ arg->field.field->flags |= FIELD_IS_SYMBOLIC;
+ is_symbolic_field = 0;
+ }
+
type = read_token(&token);
*tok = token;
@@ -1338,14 +1466,14 @@ process_fields(struct event *event, struct print_flag_sym **list, char **tok)
do {
free_token(token);
type = read_token_item(&token);
- if (test_type_token(type, token, EVENT_OP, (char *)"{"))
+ if (test_type_token(type, token, EVENT_OP, "{"))
break;
arg = malloc_or_die(sizeof(*arg));
free_token(token);
type = process_arg(event, arg, &token);
- if (test_type_token(type, token, EVENT_DELIM, (char *)","))
+ if (test_type_token(type, token, EVENT_DELIM, ","))
goto out_free;
field = malloc_or_die(sizeof(*field));
@@ -1356,7 +1484,7 @@ process_fields(struct event *event, struct print_flag_sym **list, char **tok)
free_token(token);
type = process_arg(event, arg, &token);
- if (test_type_token(type, token, EVENT_OP, (char *)"}"))
+ if (test_type_token(type, token, EVENT_OP, "}"))
goto out_free;
value = arg_eval(arg);
@@ -1391,13 +1519,13 @@ process_flags(struct event *event, struct print_arg *arg, char **tok)
memset(arg, 0, sizeof(*arg));
arg->type = PRINT_FLAGS;
- if (read_expected_item(EVENT_DELIM, (char *)"(") < 0)
+ if (read_expected_item(EVENT_DELIM, "(") < 0)
return EVENT_ERROR;
field = malloc_or_die(sizeof(*field));
type = process_arg(event, field, &token);
- if (test_type_token(type, token, EVENT_DELIM, (char *)","))
+ if (test_type_token(type, token, EVENT_DELIM, ","))
goto out_free;
arg->flags.field = field;
@@ -1408,11 +1536,11 @@ process_flags(struct event *event, struct print_arg *arg, char **tok)
type = read_token_item(&token);
}
- if (test_type_token(type, token, EVENT_DELIM, (char *)","))
+ if (test_type_token(type, token, EVENT_DELIM, ","))
goto out_free;
type = process_fields(event, &arg->flags.flags, &token);
- if (test_type_token(type, token, EVENT_DELIM, (char *)")"))
+ if (test_type_token(type, token, EVENT_DELIM, ")"))
goto out_free;
free_token(token);
@@ -1434,19 +1562,19 @@ process_symbols(struct event *event, struct print_arg *arg, char **tok)
memset(arg, 0, sizeof(*arg));
arg->type = PRINT_SYMBOL;
- if (read_expected_item(EVENT_DELIM, (char *)"(") < 0)
+ if (read_expected_item(EVENT_DELIM, "(") < 0)
return EVENT_ERROR;
field = malloc_or_die(sizeof(*field));
type = process_arg(event, field, &token);
- if (test_type_token(type, token, EVENT_DELIM, (char *)","))
+ if (test_type_token(type, token, EVENT_DELIM, ","))
goto out_free;
arg->symbol.field = field;
type = process_fields(event, &arg->symbol.symbols, &token);
- if (test_type_token(type, token, EVENT_DELIM, (char *)")"))
+ if (test_type_token(type, token, EVENT_DELIM, ")"))
goto out_free;
free_token(token);
@@ -1463,7 +1591,6 @@ process_paren(struct event *event, struct print_arg *arg, char **tok)
{
struct print_arg *item_arg;
enum event_type type;
- int ptr_cast = 0;
char *token;
type = process_arg(event, arg, &token);
@@ -1471,28 +1598,13 @@ process_paren(struct event *event, struct print_arg *arg, char **tok)
if (type == EVENT_ERROR)
return EVENT_ERROR;
- if (type == EVENT_OP) {
- /* handle the ptr casts */
- if (!strcmp(token, "*")) {
- /*
- * FIXME: should we zapp whitespaces before ')' ?
- * (may require a peek_token_item())
- */
- if (__peek_char() == ')') {
- ptr_cast = 1;
- free_token(token);
- type = read_token_item(&token);
- }
- }
- if (!ptr_cast) {
- type = process_op(event, arg, &token);
+ if (type == EVENT_OP)
+ type = process_op(event, arg, &token);
- if (type == EVENT_ERROR)
- return EVENT_ERROR;
- }
- }
+ if (type == EVENT_ERROR)
+ return EVENT_ERROR;
- if (test_type_token(type, token, EVENT_DELIM, (char *)")")) {
+ if (test_type_token(type, token, EVENT_DELIM, ")")) {
free_token(token);
return EVENT_ERROR;
}
@@ -1516,13 +1628,6 @@ process_paren(struct event *event, struct print_arg *arg, char **tok)
item_arg = malloc_or_die(sizeof(*item_arg));
arg->type = PRINT_TYPE;
- if (ptr_cast) {
- char *old = arg->atom.atom;
-
- arg->atom.atom = malloc_or_die(strlen(old + 3));
- sprintf(arg->atom.atom, "%s *", old);
- free(old);
- }
arg->typecast.type = arg->atom.atom;
arg->typecast.item = item_arg;
type = process_arg_token(event, item_arg, &token, type);
@@ -1540,7 +1645,7 @@ process_str(struct event *event __unused, struct print_arg *arg, char **tok)
enum event_type type;
char *token;
- if (read_expected(EVENT_DELIM, (char *)"(") < 0)
+ if (read_expected(EVENT_DELIM, "(") < 0)
return EVENT_ERROR;
if (read_expect_type(EVENT_ITEM, &token) < 0)
@@ -1550,7 +1655,7 @@ process_str(struct event *event __unused, struct print_arg *arg, char **tok)
arg->string.string = token;
arg->string.offset = -1;
- if (read_expected(EVENT_DELIM, (char *)")") < 0)
+ if (read_expected(EVENT_DELIM, ")") < 0)
return EVENT_ERROR;
type = read_token(&token);
@@ -1578,9 +1683,11 @@ process_arg_token(struct event *event, struct print_arg *arg,
type = process_entry(event, arg, &token);
} else if (strcmp(token, "__print_flags") == 0) {
free_token(token);
+ is_flag_field = 1;
type = process_flags(event, arg, &token);
} else if (strcmp(token, "__print_symbolic") == 0) {
free_token(token);
+ is_symbolic_field = 1;
type = process_symbols(event, arg, &token);
} else if (strcmp(token, "__get_str") == 0) {
free_token(token);
@@ -1637,12 +1744,18 @@ process_arg_token(struct event *event, struct print_arg *arg,
static int event_read_print_args(struct event *event, struct print_arg **list)
{
- enum event_type type;
+ enum event_type type = EVENT_ERROR;
struct print_arg *arg;
char *token;
int args = 0;
do {
+ if (type == EVENT_NEWLINE) {
+ free_token(token);
+ type = read_token_item(&token);
+ continue;
+ }
+
arg = malloc_or_die(sizeof(*arg));
memset(arg, 0, sizeof(*arg));
@@ -1683,18 +1796,19 @@ static int event_read_print(struct event *event)
char *token;
int ret;
- if (read_expected_item(EVENT_ITEM, (char *)"print") < 0)
+ if (read_expected_item(EVENT_ITEM, "print") < 0)
return -1;
- if (read_expected(EVENT_ITEM, (char *)"fmt") < 0)
+ if (read_expected(EVENT_ITEM, "fmt") < 0)
return -1;
- if (read_expected(EVENT_OP, (char *)":") < 0)
+ if (read_expected(EVENT_OP, ":") < 0)
return -1;
if (read_expect_type(EVENT_DQUOTE, &token) < 0)
goto fail;
+ concat:
event->print_fmt.format = token;
event->print_fmt.args = NULL;
@@ -1704,7 +1818,22 @@ static int event_read_print(struct event *event)
if (type == EVENT_NONE)
return 0;
- if (test_type_token(type, token, EVENT_DELIM, (char *)","))
+ /* Handle concatination of print lines */
+ if (type == EVENT_DQUOTE) {
+ char *cat;
+
+ cat = malloc_or_die(strlen(event->print_fmt.format) +
+ strlen(token) + 1);
+ strcpy(cat, event->print_fmt.format);
+ strcat(cat, token);
+ free_token(token);
+ free_token(event->print_fmt.format);
+ event->print_fmt.format = NULL;
+ token = cat;
+ goto concat;
+ }
+
+ if (test_type_token(type, token, EVENT_DELIM, ","))
goto fail;
free_token(token);
@@ -1713,7 +1842,7 @@ static int event_read_print(struct event *event)
if (ret < 0)
return -1;
- return 0;
+ return ret;
fail:
free_token(token);
@@ -1759,7 +1888,7 @@ find_any_field(struct event *event, const char *name)
return find_field(event, name);
}
-static unsigned long long read_size(void *ptr, int size)
+unsigned long long read_size(void *ptr, int size)
{
switch (size) {
case 1:
@@ -1822,37 +1951,67 @@ static int get_common_info(const char *type, int *offset, int *size)
return 0;
}
-int trace_parse_common_type(void *data)
+static int __parse_common(void *data, int *size, int *offset,
+ const char *name)
{
- static int type_offset;
- static int type_size;
int ret;
- if (!type_size) {
- ret = get_common_info("common_type",
- &type_offset,
- &type_size);
+ if (!*size) {
+ ret = get_common_info(name, offset, size);
if (ret < 0)
return ret;
}
- return read_size(data + type_offset, type_size);
+ return read_size(data + *offset, *size);
+}
+
+int trace_parse_common_type(void *data)
+{
+ static int type_offset;
+ static int type_size;
+
+ return __parse_common(data, &type_size, &type_offset,
+ "common_type");
}
-static int parse_common_pid(void *data)
+int trace_parse_common_pid(void *data)
{
static int pid_offset;
static int pid_size;
+
+ return __parse_common(data, &pid_size, &pid_offset,
+ "common_pid");
+}
+
+int parse_common_pc(void *data)
+{
+ static int pc_offset;
+ static int pc_size;
+
+ return __parse_common(data, &pc_size, &pc_offset,
+ "common_preempt_count");
+}
+
+int parse_common_flags(void *data)
+{
+ static int flags_offset;
+ static int flags_size;
+
+ return __parse_common(data, &flags_size, &flags_offset,
+ "common_flags");
+}
+
+int parse_common_lock_depth(void *data)
+{
+ static int ld_offset;
+ static int ld_size;
int ret;
- if (!pid_size) {
- ret = get_common_info("common_pid",
- &pid_offset,
- &pid_size);
- if (ret < 0)
- return ret;
- }
+ ret = __parse_common(data, &ld_size, &ld_offset,
+ "common_lock_depth");
+ if (ret < 0)
+ return -1;
- return read_size(data + pid_offset, pid_size);
+ return ret;
}
struct event *trace_find_event(int id)
@@ -1866,11 +2025,20 @@ struct event *trace_find_event(int id)
return event;
}
+struct event *trace_find_next_event(struct event *event)
+{
+ if (!event)
+ return event_list;
+
+ return event->next;
+}
+
static unsigned long long eval_num_arg(void *data, int size,
struct event *event, struct print_arg *arg)
{
unsigned long long val = 0;
unsigned long long left, right;
+ struct print_arg *larg;
switch (arg->type) {
case PRINT_NULL:
@@ -1897,6 +2065,26 @@ static unsigned long long eval_num_arg(void *data, int size,
return 0;
break;
case PRINT_OP:
+ if (strcmp(arg->op.op, "[") == 0) {
+ /*
+ * Arrays are special, since we don't want
+ * to read the arg as is.
+ */
+ if (arg->op.left->type != PRINT_FIELD)
+ goto default_op; /* oops, all bets off */
+ larg = arg->op.left;
+ if (!larg->field.field) {
+ larg->field.field =
+ find_any_field(event, larg->field.name);
+ if (!larg->field.field)
+ die("field %s not found", larg->field.name);
+ }
+ right = eval_num_arg(data, size, event, arg->op.right);
+ val = read_size(data + larg->field.field->offset +
+ right * long_size, long_size);
+ break;
+ }
+ default_op:
left = eval_num_arg(data, size, event, arg->op.left);
right = eval_num_arg(data, size, event, arg->op.right);
switch (arg->op.op[0]) {
@@ -1947,6 +2135,12 @@ static unsigned long long eval_num_arg(void *data, int size,
die("unknown op '%s'", arg->op.op);
val = left == right;
break;
+ case '-':
+ val = left - right;
+ break;
+ case '+':
+ val = left + right;
+ break;
default:
die("unknown op '%s'", arg->op.op);
}
@@ -1978,7 +2172,7 @@ static const struct flag flags[] = {
{ "HRTIMER_RESTART", 1 },
};
-static unsigned long long eval_flag(const char *flag)
+unsigned long long eval_flag(const char *flag)
{
int i;
@@ -2145,8 +2339,9 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
case 'u':
case 'x':
case 'i':
- bptr = (void *)(((unsigned long)bptr + (long_size - 1)) &
- ~(long_size - 1));
+ /* the pointers are always 4 bytes aligned */
+ bptr = (void *)(((unsigned long)bptr + 3) &
+ ~3);
switch (ls) {
case 0:
case 1:
@@ -2270,7 +2465,27 @@ static void pretty_print(void *data, int size, struct event *event)
for (; *ptr; ptr++) {
ls = 0;
- if (*ptr == '%') {
+ if (*ptr == '\\') {
+ ptr++;
+ switch (*ptr) {
+ case 'n':
+ printf("\n");
+ break;
+ case 't':
+ printf("\t");
+ break;
+ case 'r':
+ printf("\r");
+ break;
+ case '\\':
+ printf("\\");
+ break;
+ default:
+ printf("%c", *ptr);
+ break;
+ }
+
+ } else if (*ptr == '%') {
saveptr = ptr;
show_func = 0;
cont_process:
@@ -2377,6 +2592,41 @@ static inline int log10_cpu(int nb)
return 1;
}
+static void print_lat_fmt(void *data, int size __unused)
+{
+ unsigned int lat_flags;
+ unsigned int pc;
+ int lock_depth;
+ int hardirq;
+ int softirq;
+
+ lat_flags = parse_common_flags(data);
+ pc = parse_common_pc(data);
+ lock_depth = parse_common_lock_depth(data);
+
+ hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
+ softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
+
+ printf("%c%c%c",
+ (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
+ (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
+ 'X' : '.',
+ (lat_flags & TRACE_FLAG_NEED_RESCHED) ?
+ 'N' : '.',
+ (hardirq && softirq) ? 'H' :
+ hardirq ? 'h' : softirq ? 's' : '.');
+
+ if (pc)
+ printf("%x", pc);
+ else
+ printf(".");
+
+ if (lock_depth < 0)
+ printf(".");
+ else
+ printf("%d", lock_depth);
+}
+
/* taken from Linux, written by Frederic Weisbecker */
static void print_graph_cpu(int cpu)
{
@@ -2452,7 +2702,7 @@ get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func,
if (!(event->flags & EVENT_FL_ISFUNCRET))
return NULL;
- pid = parse_common_pid(next->data);
+ pid = trace_parse_common_pid(next->data);
field = find_field(event, "func");
if (!field)
die("function return does not have field func");
@@ -2620,6 +2870,11 @@ pretty_print_func_ent(void *data, int size, struct event *event,
printf(" | ");
+ if (latency_format) {
+ print_lat_fmt(data, size);
+ printf(" | ");
+ }
+
field = find_field(event, "func");
if (!field)
die("function entry does not have func field");
@@ -2663,6 +2918,11 @@ pretty_print_func_ret(void *data, int size __unused, struct event *event,
printf(" | ");
+ if (latency_format) {
+ print_lat_fmt(data, size);
+ printf(" | ");
+ }
+
field = find_field(event, "rettime");
if (!field)
die("can't find rettime in return graph");
@@ -2724,19 +2984,30 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
event = trace_find_event(type);
if (!event) {
- printf("ug! no event found for type %d\n", type);
+ warning("ug! no event found for type %d", type);
return;
}
- pid = parse_common_pid(data);
+ pid = trace_parse_common_pid(data);
if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET))
return pretty_print_func_graph(data, size, event, cpu,
pid, comm, secs, usecs);
- printf("%16s-%-5d [%03d] %5lu.%09Lu: %s: ",
- comm, pid, cpu,
- secs, nsecs, event->name);
+ if (latency_format) {
+ printf("%8.8s-%-5d %3d",
+ comm, pid, cpu);
+ print_lat_fmt(data, size);
+ } else
+ printf("%16s-%-5d [%03d]", comm, pid, cpu);
+
+ printf(" %5lu.%06lu: %s: ", secs, usecs, event->name);
+
+ if (event->flags & EVENT_FL_FAILED) {
+ printf("EVENT '%s' FAILED TO PARSE\n",
+ event->name);
+ return;
+ }
pretty_print(data, size, event);
printf("\n");
@@ -2807,46 +3078,71 @@ static void print_args(struct print_arg *args)
}
}
-static void parse_header_field(char *type,
+static void parse_header_field(const char *field,
int *offset, int *size)
{
char *token;
+ int type;
- if (read_expected(EVENT_ITEM, (char *)"field") < 0)
+ if (read_expected(EVENT_ITEM, "field") < 0)
return;
- if (read_expected(EVENT_OP, (char *)":") < 0)
+ if (read_expected(EVENT_OP, ":") < 0)
return;
+
/* type */
if (read_expect_type(EVENT_ITEM, &token) < 0)
- return;
+ goto fail;
free_token(token);
- if (read_expected(EVENT_ITEM, type) < 0)
+ if (read_expected(EVENT_ITEM, field) < 0)
return;
- if (read_expected(EVENT_OP, (char *)";") < 0)
+ if (read_expected(EVENT_OP, ";") < 0)
return;
- if (read_expected(EVENT_ITEM, (char *)"offset") < 0)
+ if (read_expected(EVENT_ITEM, "offset") < 0)
return;
- if (read_expected(EVENT_OP, (char *)":") < 0)
+ if (read_expected(EVENT_OP, ":") < 0)
return;
if (read_expect_type(EVENT_ITEM, &token) < 0)
- return;
+ goto fail;
*offset = atoi(token);
free_token(token);
- if (read_expected(EVENT_OP, (char *)";") < 0)
+ if (read_expected(EVENT_OP, ";") < 0)
return;
- if (read_expected(EVENT_ITEM, (char *)"size") < 0)
+ if (read_expected(EVENT_ITEM, "size") < 0)
return;
- if (read_expected(EVENT_OP, (char *)":") < 0)
+ if (read_expected(EVENT_OP, ":") < 0)
return;
if (read_expect_type(EVENT_ITEM, &token) < 0)
- return;
+ goto fail;
*size = atoi(token);
free_token(token);
- if (read_expected(EVENT_OP, (char *)";") < 0)
- return;
- if (read_expect_type(EVENT_NEWLINE, &token) < 0)
+ if (read_expected(EVENT_OP, ";") < 0)
return;
+ type = read_token(&token);
+ if (type != EVENT_NEWLINE) {
+ /* newer versions of the kernel have a "signed" type */
+ if (type != EVENT_ITEM)
+ goto fail;
+
+ if (strcmp(token, "signed") != 0)
+ goto fail;
+
+ free_token(token);
+
+ if (read_expected(EVENT_OP, ":") < 0)
+ return;
+
+ if (read_expect_type(EVENT_ITEM, &token))
+ goto fail;
+
+ free_token(token);
+ if (read_expected(EVENT_OP, ";") < 0)
+ return;
+
+ if (read_expect_type(EVENT_NEWLINE, &token))
+ goto fail;
+ }
+ fail:
free_token(token);
}
@@ -2854,11 +3150,11 @@ int parse_header_page(char *buf, unsigned long size)
{
init_input_buf(buf, size);
- parse_header_field((char *)"timestamp", &header_page_ts_offset,
+ parse_header_field("timestamp", &header_page_ts_offset,
&header_page_ts_size);
- parse_header_field((char *)"commit", &header_page_size_offset,
+ parse_header_field("commit", &header_page_size_offset,
&header_page_size_size);
- parse_header_field((char *)"data", &header_page_data_offset,
+ parse_header_field("data", &header_page_data_offset,
&header_page_data_size);
return 0;
@@ -2909,6 +3205,9 @@ int parse_ftrace_file(char *buf, unsigned long size)
if (ret < 0)
die("failed to read ftrace event print fmt");
+ /* New ftrace handles args */
+ if (ret > 0)
+ return 0;
/*
* The arguments for ftrace files are parsed by the fields.
* Set up the fields as their arguments.
@@ -2926,7 +3225,7 @@ int parse_ftrace_file(char *buf, unsigned long size)
return 0;
}
-int parse_event_file(char *buf, unsigned long size, char *system__unused __unused)
+int parse_event_file(char *buf, unsigned long size, char *sys)
{
struct event *event;
int ret;
@@ -2946,12 +3245,18 @@ int parse_event_file(char *buf, unsigned long size, char *system__unused __unuse
die("failed to read event id");
ret = event_read_format(event);
- if (ret < 0)
- die("failed to read event format");
+ if (ret < 0) {
+ warning("failed to read event format for %s", event->name);
+ goto event_failed;
+ }
ret = event_read_print(event);
- if (ret < 0)
- die("failed to read event print fmt");
+ if (ret < 0) {
+ warning("failed to read event print fmt for %s", event->name);
+ goto event_failed;
+ }
+
+ event->system = strdup(sys);
#define PRINT_ARGS 0
if (PRINT_ARGS && event->print_fmt.args)
@@ -2959,6 +3264,12 @@ int parse_event_file(char *buf, unsigned long size, char *system__unused __unuse
add_event(event);
return 0;
+
+ event_failed:
+ event->flags |= EVENT_FL_FAILED;
+ /* still add it even if it failed */
+ add_event(event);
+ return -1;
}
void parse_set_info(int nr_cpus, int long_sz)
diff --git a/tools/perf/util/trace-event-perl.c b/tools/perf/util/trace-event-perl.c
new file mode 100644
index 000000000000..51e833fd58c3
--- /dev/null
+++ b/tools/perf/util/trace-event-perl.c
@@ -0,0 +1,598 @@
+/*
+ * trace-event-perl. Feed perf trace events to an embedded Perl interpreter.
+ *
+ * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "../perf.h"
+#include "util.h"
+#include "trace-event.h"
+#include "trace-event-perl.h"
+
+void xs_init(pTHX);
+
+void boot_Perf__Trace__Context(pTHX_ CV *cv);
+void boot_DynaLoader(pTHX_ CV *cv);
+
+void xs_init(pTHX)
+{
+ const char *file = __FILE__;
+ dXSUB_SYS;
+
+ newXS("Perf::Trace::Context::bootstrap", boot_Perf__Trace__Context,
+ file);
+ newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
+}
+
+INTERP my_perl;
+
+#define FTRACE_MAX_EVENT \
+ ((1 << (sizeof(unsigned short) * 8)) - 1)
+
+struct event *events[FTRACE_MAX_EVENT];
+
+static struct scripting_context *scripting_context;
+
+static char *cur_field_name;
+static int zero_flag_atom;
+
+static void define_symbolic_value(const char *ev_name,
+ const char *field_name,
+ const char *field_value,
+ const char *field_str)
+{
+ unsigned long long value;
+ dSP;
+
+ value = eval_flag(field_value);
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+
+ XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
+ XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
+ XPUSHs(sv_2mortal(newSVuv(value)));
+ XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
+
+ PUTBACK;
+ if (get_cv("main::define_symbolic_value", 0))
+ call_pv("main::define_symbolic_value", G_SCALAR);
+ SPAGAIN;
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+}
+
+static void define_symbolic_values(struct print_flag_sym *field,
+ const char *ev_name,
+ const char *field_name)
+{
+ define_symbolic_value(ev_name, field_name, field->value, field->str);
+ if (field->next)
+ define_symbolic_values(field->next, ev_name, field_name);
+}
+
+static void define_symbolic_field(const char *ev_name,
+ const char *field_name)
+{
+ dSP;
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+
+ XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
+ XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
+
+ PUTBACK;
+ if (get_cv("main::define_symbolic_field", 0))
+ call_pv("main::define_symbolic_field", G_SCALAR);
+ SPAGAIN;
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+}
+
+static void define_flag_value(const char *ev_name,
+ const char *field_name,
+ const char *field_value,
+ const char *field_str)
+{
+ unsigned long long value;
+ dSP;
+
+ value = eval_flag(field_value);
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+
+ XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
+ XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
+ XPUSHs(sv_2mortal(newSVuv(value)));
+ XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
+
+ PUTBACK;
+ if (get_cv("main::define_flag_value", 0))
+ call_pv("main::define_flag_value", G_SCALAR);
+ SPAGAIN;
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+}
+
+static void define_flag_values(struct print_flag_sym *field,
+ const char *ev_name,
+ const char *field_name)
+{
+ define_flag_value(ev_name, field_name, field->value, field->str);
+ if (field->next)
+ define_flag_values(field->next, ev_name, field_name);
+}
+
+static void define_flag_field(const char *ev_name,
+ const char *field_name,
+ const char *delim)
+{
+ dSP;
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+
+ XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
+ XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
+ XPUSHs(sv_2mortal(newSVpv(delim, 0)));
+
+ PUTBACK;
+ if (get_cv("main::define_flag_field", 0))
+ call_pv("main::define_flag_field", G_SCALAR);
+ SPAGAIN;
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+}
+
+static void define_event_symbols(struct event *event,
+ const char *ev_name,
+ struct print_arg *args)
+{
+ switch (args->type) {
+ case PRINT_NULL:
+ break;
+ case PRINT_ATOM:
+ define_flag_value(ev_name, cur_field_name, "0",
+ args->atom.atom);
+ zero_flag_atom = 0;
+ break;
+ case PRINT_FIELD:
+ if (cur_field_name)
+ free(cur_field_name);
+ cur_field_name = strdup(args->field.name);
+ break;
+ case PRINT_FLAGS:
+ define_event_symbols(event, ev_name, args->flags.field);
+ define_flag_field(ev_name, cur_field_name, args->flags.delim);
+ define_flag_values(args->flags.flags, ev_name, cur_field_name);
+ break;
+ case PRINT_SYMBOL:
+ define_event_symbols(event, ev_name, args->symbol.field);
+ define_symbolic_field(ev_name, cur_field_name);
+ define_symbolic_values(args->symbol.symbols, ev_name,
+ cur_field_name);
+ break;
+ case PRINT_STRING:
+ break;
+ case PRINT_TYPE:
+ define_event_symbols(event, ev_name, args->typecast.item);
+ break;
+ case PRINT_OP:
+ if (strcmp(args->op.op, ":") == 0)
+ zero_flag_atom = 1;
+ define_event_symbols(event, ev_name, args->op.left);
+ define_event_symbols(event, ev_name, args->op.right);
+ break;
+ default:
+ /* we should warn... */
+ return;
+ }
+
+ if (args->next)
+ define_event_symbols(event, ev_name, args->next);
+}
+
+static inline struct event *find_cache_event(int type)
+{
+ static char ev_name[256];
+ struct event *event;
+
+ if (events[type])
+ return events[type];
+
+ events[type] = event = trace_find_event(type);
+ if (!event)
+ return NULL;
+
+ sprintf(ev_name, "%s::%s", event->system, event->name);
+
+ define_event_symbols(event, ev_name, event->print_fmt.args);
+
+ return event;
+}
+
+int common_pc(struct scripting_context *context)
+{
+ int pc;
+
+ pc = parse_common_pc(context->event_data);
+
+ return pc;
+}
+
+int common_flags(struct scripting_context *context)
+{
+ int flags;
+
+ flags = parse_common_flags(context->event_data);
+
+ return flags;
+}
+
+int common_lock_depth(struct scripting_context *context)
+{
+ int lock_depth;
+
+ lock_depth = parse_common_lock_depth(context->event_data);
+
+ return lock_depth;
+}
+
+static void perl_process_event(int cpu, void *data,
+ int size __attribute((unused)),
+ unsigned long long nsecs, char *comm)
+{
+ struct format_field *field;
+ static char handler[256];
+ unsigned long long val;
+ unsigned long s, ns;
+ struct event *event;
+ int type;
+ int pid;
+
+ dSP;
+
+ type = trace_parse_common_type(data);
+
+ event = find_cache_event(type);
+ if (!event)
+ die("ug! no event found for type %d", type);
+
+ pid = trace_parse_common_pid(data);
+
+ sprintf(handler, "%s::%s", event->system, event->name);
+
+ s = nsecs / NSECS_PER_SEC;
+ ns = nsecs - s * NSECS_PER_SEC;
+
+ scripting_context->event_data = data;
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+
+ XPUSHs(sv_2mortal(newSVpv(handler, 0)));
+ XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
+ XPUSHs(sv_2mortal(newSVuv(cpu)));
+ XPUSHs(sv_2mortal(newSVuv(s)));
+ XPUSHs(sv_2mortal(newSVuv(ns)));
+ XPUSHs(sv_2mortal(newSViv(pid)));
+ XPUSHs(sv_2mortal(newSVpv(comm, 0)));
+
+ /* common fields other than pid can be accessed via xsub fns */
+
+ for (field = event->format.fields; field; field = field->next) {
+ if (field->flags & FIELD_IS_STRING) {
+ int offset;
+ if (field->flags & FIELD_IS_DYNAMIC) {
+ offset = *(int *)(data + field->offset);
+ offset &= 0xffff;
+ } else
+ offset = field->offset;
+ XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0)));
+ } else { /* FIELD_IS_NUMERIC */
+ val = read_size(data + field->offset, field->size);
+ if (field->flags & FIELD_IS_SIGNED) {
+ XPUSHs(sv_2mortal(newSViv(val)));
+ } else {
+ XPUSHs(sv_2mortal(newSVuv(val)));
+ }
+ }
+ }
+
+ PUTBACK;
+
+ if (get_cv(handler, 0))
+ call_pv(handler, G_SCALAR);
+ else if (get_cv("main::trace_unhandled", 0)) {
+ XPUSHs(sv_2mortal(newSVpv(handler, 0)));
+ XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
+ XPUSHs(sv_2mortal(newSVuv(cpu)));
+ XPUSHs(sv_2mortal(newSVuv(nsecs)));
+ XPUSHs(sv_2mortal(newSViv(pid)));
+ XPUSHs(sv_2mortal(newSVpv(comm, 0)));
+ call_pv("main::trace_unhandled", G_SCALAR);
+ }
+ SPAGAIN;
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+}
+
+static void run_start_sub(void)
+{
+ dSP; /* access to Perl stack */
+ PUSHMARK(SP);
+
+ if (get_cv("main::trace_begin", 0))
+ call_pv("main::trace_begin", G_DISCARD | G_NOARGS);
+}
+
+/*
+ * Start trace script
+ */
+static int perl_start_script(const char *script)
+{
+ const char *command_line[2] = { "", NULL };
+
+ command_line[1] = script;
+
+ my_perl = perl_alloc();
+ perl_construct(my_perl);
+
+ if (perl_parse(my_perl, xs_init, 2, (char **)command_line,
+ (char **)NULL))
+ return -1;
+
+ perl_run(my_perl);
+ if (SvTRUE(ERRSV))
+ return -1;
+
+ run_start_sub();
+
+ fprintf(stderr, "perf trace started with Perl script %s\n\n", script);
+
+ return 0;
+}
+
+/*
+ * Stop trace script
+ */
+static int perl_stop_script(void)
+{
+ dSP; /* access to Perl stack */
+ PUSHMARK(SP);
+
+ if (get_cv("main::trace_end", 0))
+ call_pv("main::trace_end", G_DISCARD | G_NOARGS);
+
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+
+ fprintf(stderr, "\nperf trace Perl script stopped\n");
+
+ return 0;
+}
+
+static int perl_generate_script(const char *outfile)
+{
+ struct event *event = NULL;
+ struct format_field *f;
+ char fname[PATH_MAX];
+ int not_first, count;
+ FILE *ofp;
+
+ sprintf(fname, "%s.pl", outfile);
+ ofp = fopen(fname, "w");
+ if (ofp == NULL) {
+ fprintf(stderr, "couldn't open %s\n", fname);
+ return -1;
+ }
+
+ fprintf(ofp, "# perf trace event handlers, "
+ "generated by perf trace -g perl\n");
+
+ fprintf(ofp, "# Licensed under the terms of the GNU GPL"
+ " License version 2\n\n");
+
+ fprintf(ofp, "# The common_* event handler fields are the most useful "
+ "fields common to\n");
+
+ fprintf(ofp, "# all events. They don't necessarily correspond to "
+ "the 'common_*' fields\n");
+
+ fprintf(ofp, "# in the format files. Those fields not available as "
+ "handler params can\n");
+
+ fprintf(ofp, "# be retrieved using Perl functions of the form "
+ "common_*($context).\n");
+
+ fprintf(ofp, "# See Context.pm for the list of available "
+ "functions.\n\n");
+
+ fprintf(ofp, "use lib \"$ENV{'PERF_EXEC_PATH'}/scripts/perl/"
+ "Perf-Trace-Util/lib\";\n");
+
+ fprintf(ofp, "use lib \"./Perf-Trace-Util/lib\";\n");
+ fprintf(ofp, "use Perf::Trace::Core;\n");
+ fprintf(ofp, "use Perf::Trace::Context;\n");
+ fprintf(ofp, "use Perf::Trace::Util;\n\n");
+
+ fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n");
+ fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n");
+
+ while ((event = trace_find_next_event(event))) {
+ fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
+ fprintf(ofp, "\tmy (");
+
+ fprintf(ofp, "$event_name, ");
+ fprintf(ofp, "$context, ");
+ fprintf(ofp, "$common_cpu, ");
+ fprintf(ofp, "$common_secs, ");
+ fprintf(ofp, "$common_nsecs,\n");
+ fprintf(ofp, "\t $common_pid, ");
+ fprintf(ofp, "$common_comm,\n\t ");
+
+ not_first = 0;
+ count = 0;
+
+ for (f = event->format.fields; f; f = f->next) {
+ if (not_first++)
+ fprintf(ofp, ", ");
+ if (++count % 5 == 0)
+ fprintf(ofp, "\n\t ");
+
+ fprintf(ofp, "$%s", f->name);
+ }
+ fprintf(ofp, ") = @_;\n\n");
+
+ fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
+ "$common_secs, $common_nsecs,\n\t "
+ "$common_pid, $common_comm);\n\n");
+
+ fprintf(ofp, "\tprintf(\"");
+
+ not_first = 0;
+ count = 0;
+
+ for (f = event->format.fields; f; f = f->next) {
+ if (not_first++)
+ fprintf(ofp, ", ");
+ if (count && count % 4 == 0) {
+ fprintf(ofp, "\".\n\t \"");
+ }
+ count++;
+
+ fprintf(ofp, "%s=", f->name);
+ if (f->flags & FIELD_IS_STRING ||
+ f->flags & FIELD_IS_FLAG ||
+ f->flags & FIELD_IS_SYMBOLIC)
+ fprintf(ofp, "%%s");
+ else if (f->flags & FIELD_IS_SIGNED)
+ fprintf(ofp, "%%d");
+ else
+ fprintf(ofp, "%%u");
+ }
+
+ fprintf(ofp, "\\n\",\n\t ");
+
+ not_first = 0;
+ count = 0;
+
+ for (f = event->format.fields; f; f = f->next) {
+ if (not_first++)
+ fprintf(ofp, ", ");
+
+ if (++count % 5 == 0)
+ fprintf(ofp, "\n\t ");
+
+ if (f->flags & FIELD_IS_FLAG) {
+ if ((count - 1) % 5 != 0) {
+ fprintf(ofp, "\n\t ");
+ count = 4;
+ }
+ fprintf(ofp, "flag_str(\"");
+ fprintf(ofp, "%s::%s\", ", event->system,
+ event->name);
+ fprintf(ofp, "\"%s\", $%s)", f->name,
+ f->name);
+ } else if (f->flags & FIELD_IS_SYMBOLIC) {
+ if ((count - 1) % 5 != 0) {
+ fprintf(ofp, "\n\t ");
+ count = 4;
+ }
+ fprintf(ofp, "symbol_str(\"");
+ fprintf(ofp, "%s::%s\", ", event->system,
+ event->name);
+ fprintf(ofp, "\"%s\", $%s)", f->name,
+ f->name);
+ } else
+ fprintf(ofp, "$%s", f->name);
+ }
+
+ fprintf(ofp, ");\n");
+ fprintf(ofp, "}\n\n");
+ }
+
+ fprintf(ofp, "sub trace_unhandled\n{\n\tmy ($event_name, $context, "
+ "$common_cpu, $common_secs, $common_nsecs,\n\t "
+ "$common_pid, $common_comm) = @_;\n\n");
+
+ fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
+ "$common_secs, $common_nsecs,\n\t $common_pid, "
+ "$common_comm);\n}\n\n");
+
+ fprintf(ofp, "sub print_header\n{\n"
+ "\tmy ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;\n\n"
+ "\tprintf(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \",\n\t "
+ "$event_name, $cpu, $secs, $nsecs, $pid, $comm);\n}");
+
+ fclose(ofp);
+
+ fprintf(stderr, "generated Perl script: %s\n", fname);
+
+ return 0;
+}
+
+struct scripting_ops perl_scripting_ops = {
+ .name = "Perl",
+ .start_script = perl_start_script,
+ .stop_script = perl_stop_script,
+ .process_event = perl_process_event,
+ .generate_script = perl_generate_script,
+};
+
+#ifdef NO_LIBPERL
+void setup_perl_scripting(void)
+{
+ fprintf(stderr, "Perl scripting not supported."
+ " Install libperl and rebuild perf to enable it. e.g. "
+ "apt-get install libperl-dev (ubuntu), yum install "
+ "perl-ExtUtils-Embed (Fedora), etc.\n");
+}
+#else
+void setup_perl_scripting(void)
+{
+ int err;
+ err = script_spec_register("Perl", &perl_scripting_ops);
+ if (err)
+ die("error registering Perl script extension");
+
+ err = script_spec_register("pl", &perl_scripting_ops);
+ if (err)
+ die("error registering pl script extension");
+
+ scripting_context = malloc(sizeof(struct scripting_context));
+}
+#endif
diff --git a/tools/perf/util/trace-event-perl.h b/tools/perf/util/trace-event-perl.h
new file mode 100644
index 000000000000..8fe0d866fe1a
--- /dev/null
+++ b/tools/perf/util/trace-event-perl.h
@@ -0,0 +1,51 @@
+#ifndef __PERF_TRACE_EVENT_PERL_H
+#define __PERF_TRACE_EVENT_PERL_H
+#ifdef NO_LIBPERL
+typedef int INTERP;
+#define dSP
+#define ENTER
+#define SAVETMPS
+#define PUTBACK
+#define SPAGAIN
+#define FREETMPS
+#define LEAVE
+#define SP
+#define ERRSV
+#define G_SCALAR (0)
+#define G_DISCARD (0)
+#define G_NOARGS (0)
+#define PUSHMARK(a)
+#define SvTRUE(a) (0)
+#define XPUSHs(s)
+#define sv_2mortal(a)
+#define newSVpv(a,b)
+#define newSVuv(a)
+#define newSViv(a)
+#define get_cv(a,b) (0)
+#define call_pv(a,b) (0)
+#define perl_alloc() (0)
+#define perl_construct(a) (0)
+#define perl_parse(a,b,c,d,e) (0)
+#define perl_run(a) (0)
+#define perl_destruct(a) (0)
+#define perl_free(a) (0)
+#define pTHX void
+#define CV void
+#define dXSUB_SYS
+#define pTHX_
+static inline void newXS(const char *a, void *b, const char *c) {}
+#else
+#include <EXTERN.h>
+#include <perl.h>
+typedef PerlInterpreter * INTERP;
+#endif
+
+struct scripting_context {
+ void *event_data;
+};
+
+int common_pc(struct scripting_context *context);
+int common_flags(struct scripting_context *context);
+int common_lock_depth(struct scripting_context *context);
+
+#endif /* __PERF_TRACE_EVENT_PERL_H */
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index 1b5c847d2c22..342dfdd43f87 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -458,9 +458,8 @@ struct record *trace_read_data(int cpu)
return data;
}
-void trace_report(void)
+void trace_report(int fd)
{
- const char *input_file = "trace.info";
char buf[BUFSIZ];
char test[] = { 23, 8, 68 };
char *version;
@@ -468,17 +467,15 @@ void trace_report(void)
int show_funcs = 0;
int show_printk = 0;
- input_fd = open(input_file, O_RDONLY);
- if (input_fd < 0)
- die("opening '%s'\n", input_file);
+ input_fd = fd;
read_or_die(buf, 3);
if (memcmp(buf, test, 3) != 0)
- die("not an trace data file");
+ die("no trace data in the file");
read_or_die(buf, 7);
if (memcmp(buf, "tracing", 7) != 0)
- die("not a trace file (missing tracing)");
+ die("not a trace file (missing 'tracing' tag)");
version = read_string();
if (show_version)
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 693f815c9429..81698d5e6503 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -1,5 +1,5 @@
-#ifndef _TRACE_EVENTS_H
-#define _TRACE_EVENTS_H
+#ifndef __PERF_TRACE_EVENTS_H
+#define __PERF_TRACE_EVENTS_H
#include "parse-events.h"
@@ -26,6 +26,11 @@ enum {
enum format_flags {
FIELD_IS_ARRAY = 1,
FIELD_IS_POINTER = 2,
+ FIELD_IS_SIGNED = 4,
+ FIELD_IS_STRING = 8,
+ FIELD_IS_DYNAMIC = 16,
+ FIELD_IS_FLAG = 32,
+ FIELD_IS_SYMBOLIC = 64,
};
struct format_field {
@@ -132,15 +137,18 @@ struct event {
int flags;
struct format format;
struct print_fmt print_fmt;
+ char *system;
};
enum {
- EVENT_FL_ISFTRACE = 1,
- EVENT_FL_ISPRINT = 2,
- EVENT_FL_ISBPRINT = 4,
- EVENT_FL_ISFUNC = 8,
- EVENT_FL_ISFUNCENT = 16,
- EVENT_FL_ISFUNCRET = 32,
+ EVENT_FL_ISFTRACE = 0x01,
+ EVENT_FL_ISPRINT = 0x02,
+ EVENT_FL_ISBPRINT = 0x04,
+ EVENT_FL_ISFUNC = 0x08,
+ EVENT_FL_ISFUNCENT = 0x10,
+ EVENT_FL_ISFUNCRET = 0x20,
+
+ EVENT_FL_FAILED = 0x80000000
};
struct record {
@@ -154,7 +162,7 @@ struct record *trace_read_data(int cpu);
void parse_set_info(int nr_cpus, int long_sz);
-void trace_report(void);
+void trace_report(int fd);
void *malloc_or_die(unsigned int size);
@@ -166,7 +174,7 @@ void print_funcs(void);
void print_printk(void);
int parse_ftrace_file(char *buf, unsigned long size);
-int parse_event_file(char *buf, unsigned long size, char *system);
+int parse_event_file(char *buf, unsigned long size, char *sys);
void print_event(int cpu, void *data, int size, unsigned long long nsecs,
char *comm);
@@ -233,13 +241,45 @@ extern int header_page_size_size;
extern int header_page_data_offset;
extern int header_page_data_size;
+extern int latency_format;
+
int parse_header_page(char *buf, unsigned long size);
int trace_parse_common_type(void *data);
+int trace_parse_common_pid(void *data);
+int parse_common_pc(void *data);
+int parse_common_flags(void *data);
+int parse_common_lock_depth(void *data);
struct event *trace_find_event(int id);
+struct event *trace_find_next_event(struct event *event);
+unsigned long long read_size(void *ptr, int size);
unsigned long long
raw_field_value(struct event *event, const char *name, void *data);
void *raw_field_ptr(struct event *event, const char *name, void *data);
+unsigned long long eval_flag(const char *flag);
+
+int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events);
+
+/* taken from kernel/trace/trace.h */
+enum trace_flag_type {
+ TRACE_FLAG_IRQS_OFF = 0x01,
+ TRACE_FLAG_IRQS_NOSUPPORT = 0x02,
+ TRACE_FLAG_NEED_RESCHED = 0x04,
+ TRACE_FLAG_HARDIRQ = 0x08,
+ TRACE_FLAG_SOFTIRQ = 0x10,
+};
+
+struct scripting_ops {
+ const char *name;
+ int (*start_script) (const char *);
+ int (*stop_script) (void);
+ void (*process_event) (int cpu, void *data, int size,
+ unsigned long long nsecs, char *comm);
+ int (*generate_script) (const char *outfile);
+};
+
+int script_spec_register(const char *spec, struct scripting_ops *ops);
-void read_tracing_data(struct perf_event_attr *pattrs, int nb_events);
+extern struct scripting_ops perl_scripting_ops;
+void setup_perl_scripting(void);
-#endif /* _TRACE_EVENTS_H */
+#endif /* __PERF_TRACE_EVENTS_H */
diff --git a/tools/perf/util/types.h b/tools/perf/util/types.h
index 5e75f9005940..7d6b8331f898 100644
--- a/tools/perf/util/types.h
+++ b/tools/perf/util/types.h
@@ -1,5 +1,5 @@
-#ifndef _PERF_TYPES_H
-#define _PERF_TYPES_H
+#ifndef __PERF_TYPES_H
+#define __PERF_TYPES_H
/*
* We define u64 as unsigned long long for every architecture
@@ -14,4 +14,4 @@ typedef signed short s16;
typedef unsigned char u8;
typedef signed char s8;
-#endif /* _PERF_TYPES_H */
+#endif /* __PERF_TYPES_H */
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 9de2329dd44d..c673d8825883 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -84,6 +84,9 @@
#include <iconv.h>
#endif
+extern const char *graph_line;
+extern const char *graph_dotted_line;
+
/* On most systems <limits.h> would have given us this, but
* not on some systems (e.g. GNU/Hurd).
*/
@@ -134,6 +137,15 @@ extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1,
extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
+#include "../../../include/linux/stringify.h"
+
+#define DIE_IF(cnd) \
+ do { if (cnd) \
+ die(" at (" __FILE__ ":" __stringify(__LINE__) "): " \
+ __stringify(cnd) "\n"); \
+ } while (0)
+
+
extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
extern int prefixcmp(const char *str, const char *prefix);
@@ -278,17 +290,15 @@ static inline char *gitstrchrnul(const char *s, int c)
* Wrappers:
*/
extern char *xstrdup(const char *str);
-extern void *xmalloc(size_t size);
+extern void *xmalloc(size_t size) __attribute__((weak));
extern void *xmemdupz(const void *data, size_t len);
extern char *xstrndup(const char *str, size_t len);
-extern void *xrealloc(void *ptr, size_t size);
-extern void *xcalloc(size_t nmemb, size_t size);
-extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
-extern ssize_t xread(int fd, void *buf, size_t len);
-extern ssize_t xwrite(int fd, const void *buf, size_t len);
-extern int xdup(int fd);
-extern FILE *xfdopen(int fd, const char *mode);
-extern int xmkstemp(char *template);
+extern void *xrealloc(void *ptr, size_t size) __attribute__((weak));
+
+static inline void *zalloc(size_t size)
+{
+ return calloc(1, size);
+}
static inline size_t xsize_t(off_t len)
{
@@ -306,6 +316,7 @@ static inline int has_extension(const char *filename, const char *ext)
#undef isascii
#undef isspace
#undef isdigit
+#undef isxdigit
#undef isalpha
#undef isprint
#undef isalnum
@@ -323,6 +334,8 @@ extern unsigned char sane_ctype[256];
#define isascii(x) (((x) & ~0x7f) == 0)
#define isspace(x) sane_istest(x,GIT_SPACE)
#define isdigit(x) sane_istest(x,GIT_DIGIT)
+#define isxdigit(x) \
+ (sane_istest(toupper(x), GIT_ALPHA | GIT_DIGIT) && toupper(x) < 'G')
#define isalpha(x) sane_istest(x,GIT_ALPHA)
#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
#define isprint(x) sane_istest(x,GIT_PRINT)
diff --git a/tools/perf/util/values.h b/tools/perf/util/values.h
index cadf8cf2a590..2fa967e1a88a 100644
--- a/tools/perf/util/values.h
+++ b/tools/perf/util/values.h
@@ -1,5 +1,5 @@
-#ifndef _PERF_VALUES_H
-#define _PERF_VALUES_H
+#ifndef __PERF_VALUES_H
+#define __PERF_VALUES_H
#include "types.h"
@@ -24,4 +24,4 @@ void perf_read_values_add_value(struct perf_read_values *values,
void perf_read_values_display(FILE *fp, struct perf_read_values *values,
int raw);
-#endif /* _PERF_VALUES_H */
+#endif /* __PERF_VALUES_H */
diff --git a/tools/perf/util/wrapper.c b/tools/perf/util/wrapper.c
index 4574ac28396f..bf44ca85d23b 100644
--- a/tools/perf/util/wrapper.c
+++ b/tools/perf/util/wrapper.c
@@ -79,43 +79,12 @@ void *xrealloc(void *ptr, size_t size)
return ret;
}
-void *xcalloc(size_t nmemb, size_t size)
-{
- void *ret = calloc(nmemb, size);
- if (!ret && (!nmemb || !size))
- ret = calloc(1, 1);
- if (!ret) {
- release_pack_memory(nmemb * size, -1);
- ret = calloc(nmemb, size);
- if (!ret && (!nmemb || !size))
- ret = calloc(1, 1);
- if (!ret)
- die("Out of memory, calloc failed");
- }
- return ret;
-}
-
-void *xmmap(void *start, size_t length,
- int prot, int flags, int fd, off_t offset)
-{
- void *ret = mmap(start, length, prot, flags, fd, offset);
- if (ret == MAP_FAILED) {
- if (!length)
- return NULL;
- release_pack_memory(length, fd);
- ret = mmap(start, length, prot, flags, fd, offset);
- if (ret == MAP_FAILED)
- die("Out of memory? mmap failed: %s", strerror(errno));
- }
- return ret;
-}
-
/*
* xread() is the same a read(), but it automatically restarts read()
* operations with a recoverable error (EAGAIN and EINTR). xread()
* DOES NOT GUARANTEE that "len" bytes is read even if the data is available.
*/
-ssize_t xread(int fd, void *buf, size_t len)
+static ssize_t xread(int fd, void *buf, size_t len)
{
ssize_t nr;
while (1) {
@@ -131,7 +100,7 @@ ssize_t xread(int fd, void *buf, size_t len)
* operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT
* GUARANTEE that "len" bytes is written even if the operation is successful.
*/
-ssize_t xwrite(int fd, const void *buf, size_t len)
+static ssize_t xwrite(int fd, const void *buf, size_t len)
{
ssize_t nr;
while (1) {
@@ -179,29 +148,3 @@ ssize_t write_in_full(int fd, const void *buf, size_t count)
return total;
}
-
-int xdup(int fd)
-{
- int ret = dup(fd);
- if (ret < 0)
- die("dup failed: %s", strerror(errno));
- return ret;
-}
-
-FILE *xfdopen(int fd, const char *mode)
-{
- FILE *stream = fdopen(fd, mode);
- if (stream == NULL)
- die("Out of memory? fdopen failed: %s", strerror(errno));
- return stream;
-}
-
-int xmkstemp(char *template)
-{
- int fd;
-
- fd = mkstemp(template);
- if (fd < 0)
- die("Unable to create temporary file: %s", strerror(errno));
- return fd;
-}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index b7c78a403dc2..7495ce347344 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2717,8 +2717,6 @@ int kvm_init(void *opaque, unsigned int vcpu_size,
int r;
int cpu;
- kvm_init_debug();
-
r = kvm_arch_init(opaque);
if (r)
goto out_fail;
@@ -2785,6 +2783,8 @@ int kvm_init(void *opaque, unsigned int vcpu_size,
kvm_preempt_ops.sched_in = kvm_sched_in;
kvm_preempt_ops.sched_out = kvm_sched_out;
+ kvm_init_debug();
+
return 0;
out_free:
@@ -2807,7 +2807,6 @@ out_free_0:
out:
kvm_arch_exit();
out_fail:
- kvm_exit_debug();
return r;
}
EXPORT_SYMBOL_GPL(kvm_init);
@@ -2815,6 +2814,7 @@ EXPORT_SYMBOL_GPL(kvm_init);
void kvm_exit(void)
{
tracepoint_synchronize_unregister();
+ kvm_exit_debug();
misc_deregister(&kvm_dev);
kmem_cache_destroy(kvm_vcpu_cache);
sysdev_unregister(&kvm_sysdev);
@@ -2824,7 +2824,6 @@ void kvm_exit(void)
on_each_cpu(hardware_disable, NULL, 1);
kvm_arch_hardware_unsetup();
kvm_arch_exit();
- kvm_exit_debug();
free_cpumask_var(cpus_hardware_enabled);
__free_page(bad_page);
}